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,25 @@ |
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. |
+// TODO(jar): Switch to using TCMALLOC for the renderer as well. |
+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 +114,7 @@ |
case JEMALLOC: |
ptr = je_malloc(size); |
break; |
- case WINDEFAULT: |
+ case WINHEAP: |
case WINLFH: |
ptr = win_heap_malloc(size); |
break; |
@@ -129,7 +142,7 @@ |
case JEMALLOC: |
je_free(p); |
return; |
- case WINDEFAULT: |
+ case WINHEAP: |
case WINLFH: |
win_heap_free(p); |
return; |
@@ -153,7 +166,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 +198,7 @@ |
case JEMALLOC: |
// No stats. |
return; |
- case WINDEFAULT: |
+ case WINHEAP: |
case WINLFH: |
// No stats. |
return; |
@@ -201,7 +214,7 @@ |
switch (allocator) { |
case JEMALLOC: |
return je_msize(p); |
- case WINDEFAULT: |
+ case WINHEAP: |
case WINLFH: |
return win_heap_msize(p); |
} |
@@ -217,22 +230,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 +277,29 @@ |
#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); |
+ DCHECK_GT(sizeof(buffer), secondary_length); |
+ buffer[sizeof(buffer) - 1] = '\0'; |
+ |
+ 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. |