diff options
author | wfh <wfh@chromium.org> | 2015-01-12 19:11:40 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-01-13 03:12:31 +0000 |
commit | 74a449cac1340e85b3ef06be59a91fdd29110454 (patch) | |
tree | b5fb5b4672ec9630271fe3a98877a3caac159d7e | |
parent | cd8452bc113fe8c6a1566b0c6ed5245a7a230e43 (diff) | |
download | chromium_src-74a449cac1340e85b3ef06be59a91fdd29110454.zip chromium_src-74a449cac1340e85b3ef06be59a91fdd29110454.tar.gz chromium_src-74a449cac1340e85b3ef06be59a91fdd29110454.tar.bz2 |
Restore the allocator shim on Windows. Add 2Gb limit on allocations via the shim. Remove tcmalloc from Windows.
Restore working tcmalloc_unittests on Linux and allocator_unittests on other platforms. Add Death tests to base_unittests SecurityTests. Fix prep_libc.py to actually strip the objects correctly.
BUG=169327,434397
TEST=base_unittests --gtest_filter=SecurityTest.*
TEST=allocator_unittests, tcmalloc_unittest
Review URL: https://codereview.chromium.org/774683003
Cr-Commit-Position: refs/heads/master@{#311194}
-rw-r--r-- | base/allocator/allocator.gyp | 538 | ||||
-rw-r--r-- | base/allocator/allocator_shim.cc | 378 | ||||
-rw-r--r-- | base/allocator/allocator_shim.h | 27 | ||||
-rw-r--r-- | base/allocator/allocator_shim_win.cc | 221 | ||||
-rw-r--r-- | base/allocator/allocator_unittest.cc | 14 | ||||
-rw-r--r-- | base/allocator/generic_allocators.cc | 4 | ||||
-rwxr-xr-x | base/allocator/prep_libc.py | 56 | ||||
-rw-r--r-- | base/allocator/tcmalloc_unittest.cc | 25 | ||||
-rw-r--r-- | base/allocator/win_allocator.cc | 78 | ||||
-rw-r--r-- | base/profiler/alternate_timer.cc | 3 | ||||
-rw-r--r-- | base/security_unittest.cc | 115 | ||||
-rw-r--r-- | build/common.gypi | 13 | ||||
-rw-r--r-- | content/browser/browser_main_runner.cc | 9 |
13 files changed, 627 insertions, 854 deletions
diff --git a/base/allocator/allocator.gyp b/base/allocator/allocator.gyp index de3b273..860572e 100644 --- a/base/allocator/allocator.gyp +++ b/base/allocator/allocator.gyp @@ -29,12 +29,6 @@ 'variables': { 'optimize': 'max', }, - 'include_dirs': [ - '.', - '<(tcmalloc_dir)/src/base', - '<(tcmalloc_dir)/src', - '../..', - ], 'direct_dependent_settings': { 'configurations': { 'Common_Base': { @@ -56,242 +50,6 @@ }], ], }, - 'sources': [ - # Generated for our configuration from tcmalloc's build - # and checked in. - '<(tcmalloc_dir)/src/config.h', - '<(tcmalloc_dir)/src/config_android.h', - '<(tcmalloc_dir)/src/config_linux.h', - '<(tcmalloc_dir)/src/config_win.h', - - # all tcmalloc native and forked files - '<(tcmalloc_dir)/src/addressmap-inl.h', - '<(tcmalloc_dir)/src/base/abort.cc', - '<(tcmalloc_dir)/src/base/abort.h', - '<(tcmalloc_dir)/src/base/arm_instruction_set_select.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-linuxppc.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-arm-generic.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-arm-v6plus.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-macosx.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-windows.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-x86.cc', - '<(tcmalloc_dir)/src/base/atomicops-internals-x86.h', - '<(tcmalloc_dir)/src/base/atomicops.h', - '<(tcmalloc_dir)/src/base/basictypes.h', - '<(tcmalloc_dir)/src/base/commandlineflags.h', - '<(tcmalloc_dir)/src/base/cycleclock.h', - # We don't list dynamic_annotations.c since its copy is already - # present in the dynamic_annotations target. - '<(tcmalloc_dir)/src/base/dynamic_annotations.h', - '<(tcmalloc_dir)/src/base/elf_mem_image.cc', - '<(tcmalloc_dir)/src/base/elf_mem_image.h', - '<(tcmalloc_dir)/src/base/elfcore.h', - '<(tcmalloc_dir)/src/base/googleinit.h', - '<(tcmalloc_dir)/src/base/linux_syscall_support.h', - '<(tcmalloc_dir)/src/base/linuxthreads.cc', - '<(tcmalloc_dir)/src/base/linuxthreads.h', - '<(tcmalloc_dir)/src/base/logging.cc', - '<(tcmalloc_dir)/src/base/logging.h', - '<(tcmalloc_dir)/src/base/low_level_alloc.cc', - '<(tcmalloc_dir)/src/base/low_level_alloc.h', - '<(tcmalloc_dir)/src/base/simple_mutex.h', - '<(tcmalloc_dir)/src/base/spinlock.cc', - '<(tcmalloc_dir)/src/base/spinlock.h', - '<(tcmalloc_dir)/src/base/spinlock_internal.cc', - '<(tcmalloc_dir)/src/base/spinlock_internal.h', - '<(tcmalloc_dir)/src/base/spinlock_linux-inl.h', - '<(tcmalloc_dir)/src/base/spinlock_posix-inl.h', - '<(tcmalloc_dir)/src/base/spinlock_win32-inl.h', - '<(tcmalloc_dir)/src/base/stl_allocator.h', - '<(tcmalloc_dir)/src/base/synchronization_profiling.h', - '<(tcmalloc_dir)/src/base/sysinfo.cc', - '<(tcmalloc_dir)/src/base/sysinfo.h', - '<(tcmalloc_dir)/src/base/thread_annotations.h', - '<(tcmalloc_dir)/src/base/thread_lister.c', - '<(tcmalloc_dir)/src/base/thread_lister.h', - '<(tcmalloc_dir)/src/base/vdso_support.cc', - '<(tcmalloc_dir)/src/base/vdso_support.h', - '<(tcmalloc_dir)/src/central_freelist.cc', - '<(tcmalloc_dir)/src/central_freelist.h', - '<(tcmalloc_dir)/src/common.cc', - '<(tcmalloc_dir)/src/common.h', - '<(tcmalloc_dir)/src/debugallocation.cc', - '<(tcmalloc_dir)/src/deep-heap-profile.cc', - '<(tcmalloc_dir)/src/deep-heap-profile.h', - '<(tcmalloc_dir)/src/free_list.cc', - '<(tcmalloc_dir)/src/free_list.h', - '<(tcmalloc_dir)/src/getpc.h', - '<(tcmalloc_dir)/src/gperftools/heap-checker.h', - '<(tcmalloc_dir)/src/gperftools/heap-profiler.h', - '<(tcmalloc_dir)/src/gperftools/malloc_extension.h', - '<(tcmalloc_dir)/src/gperftools/malloc_extension_c.h', - '<(tcmalloc_dir)/src/gperftools/malloc_hook.h', - '<(tcmalloc_dir)/src/gperftools/malloc_hook_c.h', - '<(tcmalloc_dir)/src/gperftools/profiler.h', - '<(tcmalloc_dir)/src/gperftools/stacktrace.h', - '<(tcmalloc_dir)/src/gperftools/tcmalloc.h', - '<(tcmalloc_dir)/src/heap-checker-bcad.cc', - '<(tcmalloc_dir)/src/heap-checker.cc', - '<(tcmalloc_dir)/src/heap-profile-table.cc', - '<(tcmalloc_dir)/src/heap-profile-table.h', - '<(tcmalloc_dir)/src/heap-profiler.cc', - '<(tcmalloc_dir)/src/internal_logging.cc', - '<(tcmalloc_dir)/src/internal_logging.h', - '<(tcmalloc_dir)/src/libc_override.h', - '<(tcmalloc_dir)/src/libc_override_gcc_and_weak.h', - '<(tcmalloc_dir)/src/libc_override_glibc.h', - '<(tcmalloc_dir)/src/libc_override_osx.h', - '<(tcmalloc_dir)/src/libc_override_redefine.h', - '<(tcmalloc_dir)/src/linked_list.h', - '<(tcmalloc_dir)/src/malloc_extension.cc', - '<(tcmalloc_dir)/src/malloc_hook-inl.h', - '<(tcmalloc_dir)/src/malloc_hook.cc', - '<(tcmalloc_dir)/src/malloc_hook_mmap_freebsd.h', - '<(tcmalloc_dir)/src/malloc_hook_mmap_linux.h', - '<(tcmalloc_dir)/src/maybe_threads.cc', - '<(tcmalloc_dir)/src/maybe_threads.h', - '<(tcmalloc_dir)/src/memfs_malloc.cc', - '<(tcmalloc_dir)/src/memory_region_map.cc', - '<(tcmalloc_dir)/src/memory_region_map.h', - '<(tcmalloc_dir)/src/packed-cache-inl.h', - '<(tcmalloc_dir)/src/page_heap.cc', - '<(tcmalloc_dir)/src/page_heap.h', - '<(tcmalloc_dir)/src/page_heap_allocator.h', - '<(tcmalloc_dir)/src/pagemap.h', - '<(tcmalloc_dir)/src/profile-handler.cc', - '<(tcmalloc_dir)/src/profile-handler.h', - '<(tcmalloc_dir)/src/profiledata.cc', - '<(tcmalloc_dir)/src/profiledata.h', - '<(tcmalloc_dir)/src/profiler.cc', - '<(tcmalloc_dir)/src/raw_printer.cc', - '<(tcmalloc_dir)/src/raw_printer.h', - '<(tcmalloc_dir)/src/sampler.cc', - '<(tcmalloc_dir)/src/sampler.h', - '<(tcmalloc_dir)/src/span.cc', - '<(tcmalloc_dir)/src/span.h', - '<(tcmalloc_dir)/src/stack_trace_table.cc', - '<(tcmalloc_dir)/src/stack_trace_table.h', - '<(tcmalloc_dir)/src/stacktrace.cc', - '<(tcmalloc_dir)/src/stacktrace_arm-inl.h', - '<(tcmalloc_dir)/src/stacktrace_config.h', - '<(tcmalloc_dir)/src/stacktrace_generic-inl.h', - '<(tcmalloc_dir)/src/stacktrace_libunwind-inl.h', - '<(tcmalloc_dir)/src/stacktrace_powerpc-inl.h', - '<(tcmalloc_dir)/src/stacktrace_win32-inl.h', - '<(tcmalloc_dir)/src/stacktrace_with_context.cc', - '<(tcmalloc_dir)/src/stacktrace_x86-inl.h', - '<(tcmalloc_dir)/src/static_vars.cc', - '<(tcmalloc_dir)/src/static_vars.h', - '<(tcmalloc_dir)/src/symbolize.cc', - '<(tcmalloc_dir)/src/symbolize.h', - '<(tcmalloc_dir)/src/system-alloc.cc', - '<(tcmalloc_dir)/src/system-alloc.h', - '<(tcmalloc_dir)/src/tcmalloc.cc', - '<(tcmalloc_dir)/src/tcmalloc_guard.h', - '<(tcmalloc_dir)/src/thread_cache.cc', - '<(tcmalloc_dir)/src/thread_cache.h', - '<(tcmalloc_dir)/src/windows/config.h', - '<(tcmalloc_dir)/src/windows/get_mangled_names.cc', - '<(tcmalloc_dir)/src/windows/gperftools/tcmalloc.h', - '<(tcmalloc_dir)/src/windows/ia32_modrm_map.cc', - '<(tcmalloc_dir)/src/windows/ia32_opcode_map.cc', - '<(tcmalloc_dir)/src/windows/mingw.h', - '<(tcmalloc_dir)/src/windows/mini_disassembler.cc', - '<(tcmalloc_dir)/src/windows/mini_disassembler.h', - '<(tcmalloc_dir)/src/windows/mini_disassembler_types.h', - '<(tcmalloc_dir)/src/windows/override_functions.cc', - '<(tcmalloc_dir)/src/windows/patch_functions.cc', - '<(tcmalloc_dir)/src/windows/port.cc', - '<(tcmalloc_dir)/src/windows/port.h', - '<(tcmalloc_dir)/src/windows/preamble_patcher.cc', - '<(tcmalloc_dir)/src/windows/preamble_patcher.h', - '<(tcmalloc_dir)/src/windows/preamble_patcher_with_stub.cc', - - 'allocator_shim.cc', - 'allocator_shim.h', - 'debugallocation_shim.cc', - 'generic_allocators.cc', - 'win_allocator.cc', - ], - # sources! means that these are not compiled directly. - 'sources!': [ - # Included by allocator_shim.cc for maximal inlining. - 'generic_allocators.cc', - 'win_allocator.cc', - - # Included by debugallocation_shim.cc. - '<(tcmalloc_dir)/src/debugallocation.cc', - '<(tcmalloc_dir)/src/tcmalloc.cc', - - # We simply don't use these, but list them above so that IDE - # users can view the full available source for reference, etc. - '<(tcmalloc_dir)/src/addressmap-inl.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-linuxppc.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-macosx.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-x86-msvc.h', - '<(tcmalloc_dir)/src/base/atomicops-internals-x86.cc', - '<(tcmalloc_dir)/src/base/atomicops-internals-x86.h', - '<(tcmalloc_dir)/src/base/atomicops.h', - '<(tcmalloc_dir)/src/base/basictypes.h', - '<(tcmalloc_dir)/src/base/commandlineflags.h', - '<(tcmalloc_dir)/src/base/cycleclock.h', - '<(tcmalloc_dir)/src/base/elf_mem_image.h', - '<(tcmalloc_dir)/src/base/elfcore.h', - '<(tcmalloc_dir)/src/base/googleinit.h', - '<(tcmalloc_dir)/src/base/linux_syscall_support.h', - '<(tcmalloc_dir)/src/base/simple_mutex.h', - '<(tcmalloc_dir)/src/base/spinlock_linux-inl.h', - '<(tcmalloc_dir)/src/base/spinlock_posix-inl.h', - '<(tcmalloc_dir)/src/base/spinlock_win32-inl.h', - '<(tcmalloc_dir)/src/base/stl_allocator.h', - '<(tcmalloc_dir)/src/base/thread_annotations.h', - '<(tcmalloc_dir)/src/getpc.h', - '<(tcmalloc_dir)/src/gperftools/heap-checker.h', - '<(tcmalloc_dir)/src/gperftools/heap-profiler.h', - '<(tcmalloc_dir)/src/gperftools/malloc_extension.h', - '<(tcmalloc_dir)/src/gperftools/malloc_extension_c.h', - '<(tcmalloc_dir)/src/gperftools/malloc_hook.h', - '<(tcmalloc_dir)/src/gperftools/malloc_hook_c.h', - '<(tcmalloc_dir)/src/gperftools/profiler.h', - '<(tcmalloc_dir)/src/gperftools/stacktrace.h', - '<(tcmalloc_dir)/src/gperftools/tcmalloc.h', - '<(tcmalloc_dir)/src/heap-checker-bcad.cc', - '<(tcmalloc_dir)/src/heap-checker.cc', - '<(tcmalloc_dir)/src/libc_override.h', - '<(tcmalloc_dir)/src/libc_override_gcc_and_weak.h', - '<(tcmalloc_dir)/src/libc_override_glibc.h', - '<(tcmalloc_dir)/src/libc_override_osx.h', - '<(tcmalloc_dir)/src/libc_override_redefine.h', - '<(tcmalloc_dir)/src/malloc_hook_mmap_freebsd.h', - '<(tcmalloc_dir)/src/malloc_hook_mmap_linux.h', - '<(tcmalloc_dir)/src/memfs_malloc.cc', - '<(tcmalloc_dir)/src/packed-cache-inl.h', - '<(tcmalloc_dir)/src/page_heap_allocator.h', - '<(tcmalloc_dir)/src/pagemap.h', - '<(tcmalloc_dir)/src/stacktrace_arm-inl.h', - '<(tcmalloc_dir)/src/stacktrace_config.h', - '<(tcmalloc_dir)/src/stacktrace_generic-inl.h', - '<(tcmalloc_dir)/src/stacktrace_libunwind-inl.h', - '<(tcmalloc_dir)/src/stacktrace_powerpc-inl.h', - '<(tcmalloc_dir)/src/stacktrace_win32-inl.h', - '<(tcmalloc_dir)/src/stacktrace_with_context.cc', - '<(tcmalloc_dir)/src/stacktrace_x86-inl.h', - '<(tcmalloc_dir)/src/tcmalloc_guard.h', - '<(tcmalloc_dir)/src/windows/config.h', - '<(tcmalloc_dir)/src/windows/gperftools/tcmalloc.h', - '<(tcmalloc_dir)/src/windows/get_mangled_names.cc', - '<(tcmalloc_dir)/src/windows/ia32_modrm_map.cc', - '<(tcmalloc_dir)/src/windows/ia32_opcode_map.cc', - '<(tcmalloc_dir)/src/windows/mingw.h', - '<(tcmalloc_dir)/src/windows/mini_disassembler.cc', - '<(tcmalloc_dir)/src/windows/mini_disassembler.h', - '<(tcmalloc_dir)/src/windows/mini_disassembler_types.h', - '<(tcmalloc_dir)/src/windows/override_functions.cc', - '<(tcmalloc_dir)/src/windows/patch_functions.cc', - '<(tcmalloc_dir)/src/windows/preamble_patcher.cc', - '<(tcmalloc_dir)/src/windows/preamble_patcher.h', - '<(tcmalloc_dir)/src/windows/preamble_patcher_with_stub.cc', - ], 'dependencies': [ '../third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', ], @@ -318,8 +76,7 @@ 'disable_debugallocation%': 0, }, 'conditions': [ - # TODO(phajdan.jr): Also enable on Windows. - ['disable_debugallocation==0 and OS!="win"', { + ['disable_debugallocation==0', { 'defines': [ # Use debugallocation for Debug builds to catch problems early # and cleanly, http://crbug.com/30715 . @@ -329,11 +86,221 @@ ], }, }, - # Disable the heap checker in tcmalloc. - 'defines': [ - 'NO_HEAP_CHECK', - ], 'conditions': [ + ['use_allocator=="tcmalloc"', { + # Disable the heap checker in tcmalloc. + 'defines': [ + 'NO_HEAP_CHECK', + ], + 'include_dirs': [ + '.', + '<(tcmalloc_dir)/src/base', + '<(tcmalloc_dir)/src', + '../..', + ], + 'sources': [ + # Generated for our configuration from tcmalloc's build + # and checked in. + '<(tcmalloc_dir)/src/config.h', + '<(tcmalloc_dir)/src/config_android.h', + '<(tcmalloc_dir)/src/config_linux.h', + '<(tcmalloc_dir)/src/config_win.h', + + # all tcmalloc native and forked files + '<(tcmalloc_dir)/src/addressmap-inl.h', + '<(tcmalloc_dir)/src/base/abort.cc', + '<(tcmalloc_dir)/src/base/abort.h', + '<(tcmalloc_dir)/src/base/arm_instruction_set_select.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-linuxppc.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-arm-generic.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-arm-v6plus.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-macosx.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-windows.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-x86.cc', + '<(tcmalloc_dir)/src/base/atomicops-internals-x86.h', + '<(tcmalloc_dir)/src/base/atomicops.h', + '<(tcmalloc_dir)/src/base/basictypes.h', + '<(tcmalloc_dir)/src/base/commandlineflags.h', + '<(tcmalloc_dir)/src/base/cycleclock.h', + # We don't list dynamic_annotations.c since its copy is already + # present in the dynamic_annotations target. + '<(tcmalloc_dir)/src/base/dynamic_annotations.h', + '<(tcmalloc_dir)/src/base/elf_mem_image.cc', + '<(tcmalloc_dir)/src/base/elf_mem_image.h', + '<(tcmalloc_dir)/src/base/elfcore.h', + '<(tcmalloc_dir)/src/base/googleinit.h', + '<(tcmalloc_dir)/src/base/linux_syscall_support.h', + '<(tcmalloc_dir)/src/base/linuxthreads.cc', + '<(tcmalloc_dir)/src/base/linuxthreads.h', + '<(tcmalloc_dir)/src/base/logging.cc', + '<(tcmalloc_dir)/src/base/logging.h', + '<(tcmalloc_dir)/src/base/low_level_alloc.cc', + '<(tcmalloc_dir)/src/base/low_level_alloc.h', + '<(tcmalloc_dir)/src/base/simple_mutex.h', + '<(tcmalloc_dir)/src/base/spinlock.cc', + '<(tcmalloc_dir)/src/base/spinlock.h', + '<(tcmalloc_dir)/src/base/spinlock_internal.cc', + '<(tcmalloc_dir)/src/base/spinlock_internal.h', + '<(tcmalloc_dir)/src/base/spinlock_linux-inl.h', + '<(tcmalloc_dir)/src/base/spinlock_posix-inl.h', + '<(tcmalloc_dir)/src/base/spinlock_win32-inl.h', + '<(tcmalloc_dir)/src/base/stl_allocator.h', + '<(tcmalloc_dir)/src/base/synchronization_profiling.h', + '<(tcmalloc_dir)/src/base/sysinfo.cc', + '<(tcmalloc_dir)/src/base/sysinfo.h', + '<(tcmalloc_dir)/src/base/thread_annotations.h', + '<(tcmalloc_dir)/src/base/thread_lister.c', + '<(tcmalloc_dir)/src/base/thread_lister.h', + '<(tcmalloc_dir)/src/base/vdso_support.cc', + '<(tcmalloc_dir)/src/base/vdso_support.h', + '<(tcmalloc_dir)/src/central_freelist.cc', + '<(tcmalloc_dir)/src/central_freelist.h', + '<(tcmalloc_dir)/src/common.cc', + '<(tcmalloc_dir)/src/common.h', + '<(tcmalloc_dir)/src/debugallocation.cc', + '<(tcmalloc_dir)/src/deep-heap-profile.cc', + '<(tcmalloc_dir)/src/deep-heap-profile.h', + '<(tcmalloc_dir)/src/free_list.cc', + '<(tcmalloc_dir)/src/free_list.h', + '<(tcmalloc_dir)/src/getpc.h', + '<(tcmalloc_dir)/src/gperftools/heap-checker.h', + '<(tcmalloc_dir)/src/gperftools/heap-profiler.h', + '<(tcmalloc_dir)/src/gperftools/malloc_extension.h', + '<(tcmalloc_dir)/src/gperftools/malloc_extension_c.h', + '<(tcmalloc_dir)/src/gperftools/malloc_hook.h', + '<(tcmalloc_dir)/src/gperftools/malloc_hook_c.h', + '<(tcmalloc_dir)/src/gperftools/profiler.h', + '<(tcmalloc_dir)/src/gperftools/stacktrace.h', + '<(tcmalloc_dir)/src/gperftools/tcmalloc.h', + '<(tcmalloc_dir)/src/heap-checker-bcad.cc', + '<(tcmalloc_dir)/src/heap-checker.cc', + '<(tcmalloc_dir)/src/heap-profile-table.cc', + '<(tcmalloc_dir)/src/heap-profile-table.h', + '<(tcmalloc_dir)/src/heap-profiler.cc', + '<(tcmalloc_dir)/src/internal_logging.cc', + '<(tcmalloc_dir)/src/internal_logging.h', + '<(tcmalloc_dir)/src/libc_override.h', + '<(tcmalloc_dir)/src/libc_override_gcc_and_weak.h', + '<(tcmalloc_dir)/src/libc_override_glibc.h', + '<(tcmalloc_dir)/src/libc_override_osx.h', + '<(tcmalloc_dir)/src/libc_override_redefine.h', + '<(tcmalloc_dir)/src/linked_list.h', + '<(tcmalloc_dir)/src/malloc_extension.cc', + '<(tcmalloc_dir)/src/malloc_hook-inl.h', + '<(tcmalloc_dir)/src/malloc_hook.cc', + '<(tcmalloc_dir)/src/malloc_hook_mmap_freebsd.h', + '<(tcmalloc_dir)/src/malloc_hook_mmap_linux.h', + '<(tcmalloc_dir)/src/maybe_threads.cc', + '<(tcmalloc_dir)/src/maybe_threads.h', + '<(tcmalloc_dir)/src/memfs_malloc.cc', + '<(tcmalloc_dir)/src/memory_region_map.cc', + '<(tcmalloc_dir)/src/memory_region_map.h', + '<(tcmalloc_dir)/src/packed-cache-inl.h', + '<(tcmalloc_dir)/src/page_heap.cc', + '<(tcmalloc_dir)/src/page_heap.h', + '<(tcmalloc_dir)/src/page_heap_allocator.h', + '<(tcmalloc_dir)/src/pagemap.h', + '<(tcmalloc_dir)/src/profile-handler.cc', + '<(tcmalloc_dir)/src/profile-handler.h', + '<(tcmalloc_dir)/src/profiledata.cc', + '<(tcmalloc_dir)/src/profiledata.h', + '<(tcmalloc_dir)/src/profiler.cc', + '<(tcmalloc_dir)/src/raw_printer.cc', + '<(tcmalloc_dir)/src/raw_printer.h', + '<(tcmalloc_dir)/src/sampler.cc', + '<(tcmalloc_dir)/src/sampler.h', + '<(tcmalloc_dir)/src/span.cc', + '<(tcmalloc_dir)/src/span.h', + '<(tcmalloc_dir)/src/stack_trace_table.cc', + '<(tcmalloc_dir)/src/stack_trace_table.h', + '<(tcmalloc_dir)/src/stacktrace.cc', + '<(tcmalloc_dir)/src/stacktrace_arm-inl.h', + '<(tcmalloc_dir)/src/stacktrace_config.h', + '<(tcmalloc_dir)/src/stacktrace_generic-inl.h', + '<(tcmalloc_dir)/src/stacktrace_libunwind-inl.h', + '<(tcmalloc_dir)/src/stacktrace_powerpc-inl.h', + '<(tcmalloc_dir)/src/stacktrace_win32-inl.h', + '<(tcmalloc_dir)/src/stacktrace_with_context.cc', + '<(tcmalloc_dir)/src/stacktrace_x86-inl.h', + '<(tcmalloc_dir)/src/static_vars.cc', + '<(tcmalloc_dir)/src/static_vars.h', + '<(tcmalloc_dir)/src/symbolize.cc', + '<(tcmalloc_dir)/src/symbolize.h', + '<(tcmalloc_dir)/src/system-alloc.cc', + '<(tcmalloc_dir)/src/system-alloc.h', + '<(tcmalloc_dir)/src/tcmalloc.cc', + '<(tcmalloc_dir)/src/tcmalloc_guard.h', + '<(tcmalloc_dir)/src/thread_cache.cc', + '<(tcmalloc_dir)/src/thread_cache.h', + + 'debugallocation_shim.cc', + ], + # sources! means that these are not compiled directly. + 'sources!': [ + # We simply don't use these, but list them above so that IDE + # users can view the full available source for reference, etc. + '<(tcmalloc_dir)/src/addressmap-inl.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-linuxppc.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-macosx.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-x86-msvc.h', + '<(tcmalloc_dir)/src/base/atomicops-internals-x86.h', + '<(tcmalloc_dir)/src/base/atomicops.h', + '<(tcmalloc_dir)/src/base/basictypes.h', + '<(tcmalloc_dir)/src/base/commandlineflags.h', + '<(tcmalloc_dir)/src/base/cycleclock.h', + '<(tcmalloc_dir)/src/base/elf_mem_image.h', + '<(tcmalloc_dir)/src/base/elfcore.h', + '<(tcmalloc_dir)/src/base/googleinit.h', + '<(tcmalloc_dir)/src/base/linux_syscall_support.h', + '<(tcmalloc_dir)/src/base/simple_mutex.h', + '<(tcmalloc_dir)/src/base/spinlock_linux-inl.h', + '<(tcmalloc_dir)/src/base/spinlock_posix-inl.h', + '<(tcmalloc_dir)/src/base/spinlock_win32-inl.h', + '<(tcmalloc_dir)/src/base/stl_allocator.h', + '<(tcmalloc_dir)/src/base/thread_annotations.h', + '<(tcmalloc_dir)/src/getpc.h', + '<(tcmalloc_dir)/src/gperftools/heap-checker.h', + '<(tcmalloc_dir)/src/gperftools/heap-profiler.h', + '<(tcmalloc_dir)/src/gperftools/malloc_extension.h', + '<(tcmalloc_dir)/src/gperftools/malloc_extension_c.h', + '<(tcmalloc_dir)/src/gperftools/malloc_hook.h', + '<(tcmalloc_dir)/src/gperftools/malloc_hook_c.h', + '<(tcmalloc_dir)/src/gperftools/profiler.h', + '<(tcmalloc_dir)/src/gperftools/stacktrace.h', + '<(tcmalloc_dir)/src/gperftools/tcmalloc.h', + '<(tcmalloc_dir)/src/heap-checker-bcad.cc', + '<(tcmalloc_dir)/src/heap-checker.cc', + '<(tcmalloc_dir)/src/libc_override.h', + '<(tcmalloc_dir)/src/libc_override_gcc_and_weak.h', + '<(tcmalloc_dir)/src/libc_override_glibc.h', + '<(tcmalloc_dir)/src/libc_override_osx.h', + '<(tcmalloc_dir)/src/libc_override_redefine.h', + '<(tcmalloc_dir)/src/malloc_hook_mmap_freebsd.h', + '<(tcmalloc_dir)/src/malloc_hook_mmap_linux.h', + '<(tcmalloc_dir)/src/memfs_malloc.cc', + '<(tcmalloc_dir)/src/packed-cache-inl.h', + '<(tcmalloc_dir)/src/page_heap_allocator.h', + '<(tcmalloc_dir)/src/pagemap.h', + '<(tcmalloc_dir)/src/stacktrace_arm-inl.h', + '<(tcmalloc_dir)/src/stacktrace_config.h', + '<(tcmalloc_dir)/src/stacktrace_generic-inl.h', + '<(tcmalloc_dir)/src/stacktrace_libunwind-inl.h', + '<(tcmalloc_dir)/src/stacktrace_powerpc-inl.h', + '<(tcmalloc_dir)/src/stacktrace_win32-inl.h', + '<(tcmalloc_dir)/src/stacktrace_with_context.cc', + '<(tcmalloc_dir)/src/stacktrace_x86-inl.h', + '<(tcmalloc_dir)/src/tcmalloc_guard.h', + + # Included by debugallocation_shim.cc. + '<(tcmalloc_dir)/src/debugallocation.cc', + '<(tcmalloc_dir)/src/tcmalloc.cc', + ] + },{ + 'include_dirs': [ + '.', + '../..', + ], + }], ['OS=="linux" and clang_type_profiler==1', { 'dependencies': [ 'type_profiler_tcmalloc', @@ -348,38 +315,20 @@ ], }], ['OS=="win"', { - 'defines': [ - 'PERFTOOLS_DLL_DECL=', - ], - 'defines!': [ - # tcmalloc source files unconditionally define this, remove it from - # the list of defines that common.gypi defines globally. - 'NOMINMAX', - ], 'dependencies': [ 'libcmt', ], - 'include_dirs': [ - '<(tcmalloc_dir)/src/windows', + 'sources': [ + 'allocator_shim_win.cc', + 'generic_allocators.cc', ], + # sources! means that these are not compiled directly. 'sources!': [ - '<(tcmalloc_dir)/src/base/elf_mem_image.cc', - '<(tcmalloc_dir)/src/base/elf_mem_image.h', - '<(tcmalloc_dir)/src/base/linuxthreads.cc', - '<(tcmalloc_dir)/src/base/linuxthreads.h', - '<(tcmalloc_dir)/src/base/vdso_support.cc', - '<(tcmalloc_dir)/src/base/vdso_support.h', - '<(tcmalloc_dir)/src/maybe_threads.cc', - '<(tcmalloc_dir)/src/maybe_threads.h', - '<(tcmalloc_dir)/src/symbolize.h', - '<(tcmalloc_dir)/src/system-alloc.cc', - '<(tcmalloc_dir)/src/system-alloc.h', - - # included by allocator_shim.cc - 'debugallocation_shim.cc', + # Included by allocator_shim_win.cc for maximal inlining. + 'generic_allocators.cc', ], }], - ['OS=="win" or profiling!=1', { + ['profiling!=1', { 'sources!': [ # cpuprofiler '<(tcmalloc_dir)/src/base/thread_lister.c', @@ -394,11 +343,6 @@ ['OS=="linux" or OS=="freebsd" or OS=="solaris" or OS=="android"', { 'sources!': [ '<(tcmalloc_dir)/src/system-alloc.h', - '<(tcmalloc_dir)/src/windows/port.cc', - '<(tcmalloc_dir)/src/windows/port.h', - - # TODO(willchan): Support allocator shim later on. - 'allocator_shim.cc', ], # We enable all warnings by default, but upstream disables a few. # Keep "-Wno-*" flags in sync with upstream by comparing against: @@ -498,8 +442,6 @@ ], 'include_dirs': [ '.', - '<(tcmalloc_dir)/src/base', - '<(tcmalloc_dir)/src', '../..', ], 'sources': [ @@ -508,23 +450,6 @@ '../profiler/alternate_timer.h', ], }, - { - 'target_name': 'tcmalloc_unittest', - 'type': 'executable', - 'sources': [ - 'tcmalloc_unittest.cc', - ], - 'include_dirs': [ - '../..', - # For constants of TCMalloc. - '<(tcmalloc_dir)/src', - ], - 'dependencies': [ - '../../testing/gtest.gyp:gtest', - '../base.gyp:base', - 'allocator', - ], - }, ], }], ['OS=="win" and target_arch=="ia32"', { @@ -635,5 +560,24 @@ }, ], }], + ['use_allocator=="tcmalloc"', { + 'targets': [ + { + 'target_name': 'tcmalloc_unittest', + 'type': 'executable', + 'sources': [ + 'tcmalloc_unittest.cc', + ], + 'include_dirs': [ + '<(tcmalloc_dir)/src', + '../..', + ], + 'dependencies': [ + '../../testing/gtest.gyp:gtest', + 'allocator', + ], + }, + ], + }], ], } diff --git a/base/allocator/allocator_shim.cc b/base/allocator/allocator_shim.cc deleted file mode 100644 index 961cda4..0000000 --- a/base/allocator/allocator_shim.cc +++ /dev/null @@ -1,378 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "base/allocator/allocator_shim.h" - -#include <config.h> -#include "base/allocator/allocator_extension_thunks.h" -#include "base/profiler/alternate_timer.h" -#include "base/sysinfo.h" - -// This shim make it possible to use different allocators via an environment -// variable set before running the program. This may reduce the -// amount of inlining that we get with malloc/free/etc. - -// TODO(mbelshe): Ensure that all calls to tcmalloc have the proper call depth -// from the "user code" so that debugging tools (HeapChecker) can work. - -// new_mode behaves similarly to MSVC's _set_new_mode. -// If flag is 0 (default), calls to malloc will behave normally. -// If flag is 1, calls to malloc will behave like calls to new, -// and the std_new_handler will be invoked on failure. -// Can be set by calling _set_new_mode(). -static int new_mode = 0; - -typedef enum { - TCMALLOC, // TCMalloc is the default allocator. - WINHEAP, // Windows Heap (standard Windows allocator). - WINLFH, // Windows LFH Heap. -} Allocator; - -// This is the default allocator. This value can be changed at startup by -// specifying environment variables shown below it. -// See SetupSubprocessAllocator() to specify a default secondary (subprocess) -// allocator. -// TODO(jar): Switch to using TCMALLOC for the renderer as well. -#if defined(SYZYASAN) -// SyzyASan requires the use of "WINHEAP". -static Allocator allocator = WINHEAP; -#else -static Allocator allocator = TCMALLOC; -#endif -// The names of the environment variables that can optionally control the -// selection of the allocator. The primary may be used to control overall -// allocator selection, and the secondary can be used to specify an allocator -// to use in sub-processes. -static const char primary_name[] = "CHROME_ALLOCATOR"; -static const char secondary_name[] = "CHROME_ALLOCATOR_2"; - -// We include tcmalloc and the win_allocator to get as much inlining as -// possible. -#include "debugallocation_shim.cc" -#include "win_allocator.cc" - -// Call the new handler, if one has been set. -// Returns true on successfully calling the handler, false otherwise. -inline bool call_new_handler(bool nothrow) { - // Get the current new handler. NB: this function is not - // thread-safe. We make a feeble stab at making it so here, but - // this lock only protects against tcmalloc interfering with - // itself, not with other libraries calling set_new_handler. - std::new_handler nh; - { - SpinLockHolder h(&set_new_handler_lock); - nh = std::set_new_handler(0); - (void) std::set_new_handler(nh); - } -#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || \ - (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) - if (!nh) - return false; - // Since exceptions are disabled, we don't really know if new_handler - // failed. Assume it will abort if it fails. - (*nh)(); - return false; // break out of the retry loop. -#else - // If no new_handler is established, the allocation failed. - if (!nh) { - if (nothrow) - return false; - throw std::bad_alloc(); - } - // Otherwise, try the new_handler. If it returns, retry the - // allocation. If it throws std::bad_alloc, fail the allocation. - // if it throws something else, don't interfere. - try { - (*nh)(); - } catch (const std::bad_alloc&) { - if (!nothrow) - throw; - return true; - } -#endif // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS) - return false; -} - -extern "C" { -void* malloc(size_t size) { - void* ptr; - for (;;) { - switch (allocator) { - case WINHEAP: - case WINLFH: - ptr = win_heap_malloc(size); - break; - case TCMALLOC: - default: - ptr = do_malloc(size); - break; - } - if (ptr) - return ptr; - - if (!new_mode || !call_new_handler(true)) - break; - } - return ptr; -} - -void free(void* p) { - switch (allocator) { - case WINHEAP: - case WINLFH: - win_heap_free(p); - return; - case TCMALLOC: - do_free(p); - return; - } -} - -void* realloc(void* ptr, size_t size) { - // Webkit is brittle for allocators that return NULL for malloc(0). The - // realloc(0, 0) code path does not guarantee a non-NULL return, so be sure - // to call malloc for this case. - if (!ptr) - return malloc(size); - - void* new_ptr; - for (;;) { - switch (allocator) { - case WINHEAP: - case WINLFH: - new_ptr = win_heap_realloc(ptr, size); - break; - case TCMALLOC: - default: - new_ptr = do_realloc(ptr, size); - break; - } - - // Subtle warning: NULL return does not alwas indicate out-of-memory. If - // the requested new size is zero, realloc should free the ptr and return - // NULL. - if (new_ptr || !size) - return new_ptr; - if (!new_mode || !call_new_handler(true)) - break; - } - return new_ptr; -} - -// TODO(mbelshe): Implement this for other allocators. -void malloc_stats(void) { - switch (allocator) { - case WINHEAP: - case WINLFH: - // No stats. - return; - case TCMALLOC: - tc_malloc_stats(); - return; - } -} - -#ifdef WIN32 - -extern "C" size_t _msize(void* p) { - switch (allocator) { - case WINHEAP: - case WINLFH: - return win_heap_msize(p); - } - - // TCMALLOC - return MallocExtension::instance()->GetAllocatedSize(p); -} - -// This is included to resolve references from libcmt. -extern "C" intptr_t _get_heap_handle() { - return 0; -} - -static bool get_allocator_waste_size_thunk(size_t* size) { - switch (allocator) { - case WINHEAP: - case WINLFH: - // TODO(alexeif): Implement for allocators other than tcmalloc. - return false; - } - size_t heap_size, allocated_bytes, unmapped_bytes; - MallocExtension* ext = MallocExtension::instance(); - if (ext->GetNumericProperty("generic.heap_size", &heap_size) && - ext->GetNumericProperty("generic.current_allocated_bytes", - &allocated_bytes) && - ext->GetNumericProperty("tcmalloc.pageheap_unmapped_bytes", - &unmapped_bytes)) { - *size = heap_size - allocated_bytes - unmapped_bytes; - return true; - } - return false; -} - -static void get_stats_thunk(char* buffer, int buffer_length) { - MallocExtension::instance()->GetStats(buffer, buffer_length); -} - -static void release_free_memory_thunk() { - MallocExtension::instance()->ReleaseFreeMemory(); -} - -// The CRT heap initialization stub. -extern "C" int _heap_init() { -// Don't use the environment variable if SYZYASAN is defined, as the -// implementation requires Winheap to be the allocator. -#if !defined(SYZYASAN) - const char* environment_value = GetenvBeforeMain(primary_name); - if (environment_value) { - if (!stricmp(environment_value, "winheap")) - allocator = WINHEAP; - else if (!stricmp(environment_value, "winlfh")) - allocator = WINLFH; - else if (!stricmp(environment_value, "tcmalloc")) - allocator = TCMALLOC; - } -#endif - - switch (allocator) { - case WINHEAP: - return win_heap_init(false) ? 1 : 0; - case WINLFH: - return win_heap_init(true) ? 1 : 0; - case TCMALLOC: - default: - // fall through - break; - } - - // Initializing tcmalloc. - // We intentionally leak this object. It lasts for the process - // lifetime. Trying to teardown at _heap_term() is so late that - // you can't do anything useful anyway. - new TCMallocGuard(); - - // Provide optional hook for monitoring allocation quantities on a per-thread - // basis. Only set the hook if the environment indicates this needs to be - // enabled. - const char* profiling = - GetenvBeforeMain(tracked_objects::kAlternateProfilerTime); - if (profiling && *profiling == '1') { - tracked_objects::SetAlternateTimeSource( - tcmalloc::ThreadCache::GetBytesAllocatedOnCurrentThread, - tracked_objects::TIME_SOURCE_TYPE_TCMALLOC); - } - - base::allocator::thunks::SetGetAllocatorWasteSizeFunction( - get_allocator_waste_size_thunk); - base::allocator::thunks::SetGetStatsFunction(get_stats_thunk); - base::allocator::thunks::SetReleaseFreeMemoryFunction( - release_free_memory_thunk); - - return 1; -} - -// The CRT heap cleanup stub. -extern "C" void _heap_term() {} - -// We set this to 1 because part of the CRT uses a check of _crtheap != 0 -// to test whether the CRT has been initialized. Once we've ripped out -// the allocators from libcmt, we need to provide this definition so that -// the rest of the CRT is still usable. -extern "C" void* _crtheap = reinterpret_cast<void*>(1); - -// Provide support for aligned memory through Windows only _aligned_malloc(). -void* _aligned_malloc(size_t size, size_t alignment) { - // _aligned_malloc guarantees parameter validation, so do so here. These - // checks are somewhat stricter than _aligned_malloc() since we're effectively - // using memalign() under the hood. - DCHECK_GT(size, 0U); - DCHECK_EQ(alignment & (alignment - 1), 0U); - DCHECK_EQ(alignment % sizeof(void*), 0U); - - void* ptr; - for (;;) { - switch (allocator) { - case WINHEAP: - case WINLFH: - ptr = win_heap_memalign(alignment, size); - break; - case TCMALLOC: - default: - ptr = tc_memalign(alignment, size); - break; - } - - if (ptr) { - // Sanity check alignment. - DCHECK_EQ(reinterpret_cast<uintptr_t>(ptr) & (alignment - 1), 0U); - return ptr; - } - - if (!new_mode || !call_new_handler(true)) - break; - } - return ptr; -} - -void _aligned_free(void* p) { - // TCMalloc returns pointers from memalign() that are safe to use with free(). - // Pointers allocated with win_heap_memalign() MUST be freed via - // win_heap_memalign_free() since the aligned pointer is not the real one. - switch (allocator) { - case WINHEAP: - case WINLFH: - win_heap_memalign_free(p); - return; - case TCMALLOC: - do_free(p); - } -} - -#endif // WIN32 - -#include "generic_allocators.cc" - -} // extern C - -namespace base { -namespace allocator { - -void SetupSubprocessAllocator() { - size_t primary_length = 0; - getenv_s(&primary_length, NULL, 0, primary_name); - - size_t secondary_length = 0; - char buffer[20]; - getenv_s(&secondary_length, buffer, sizeof(buffer), secondary_name); - DCHECK_GT(sizeof(buffer), secondary_length); - buffer[sizeof(buffer) - 1] = '\0'; - - if (secondary_length || !primary_length) { -// Don't use the environment variable if SYZYASAN is defined, as the -// implementation require Winheap to be the allocator. -#if !defined(SYZYASAN) - const char* secondary_value = secondary_length ? buffer : "TCMALLOC"; - // Force renderer (or other subprocesses) to use secondary_value. -#else - const char* secondary_value = "WINHEAP"; -#endif - int ret_val = _putenv_s(primary_name, secondary_value); - DCHECK_EQ(0, ret_val); - } -} - -void* TCMallocDoMallocForTest(size_t size) { - return do_malloc(size); -} - -void TCMallocDoFreeForTest(void* ptr) { - do_free(ptr); -} - -size_t ExcludeSpaceForMarkForTest(size_t size) { - return ExcludeSpaceForMark(size); -} - -} // namespace allocator. -} // namespace base. diff --git a/base/allocator/allocator_shim.h b/base/allocator/allocator_shim.h deleted file mode 100644 index ca70ab0..0000000 --- a/base/allocator/allocator_shim.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef BASE_ALLOCATOR_ALLOCATOR_SHIM_H_ -#define BASE_ALLOCATOR_ALLOCATOR_SHIM_H_ - -#include <stddef.h> - -namespace base { -namespace allocator { - -// Resets the environment variable CHROME_ALLOCATOR to specify the choice to -// be used by subprocesses. Priority is given to the current value of -// CHROME_ALLOCATOR_2 (if specified), then CHROME_ALLOCATOR (if specified), and -// then a default value (typically set to TCMALLOC). -void SetupSubprocessAllocator(); - -// Expose some of tcmalloc functions for test. -void* TCMallocDoMallocForTest(size_t size); -void TCMallocDoFreeForTest(void* ptr); -size_t ExcludeSpaceForMarkForTest(size_t size); - -} // namespace allocator. -} // namespace base. - -#endif // BASE_ALLOCATOR_ALLOCATOR_SHIM_H_ diff --git a/base/allocator/allocator_shim_win.cc b/base/allocator/allocator_shim_win.cc new file mode 100644 index 0000000..0ebaa6b --- /dev/null +++ b/base/allocator/allocator_shim_win.cc @@ -0,0 +1,221 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <malloc.h> +#include <new.h> +#include <windows.h> + +#include "base/basictypes.h" + +// This shim make it possible to perform additional checks on allocations +// before passing them to the Heap functions. + +// new_mode behaves similarly to MSVC's _set_new_mode. +// If flag is 0 (default), calls to malloc will behave normally. +// If flag is 1, calls to malloc will behave like calls to new, +// and the std_new_handler will be invoked on failure. +// Can be set by calling _set_new_mode(). +static int new_mode = 0; + +namespace { + +// This is a simple allocator based on the windows heap. +const size_t kWindowsPageSize = 4096; +const size_t kMaxWindowsAllocation = INT_MAX - kWindowsPageSize; +static HANDLE win_heap; + +// VS2013 crt uses the process heap as its heap, so we do the same here. +// See heapinit.c in VS CRT sources. +bool win_heap_init() { + win_heap = GetProcessHeap(); + if (win_heap == NULL) + return false; + + ULONG enable_lfh = 2; + // NOTE: Setting LFH may fail. Vista already has it enabled. + // And under the debugger, it won't use LFH. So we + // ignore any errors. + HeapSetInformation(win_heap, HeapCompatibilityInformation, &enable_lfh, + sizeof(enable_lfh)); + + return true; +} + +void* win_heap_malloc(size_t size) { + if (size < kMaxWindowsAllocation) + return HeapAlloc(win_heap, 0, size); + return NULL; +} + +void win_heap_free(void* size) { + HeapFree(win_heap, 0, size); +} + +void* win_heap_realloc(void* ptr, size_t size) { + if (!ptr) + return win_heap_malloc(size); + if (!size) { + win_heap_free(ptr); + return NULL; + } + if (size < kMaxWindowsAllocation) + return HeapReAlloc(win_heap, 0, ptr, size); + return NULL; +} + +size_t win_heap_msize(void* ptr) { + return HeapSize(win_heap, 0, ptr); +} + +void* win_heap_memalign(size_t alignment, size_t size) { + // Reserve enough space to ensure we can align and set aligned_ptr[-1] to the + // original allocation for use with win_heap_memalign_free() later. + size_t allocation_size = size + (alignment - 1) + sizeof(void*); + + // Check for overflow. Alignment and size are checked in allocator_shim. + if (size >= allocation_size || alignment >= allocation_size) { + return NULL; + } + + // Since we're directly calling the allocator function, before OOM handling, + // we need to NULL check to ensure the allocation succeeded. + void* ptr = win_heap_malloc(allocation_size); + if (!ptr) + return ptr; + + char* aligned_ptr = static_cast<char*>(ptr) + sizeof(void*); + aligned_ptr += + alignment - reinterpret_cast<uintptr_t>(aligned_ptr) & (alignment - 1); + + reinterpret_cast<void**>(aligned_ptr)[-1] = ptr; + return aligned_ptr; +} + +void win_heap_memalign_free(void* ptr) { + if (ptr) + win_heap_free(static_cast<void**>(ptr)[-1]); +} + +void win_heap_term() { + win_heap = NULL; +} + +} // namespace + +// Call the new handler, if one has been set. +// Returns true on successfully calling the handler, false otherwise. +inline bool call_new_handler(bool nothrow, size_t size) { + // Get the current new handler. + _PNH nh = _query_new_handler(); +#if defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS + if (!nh) + return false; + // Since exceptions are disabled, we don't really know if new_handler + // failed. Assume it will abort if it fails. + return nh(size); +#else +#error "Exceptions in allocator shim are not supported!" +#endif // defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS + return false; +} + +extern "C" { + +void* malloc(size_t size) { + void* ptr; + for (;;) { + ptr = win_heap_malloc(size); + if (ptr) + return ptr; + + if (!new_mode || !call_new_handler(true, size)) + break; + } + return ptr; +} + +void free(void* p) { + win_heap_free(p); + return; +} + +void* realloc(void* ptr, size_t size) { + // Webkit is brittle for allocators that return NULL for malloc(0). The + // realloc(0, 0) code path does not guarantee a non-NULL return, so be sure + // to call malloc for this case. + if (!ptr) + return malloc(size); + + void* new_ptr; + for (;;) { + new_ptr = win_heap_realloc(ptr, size); + + // Subtle warning: NULL return does not alwas indicate out-of-memory. If + // the requested new size is zero, realloc should free the ptr and return + // NULL. + if (new_ptr || !size) + return new_ptr; + if (!new_mode || !call_new_handler(true, size)) + break; + } + return new_ptr; +} + + +size_t _msize(void* p) { + return win_heap_msize(p); +} + +intptr_t _get_heap_handle() { + return reinterpret_cast<intptr_t>(win_heap); +} + +// The CRT heap initialization stub. +int _heap_init() { + return win_heap_init() ? 1 : 0; +} + +// The CRT heap cleanup stub. +void _heap_term() { + win_heap_term(); +} + +// We set this to 1 because part of the CRT uses a check of _crtheap != 0 +// to test whether the CRT has been initialized. Once we've ripped out +// the allocators from libcmt, we need to provide this definition so that +// the rest of the CRT is still usable. +void* _crtheap = reinterpret_cast<void*>(1); + +// Provide support for aligned memory through Windows only _aligned_malloc(). +void* _aligned_malloc(size_t size, size_t alignment) { + // _aligned_malloc guarantees parameter validation, so do so here. These + // checks are somewhat stricter than _aligned_malloc() since we're effectively + // using memalign() under the hood. + if (size == 0U || (alignment & (alignment - 1)) != 0U || + (alignment % sizeof(void*)) != 0U) + return NULL; + + void* ptr; + for (;;) { + ptr = win_heap_memalign(alignment, size); + + if (ptr) { + return ptr; + } + + if (!new_mode || !call_new_handler(true, size)) + break; + } + return ptr; +} + +void _aligned_free(void* p) { + // Pointers allocated with win_heap_memalign() MUST be freed via + // win_heap_memalign_free() since the aligned pointer is not the real one. + win_heap_memalign_free(p); +} + +#include "generic_allocators.cc" + +} // extern C diff --git a/base/allocator/allocator_unittest.cc b/base/allocator/allocator_unittest.cc index a39b838..9471e95 100644 --- a/base/allocator/allocator_unittest.cc +++ b/base/allocator/allocator_unittest.cc @@ -280,7 +280,7 @@ static void TestCalloc(size_t n, size_t s, bool ok) { } else { EXPECT_NE(reinterpret_cast<void*>(NULL), p) << "calloc(n, s) should succeed"; - for (int i = 0; i < n*s; i++) { + for (size_t i = 0; i < n*s; i++) { EXPECT_EQ('\0', p[i]); } free(p); @@ -347,19 +347,19 @@ static void TestNothrowNew(void* (*func)(size_t)) { //----------------------------------------------------------------------------- TEST(Atomics, AtomicIncrementWord) { - TestAtomicIncrement<AtomicWord>(); + TestAtomicIncrement<base::subtle::AtomicWord>(); } TEST(Atomics, AtomicIncrement32) { - TestAtomicIncrement<Atomic32>(); + TestAtomicIncrement<base::subtle::Atomic32>(); } TEST(Atomics, AtomicOpsWord) { - TestAtomicIncrement<AtomicWord>(); + TestAtomicIncrement<base::subtle::AtomicWord>(); } TEST(Atomics, AtomicOps32) { - TestAtomicIncrement<Atomic32>(); + TestAtomicIncrement<base::subtle::Atomic32>(); } TEST(Allocators, Malloc) { @@ -458,6 +458,9 @@ TEST(Allocators, Realloc2) { free(p); } +// tcmalloc uses these semantics but system allocators can return NULL for +// realloc(ptr, 0). +#if defined(USE_TCMALLOC) TEST(Allocators, ReallocZero) { // Test that realloc to zero does not return NULL. for (int size = 0; size >= 0; size = NextSize(size)) { @@ -469,6 +472,7 @@ TEST(Allocators, ReallocZero) { free(ptr); } } +#endif #ifdef WIN32 // Test recalloc diff --git a/base/allocator/generic_allocators.cc b/base/allocator/generic_allocators.cc index d12f3b9..2726903 100644 --- a/base/allocator/generic_allocators.cc +++ b/base/allocator/generic_allocators.cc @@ -16,7 +16,7 @@ inline void* generic_cpp_alloc(size_t size, bool nothrow) { ptr = malloc(size); if (ptr) return ptr; - if (!call_new_handler(nothrow)) + if (!call_new_handler(nothrow, size)) break; } return ptr; @@ -83,7 +83,7 @@ void* calloc(size_t n, size_t elem_size) { return result; } -void cfree(void* p) __THROW { +void cfree(void* p) { free(p); } diff --git a/base/allocator/prep_libc.py b/base/allocator/prep_libc.py index 471140c..3238eec 100755 --- a/base/allocator/prep_libc.py +++ b/base/allocator/prep_libc.py @@ -4,8 +4,8 @@ # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # -# This script takes libcmt.lib for VS2005/08/10/12/13 and removes the allocation -# related functions from it. +# This script takes libcmt.lib for VS2013 and removes the allocation related +# functions from it. # # Usage: prep_libc.py <VCLibDir> <OutputDir> <arch> # @@ -19,16 +19,18 @@ import shutil import subprocess import sys -def run(command, filter=None): - """Run |command|, removing any lines that match |filter|. The filter is - to remove the echoing of input filename that 'lib' does.""" +def run(command): + """Run |command|. If any lines that match an error condition then + terminate.""" + error = 'cannot find member object' popen = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) out, _ = popen.communicate() for line in out.splitlines(): - if filter and line.strip() != filter: - print line - return popen.returncode + print line + if error and line.find(error) != -1: + print 'prep_libc.py: Error stripping object from C runtime.' + sys.exit(1) def main(): bindir = 'SELF_X86' @@ -43,28 +45,24 @@ def main(): shutil.copyfile(os.path.join(vs_install_dir, 'libcmt.lib'), output_lib) shutil.copyfile(os.path.join(vs_install_dir, 'libcmt.pdb'), os.path.join(outdir, 'libcmt.pdb')) + cvspath = 'f:\\binaries\\Intermediate\\vctools\\crt_bld\\' + bindir + \ + '\\crt\\prebuild\\build\\' + objdir + '\\mt_obj\\nativec\\\\'; + cppvspath = 'f:\\binaries\\Intermediate\\vctools\\crt_bld\\' + bindir + \ + '\\crt\\prebuild\\build\\' + objdir + '\\mt_obj\\nativecpp\\\\'; - vspaths = [ - 'build\\intel\\mt_obj\\', - 'f:\\dd\\vctools\\crt_bld\\' + bindir + \ - '\\crt\\src\\build\\' + objdir + '\\mt_obj\\', - 'F:\\dd\\vctools\\crt_bld\\' + bindir + \ - '\\crt\\src\\build\\' + objdir + '\\mt_obj\\nativec\\\\', - 'F:\\dd\\vctools\\crt_bld\\' + bindir + \ - '\\crt\\src\\build\\' + objdir + '\\mt_obj\\nativecpp\\\\', - 'f:\\binaries\\Intermediate\\vctools\\crt_bld\\' + bindir + \ - '\\crt\\prebuild\\build\\INTEL\\mt_obj\\cpp_obj\\\\', - ] - - objfiles = ['malloc', 'free', 'realloc', 'new', 'delete', 'new2', 'delete2', - 'align', 'msize', 'heapinit', 'expand', 'heapchk', 'heapwalk', - 'heapmin', 'sbheap', 'calloc', 'recalloc', 'calloc_impl', - 'new_mode', 'newopnt', 'newaopnt'] - for obj in objfiles: - for vspath in vspaths: - cmd = ('lib /nologo /ignore:4006,4014,4221 /remove:%s%s.obj %s' % - (vspath, obj, output_lib)) - run(cmd, obj + '.obj') + cobjfiles = ['malloc', 'free', 'realloc', 'align', 'msize', 'heapinit', + 'expand', 'heapchk', 'heapwalk', 'heapmin', 'calloc', 'recalloc', + 'calloc_impl'] + cppobjfiles = ['new', 'new2', 'delete', 'delete2', 'new_mode', 'newopnt', + 'newaopnt'] + for obj in cobjfiles: + cmd = ('lib /nologo /ignore:4006,4221 /remove:%s%s.obj %s' % + (cvspath, obj, output_lib)) + run(cmd) + for obj in cppobjfiles: + cmd = ('lib /nologo /ignore:4006,4221 /remove:%s%s.obj %s' % + (cppvspath, obj, output_lib)) + run(cmd) if __name__ == "__main__": sys.exit(main()) diff --git a/base/allocator/tcmalloc_unittest.cc b/base/allocator/tcmalloc_unittest.cc index 053a9d5..0f7082e 100644 --- a/base/allocator/tcmalloc_unittest.cc +++ b/base/allocator/tcmalloc_unittest.cc @@ -1,17 +1,32 @@ // Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <stddef.h> #include <stdio.h> -#include "base/allocator/allocator_shim.h" #include "testing/gtest/include/gtest/gtest.h" -// TCMalloc header files +// TCMalloc header files. #include "common.h" // For TCMalloc constants like page size, etc. -using base::allocator::TCMallocDoMallocForTest; -using base::allocator::TCMallocDoFreeForTest; -using base::allocator::ExcludeSpaceForMarkForTest; +// TCMalloc implementation. +#include "debugallocation_shim.cc" + +namespace { + +void* TCMallocDoMallocForTest(size_t size) { + return do_malloc(size); +} + +void TCMallocDoFreeForTest(void* ptr) { + do_free(ptr); +} + +size_t ExcludeSpaceForMarkForTest(size_t size) { + return ExcludeSpaceForMark(size); +} + +} // namespace TEST(TCMallocFreeCheck, BadPointerInFirstPageOfTheLargeObject) { char* p = reinterpret_cast<char*>( diff --git a/base/allocator/win_allocator.cc b/base/allocator/win_allocator.cc deleted file mode 100644 index ee451f5..0000000 --- a/base/allocator/win_allocator.cc +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -// This is a simple allocator based on the windows heap. - -extern "C" { - -HANDLE win_heap; - -bool win_heap_init(bool use_lfh) { - win_heap = HeapCreate(0, 0, 0); - if (win_heap == NULL) - return false; - - if (use_lfh) { - ULONG enable_lfh = 2; - HeapSetInformation(win_heap, HeapCompatibilityInformation, - &enable_lfh, sizeof(enable_lfh)); - // NOTE: Setting LFH may fail. Vista already has it enabled. - // And under the debugger, it won't use LFH. So we - // ignore any errors. - } - - return true; -} - -void* win_heap_malloc(size_t size) { - return HeapAlloc(win_heap, 0, size); -} - -void win_heap_free(void* size) { - HeapFree(win_heap, 0, size); -} - -void* win_heap_realloc(void* ptr, size_t size) { - if (!ptr) - return win_heap_malloc(size); - if (!size) { - win_heap_free(ptr); - return NULL; - } - return HeapReAlloc(win_heap, 0, ptr, size); -} - -size_t win_heap_msize(void* ptr) { - return HeapSize(win_heap, 0, ptr); -} - -void* win_heap_memalign(size_t alignment, size_t size) { - // Reserve enough space to ensure we can align and set aligned_ptr[-1] to the - // original allocation for use with win_heap_memalign_free() later. - size_t allocation_size = size + (alignment - 1) + sizeof(void*); - - // Check for overflow. Alignment and size are checked in allocator_shim. - DCHECK_LT(size, allocation_size); - DCHECK_LT(alignment, allocation_size); - - // Since we're directly calling the allocator function, before OOM handling, - // we need to NULL check to ensure the allocation succeeded. - void* ptr = win_heap_malloc(allocation_size); - if (!ptr) - return ptr; - - char* aligned_ptr = static_cast<char*>(ptr) + sizeof(void*); - aligned_ptr += - alignment - reinterpret_cast<uintptr_t>(aligned_ptr) & (alignment - 1); - - reinterpret_cast<void**>(aligned_ptr)[-1] = ptr; - return aligned_ptr; -} - -void win_heap_memalign_free(void* ptr) { - if (ptr) - win_heap_free(static_cast<void**>(ptr)[-1]); -} - -} // extern "C" diff --git a/base/profiler/alternate_timer.cc b/base/profiler/alternate_timer.cc index 4eba89c..02763cd 100644 --- a/base/profiler/alternate_timer.cc +++ b/base/profiler/alternate_timer.cc @@ -4,7 +4,7 @@ #include "base/profiler/alternate_timer.h" -#include "base/logging.h" +#include "base/basictypes.h" namespace { @@ -21,7 +21,6 @@ const char kAlternateProfilerTime[] = "CHROME_PROFILER_TIME"; // Set an alternate timer function to replace the OS time function when // profiling. void SetAlternateTimeSource(NowFunction* now_function, TimeSourceType type) { - DCHECK_EQ(reinterpret_cast<NowFunction*>(NULL), g_time_function); g_time_function = now_function; g_time_source_type = type; } diff --git a/base/security_unittest.cc b/base/security_unittest.cc index d786273..a7e3bc4 100644 --- a/base/security_unittest.cc +++ b/base/security_unittest.cc @@ -23,11 +23,46 @@ #include <unistd.h> #endif +#if defined(OS_WIN) +#include <new.h> +#endif + using std::nothrow; using std::numeric_limits; namespace { +#if defined(OS_WIN) +// This is a permitted size but exhausts memory pretty quickly. +const size_t kLargePermittedAllocation = 0x7FFFE000; + +int OnNoMemory(size_t) { + _exit(1); +} + +void ExhaustMemoryWithMalloc() { + for (;;) { + void* buf = malloc(kLargePermittedAllocation); + if (!buf) + break; + } +} + +void ExhaustMemoryWithRealloc() { + size_t size = kLargePermittedAllocation; + void* buf = malloc(size); + if (!buf) + return; + for (;;) { + size += kLargePermittedAllocation; + void* new_buf = realloc(buf, size); + if (!buf) + break; + buf = new_buf; + } +} +#endif + // This function acts as a compiler optimization barrier. We use it to // prevent the compiler from making an expression a compile-time constant. // We also use it so that the compiler doesn't discard certain return values @@ -42,15 +77,18 @@ Type HideValueFromCompiler(volatile Type value) { return value; } +// Tcmalloc and Windows allocator shim support setting malloc limits. // - NO_TCMALLOC (should be defined if compiled with use_allocator!="tcmalloc") // - ADDRESS_SANITIZER and SYZYASAN because they have their own memory allocator // - IOS does not use tcmalloc // - OS_MACOSX does not use tcmalloc -#if !defined(NO_TCMALLOC) && !defined(ADDRESS_SANITIZER) && \ - !defined(OS_IOS) && !defined(OS_MACOSX) && !defined(SYZYASAN) - #define TCMALLOC_TEST(function) function +// - Windows allocator shim defines ALLOCATOR_SHIM +#if (!defined(NO_TCMALLOC) || defined(ALLOCATOR_SHIM)) && \ + !defined(ADDRESS_SANITIZER) && !defined(OS_IOS) && !defined(OS_MACOSX) && \ + !defined(SYZYASAN) +#define MALLOC_OVERFLOW_TEST(function) function #else - #define TCMALLOC_TEST(function) DISABLED_##function +#define MALLOC_OVERFLOW_TEST(function) DISABLED_##function #endif // TODO(jln): switch to std::numeric_limits<int>::max() when we switch to @@ -64,12 +102,6 @@ bool IsTcMallocBypassed() { char* g_slice = getenv("G_SLICE"); if (g_slice && !strcmp(g_slice, "always-malloc")) return true; -#elif defined(OS_WIN) - // This should detect a TCMalloc bypass from setting - // the CHROME_ALLOCATOR environment variable. - char* allocator = getenv("CHROME_ALLOCATOR"); - if (allocator && strcmp(allocator, "tcmalloc")) - return true; #endif return false; } @@ -89,7 +121,7 @@ bool CallocDiesOnOOM() { } // Fake test that allow to know the state of TCMalloc by looking at bots. -TEST(SecurityTest, TCMALLOC_TEST(IsTCMallocDynamicallyBypassed)) { +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(IsTCMallocDynamicallyBypassed)) { printf("Malloc is dynamically bypassed: %s\n", IsTcMallocBypassed() ? "yes." : "no."); } @@ -99,7 +131,7 @@ TEST(SecurityTest, TCMALLOC_TEST(IsTCMallocDynamicallyBypassed)) { // vulnerabilities in libraries that use int instead of size_t. See // crbug.com/169327. -TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsMalloc)) { +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsMalloc)) { if (!IsTcMallocBypassed()) { scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>( HideValueFromCompiler(malloc(kTooBigAllocSize)))); @@ -107,7 +139,43 @@ TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsMalloc)) { } } -TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsCalloc)) { +#if defined(GTEST_HAS_DEATH_TEST) && defined(OS_WIN) +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationMallocDeathTest)) { + _set_new_handler(&OnNoMemory); + _set_new_mode(1); + { + scoped_ptr<char, base::FreeDeleter> ptr; + EXPECT_DEATH(ptr.reset(static_cast<char*>( + HideValueFromCompiler(malloc(kTooBigAllocSize)))), + ""); + ASSERT_TRUE(!ptr); + } + _set_new_handler(NULL); + _set_new_mode(0); +} + +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationExhaustDeathTest)) { + _set_new_handler(&OnNoMemory); + _set_new_mode(1); + { + ASSERT_DEATH(ExhaustMemoryWithMalloc(), ""); + } + _set_new_handler(NULL); + _set_new_mode(0); +} + +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryReallocationExhaustDeathTest)) { + _set_new_handler(&OnNoMemory); + _set_new_mode(1); + { + ASSERT_DEATH(ExhaustMemoryWithRealloc(), ""); + } + _set_new_handler(NULL); + _set_new_mode(0); +} +#endif + +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsCalloc)) { if (!IsTcMallocBypassed()) { scoped_ptr<char, base::FreeDeleter> ptr(static_cast<char*>( HideValueFromCompiler(calloc(kTooBigAllocSize, 1)))); @@ -115,7 +183,7 @@ TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsCalloc)) { } } -TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsRealloc)) { +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsRealloc)) { if (!IsTcMallocBypassed()) { char* orig_ptr = static_cast<char*>(malloc(1)); ASSERT_TRUE(orig_ptr); @@ -131,7 +199,7 @@ typedef struct { char large_array[kTooBigAllocSize]; } VeryLargeStruct; -TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNew)) { +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsNew)) { if (!IsTcMallocBypassed()) { scoped_ptr<VeryLargeStruct> ptr( HideValueFromCompiler(new (nothrow) VeryLargeStruct)); @@ -139,7 +207,20 @@ TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNew)) { } } -TEST(SecurityTest, TCMALLOC_TEST(MemoryAllocationRestrictionsNewArray)) { +#if defined(GTEST_HAS_DEATH_TEST) && defined(OS_WIN) +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationNewDeathTest)) { + _set_new_handler(&OnNoMemory); + { + scoped_ptr<VeryLargeStruct> ptr; + EXPECT_DEATH( + ptr.reset(HideValueFromCompiler(new (nothrow) VeryLargeStruct)), ""); + ASSERT_TRUE(!ptr); + } + _set_new_handler(NULL); +} +#endif + +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(MemoryAllocationRestrictionsNewArray)) { if (!IsTcMallocBypassed()) { scoped_ptr<char[]> ptr( HideValueFromCompiler(new (nothrow) char[kTooBigAllocSize])); @@ -242,7 +323,7 @@ bool ArePointersToSameArea(void* ptr1, void* ptr2, size_t size) { } // Check if TCMalloc uses an underlying random memory allocator. -TEST(SecurityTest, TCMALLOC_TEST(RandomMemoryAllocations)) { +TEST(SecurityTest, MALLOC_OVERFLOW_TEST(RandomMemoryAllocations)) { if (IsTcMallocBypassed()) return; size_t kPageSize = 4096; // We support x86_64 only. diff --git a/build/common.gypi b/build/common.gypi index abfa247..d3e39bb 100644 --- a/build/common.gypi +++ b/build/common.gypi @@ -1252,7 +1252,7 @@ # 'win_use_allocator_shim': 0, # 'win_release_RuntimeLibrary': 2 # to ~/.gyp/include.gypi, gclient runhooks --force, and do a release build. - 'win_use_allocator_shim%': 0, # 1 = shim allocator via libcmt; 0 = msvcrt + 'win_use_allocator_shim%': 1, # 1 = shim allocator via libcmt; 0 = msvcrt # TODO(bradnelson): eliminate this when possible. # To allow local gyp files to prevent release.vsprops from being included. @@ -1950,6 +1950,8 @@ # Native Client loader for 64-bit Windows. 'NACL_WIN64', ], + # Need to include allocator target, but exclude tcmalloc files. + 'use_allocator%': 'winheap', }], ['os_posix==1 and chromeos==0 and OS!="android" and OS!="ios" and embedded==0', { @@ -2762,10 +2764,11 @@ ['tracing_like_official_build!=0', { 'defines': ['TRACING_IS_OFFICIAL_BUILD=1'], }], # tracing_like_official_build!=0 - ['win_use_allocator_shim==0', { + ['OS=="win"', { + 'defines': ['NO_TCMALLOC'], 'conditions': [ - ['OS=="win"', { - 'defines': ['NO_TCMALLOC'], + ['win_use_allocator_shim==1', { + 'defines': ['ALLOCATOR_SHIM'], }], ], }], @@ -3423,7 +3426,7 @@ 'WTF_USE_DYNAMIC_ANNOTATIONS=1', ], }], - ['OS=="win" and win_use_allocator_shim==0', { + ['OS=="win"', { 'defines': ['NO_TCMALLOC'], }], # _FORTIFY_SOURCE isn't really supported by Clang now, see diff --git a/content/browser/browser_main_runner.cc b/content/browser/browser_main_runner.cc index 2975ef8..d5ed975 100644 --- a/content/browser/browser_main_runner.cc +++ b/content/browser/browser_main_runner.cc @@ -4,7 +4,6 @@ #include "content/public/browser/browser_main_runner.h" -#include "base/allocator/allocator_shim.h" #include "base/base_switches.h" #include "base/command_line.h" #include "base/debug/leak_annotations.h" @@ -184,14 +183,6 @@ class BrowserMainRunnerImpl : public BrowserMainRunner { // are NOT deleted. If you need something to run during WM_ENDSESSION add it // to browser_shutdown::Shutdown or BrowserProcess::EndSession. -#if defined(OS_WIN) && !defined(NO_TCMALLOC) - // When linking shared libraries, NO_TCMALLOC is defined, and dynamic - // allocator selection is not supported. - - // Make this call before going multithreaded, or spawning any - // subprocesses. - base::allocator::SetupSubprocessAllocator(); -#endif ui::InitializeInputMethod(); } main_loop_->CreateStartupTasks(); |