Chromium Code Reviews| Index: base/allocator/allocator_shim.cc |
| =================================================================== |
| --- base/allocator/allocator_shim.cc (revision 77155) |
| +++ base/allocator/allocator_shim.cc (working copy) |
| @@ -2,6 +2,8 @@ |
| // 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> |
| // When defined, different heap allocators can be used via an environment |
| @@ -29,14 +31,24 @@ |
| typedef enum { |
| TCMALLOC, // TCMalloc is the default allocator. |
| - JEMALLOC, // JEMalloc |
| - WINDEFAULT, // Windows Heap |
| - WINLFH, // Windows LFH Heap |
| + JEMALLOC, // JEMalloc. |
| + WINHEAP, // Windows Heap (standard Windows allocator). |
| + WINLFH, // Windows LFH Heap. |
| } Allocator; |
| -// This is the default allocator. |
| -static Allocator allocator = TCMALLOC; |
| +// 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. |
| +static Allocator allocator = WINHEAP; |
| +// 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 "tcmalloc.cc" |
| @@ -101,7 +113,7 @@ |
| case JEMALLOC: |
| ptr = je_malloc(size); |
| break; |
| - case WINDEFAULT: |
| + case WINHEAP: |
| case WINLFH: |
| ptr = win_heap_malloc(size); |
| break; |
| @@ -129,7 +141,7 @@ |
| case JEMALLOC: |
| je_free(p); |
| return; |
| - case WINDEFAULT: |
| + case WINHEAP: |
| case WINLFH: |
| win_heap_free(p); |
| return; |
| @@ -153,7 +165,7 @@ |
| case JEMALLOC: |
| new_ptr = je_realloc(ptr, size); |
| break; |
| - case WINDEFAULT: |
| + case WINHEAP: |
| case WINLFH: |
| new_ptr = win_heap_realloc(ptr, size); |
| break; |
| @@ -185,7 +197,7 @@ |
| case JEMALLOC: |
| // No stats. |
| return; |
| - case WINDEFAULT: |
| + case WINHEAP: |
| case WINLFH: |
| // No stats. |
| return; |
| @@ -201,7 +213,7 @@ |
| switch (allocator) { |
| case JEMALLOC: |
| return je_msize(p); |
| - case WINDEFAULT: |
| + case WINHEAP: |
| case WINLFH: |
| return win_heap_msize(p); |
| } |
| @@ -217,22 +229,22 @@ |
| // The CRT heap initialization stub. |
| extern "C" int _heap_init() { |
| #ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING |
| - const char* override = GetenvBeforeMain("CHROME_ALLOCATOR"); |
| - if (override) { |
| - if (!stricmp(override, "jemalloc")) |
| + const char* environment_value = GetenvBeforeMain(primary_name); |
| + if (environment_value) { |
| + if (!stricmp(environment_value, "jemalloc")) |
| allocator = JEMALLOC; |
| - else if (!stricmp(override, "winheap")) |
| - allocator = WINDEFAULT; |
| - else if (!stricmp(override, "winlfh")) |
| + else if (!stricmp(environment_value, "winheap")) |
| + allocator = WINHEAP; |
| + else if (!stricmp(environment_value, "winlfh")) |
| allocator = WINLFH; |
| - else if (!stricmp(override, "tcmalloc")) |
| + else if (!stricmp(environment_value, "tcmalloc")) |
| allocator = TCMALLOC; |
| } |
| switch (allocator) { |
| case JEMALLOC: |
| return je_malloc_init_hard() ? 0 : 1; |
| - case WINDEFAULT: |
| + case WINHEAP: |
| return win_heap_init(false) ? 1 : 0; |
| case WINLFH: |
| return win_heap_init(true) ? 1 : 0; |
| @@ -264,3 +276,28 @@ |
| #include "generic_allocators.cc" |
| } // extern C |
| + |
| +namespace base { |
| +namespace allocator { |
| + |
| +void SetupSubprocessAllocator() { |
| +#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING |
| + 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); |
|
Mike Belshe
2011/03/07 22:37:16
nit: not sure if this API provides null terminatio
jar (doing other things)
2011/03/07 22:45:07
Added safety net null termination (especially sinc
|
| + DCHECK_GT(sizeof(buffer), secondary_length); |
| + |
| + if (secondary_length || !primary_length) { |
| + char* secondary_value = secondary_length ? buffer : "TCMALLOC"; |
| + // Force renderer (or other subprocesses) to use secondary_value. |
| + int ret_val = _putenv_s(primary_name, secondary_value); |
| + CHECK_EQ(0, ret_val); |
| + } |
| +#endif // ENABLE_DYNAMIC_ALLOCATOR_SWITCHING |
| +} |
| + |
| +} // namespace base. |
| +} // namespace allocator. |