OLD | NEW |
---|---|
1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 | 5 |
6 #include "base/process_util.h" | 6 #include "base/process_util.h" |
7 | 7 |
8 #import <Cocoa/Cocoa.h> | 8 #import <Cocoa/Cocoa.h> |
9 #include <crt_externs.h> | 9 #include <crt_externs.h> |
10 #include <dlfcn.h> | 10 #include <dlfcn.h> |
11 #include <mach/mach.h> | 11 #include <mach/mach.h> |
12 #include <mach/mach_init.h> | 12 #include <mach/mach_init.h> |
13 #include <mach/task.h> | 13 #include <mach/task.h> |
14 #include <malloc/malloc.h> | 14 #include <malloc/malloc.h> |
15 #import <objc/runtime.h> | 15 #import <objc/runtime.h> |
16 #include <spawn.h> | 16 #include <spawn.h> |
17 #include <sys/mman.h> | 17 #include <sys/mman.h> |
18 #include <sys/sysctl.h> | 18 #include <sys/sysctl.h> |
19 #include <sys/types.h> | 19 #include <sys/types.h> |
20 #include <sys/utsname.h> | |
20 #include <sys/wait.h> | 21 #include <sys/wait.h> |
21 | 22 |
22 #include <new> | 23 #include <new> |
23 #include <string> | 24 #include <string> |
24 | 25 |
25 #include "base/debug_util.h" | 26 #include "base/debug_util.h" |
26 #include "base/eintr_wrapper.h" | 27 #include "base/eintr_wrapper.h" |
27 #include "base/logging.h" | 28 #include "base/logging.h" |
28 #include "base/string_util.h" | 29 #include "base/string_util.h" |
29 #include "base/sys_info.h" | 30 #include "base/sys_info.h" |
(...skipping 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
606 return malloc_purgeable_zone(); | 607 return malloc_purgeable_zone(); |
607 return NULL; | 608 return NULL; |
608 } | 609 } |
609 | 610 |
610 void EnableTerminationOnOutOfMemory() { | 611 void EnableTerminationOnOutOfMemory() { |
611 if (g_oom_killer_enabled) | 612 if (g_oom_killer_enabled) |
612 return; | 613 return; |
613 | 614 |
614 g_oom_killer_enabled = true; | 615 g_oom_killer_enabled = true; |
615 | 616 |
616 int32 os_major; | 617 // Not SysInfo::OperatingSystemVersionNumbers as that calls through to Gestalt |
617 int32 os_minor; | 618 // which ends up (on > 10.6) spawning threads. |
618 int32 os_bugfix; | 619 struct utsname machine_info; |
619 SysInfo::OperatingSystemVersionNumbers(&os_major, &os_minor, &os_bugfix); | 620 if (uname(&machine_info)) { |
621 return; | |
622 } | |
623 | |
624 // The string machine_info.release is the xnu/Darwin version number, "9.xxx" | |
625 // on Mac OS X 10.5, and "10.xxx" on Mac OS X 10.6. See | |
626 // http://en.wikipedia.org/wiki/Darwin_(operating_system) . | |
627 long darwin_version = strtol(machine_info.release, (char**)NULL, 10); | |
Mark Mentovai
2010/08/24 15:13:24
Do you really need this cast?
Avi (use Gerrit)
2010/08/24 15:16:37
No. Done.
| |
620 | 628 |
621 // === C malloc/calloc/valloc/realloc/posix_memalign === | 629 // === C malloc/calloc/valloc/realloc/posix_memalign === |
622 | 630 |
623 // This approach is not perfect, as requests for amounts of memory larger than | 631 // This approach is not perfect, as requests for amounts of memory larger than |
624 // MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will | 632 // MALLOC_ABSOLUTE_MAX_SIZE (currently SIZE_T_MAX - (2 * PAGE_SIZE)) will |
625 // still fail with a NULL rather than dying (see | 633 // still fail with a NULL rather than dying (see |
626 // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details). | 634 // http://opensource.apple.com/source/Libc/Libc-583/gen/malloc.c for details). |
627 // Unfortunately, it's the best we can do. Also note that this does not affect | 635 // Unfortunately, it's the best we can do. Also note that this does not affect |
628 // allocations from non-default zones. | 636 // allocations from non-default zones. |
629 | 637 |
630 CHECK(!g_old_malloc && !g_old_calloc && !g_old_valloc && !g_old_realloc && | 638 CHECK(!g_old_malloc && !g_old_calloc && !g_old_valloc && !g_old_realloc && |
631 !g_old_memalign) << "Old allocators unexpectedly non-null"; | 639 !g_old_memalign) << "Old allocators unexpectedly non-null"; |
632 | 640 |
633 CHECK(!g_old_malloc_purgeable && !g_old_calloc_purgeable && | 641 CHECK(!g_old_malloc_purgeable && !g_old_calloc_purgeable && |
634 !g_old_valloc_purgeable && !g_old_realloc_purgeable && | 642 !g_old_valloc_purgeable && !g_old_realloc_purgeable && |
635 !g_old_memalign_purgeable) << "Old allocators unexpectedly non-null"; | 643 !g_old_memalign_purgeable) << "Old allocators unexpectedly non-null"; |
636 | 644 |
637 // See http://trac.webkit.org/changeset/53362/trunk/WebKitTools/DumpRenderTree /mac | 645 // See http://trac.webkit.org/changeset/53362/trunk/WebKitTools/DumpRenderTree /mac |
638 bool zone_allocators_protected = | 646 bool zone_allocators_protected = darwin_version > 10; |
639 ((os_major == 10 && os_minor > 6) || os_major > 10); | |
640 | 647 |
641 ChromeMallocZone* default_zone = | 648 ChromeMallocZone* default_zone = |
642 reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); | 649 reinterpret_cast<ChromeMallocZone*>(malloc_default_zone()); |
643 ChromeMallocZone* purgeable_zone = | 650 ChromeMallocZone* purgeable_zone = |
644 reinterpret_cast<ChromeMallocZone*>(GetPurgeableZone()); | 651 reinterpret_cast<ChromeMallocZone*>(GetPurgeableZone()); |
645 | 652 |
646 vm_address_t page_start_default = NULL; | 653 vm_address_t page_start_default = NULL; |
647 vm_address_t page_start_purgeable = NULL; | 654 vm_address_t page_start_purgeable = NULL; |
648 vm_size_t len_default = 0; | 655 vm_size_t len_default = 0; |
649 vm_size_t len_purgeable = 0; | 656 vm_size_t len_purgeable = 0; |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
745 // === Core Foundation CFAllocators === | 752 // === Core Foundation CFAllocators === |
746 | 753 |
747 // This will not catch allocation done by custom allocators, but will catch | 754 // This will not catch allocation done by custom allocators, but will catch |
748 // all allocation done by system-provided ones. | 755 // all allocation done by system-provided ones. |
749 | 756 |
750 CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc && | 757 CHECK(!g_old_cfallocator_system_default && !g_old_cfallocator_malloc && |
751 !g_old_cfallocator_malloc_zone) | 758 !g_old_cfallocator_malloc_zone) |
752 << "Old allocators unexpectedly non-null"; | 759 << "Old allocators unexpectedly non-null"; |
753 | 760 |
754 bool cf_allocator_internals_known = | 761 bool cf_allocator_internals_known = |
755 (os_major == 10 && (os_minor == 5 || os_minor == 6)); | 762 (darwin_version == 9) || (darwin_version == 10); |
Mark Mentovai
2010/08/24 15:13:24
The parentheses aren’t necessary and I don’t think
Avi (use Gerrit)
2010/08/24 15:16:37
Done.
| |
756 | 763 |
757 if (cf_allocator_internals_known) { | 764 if (cf_allocator_internals_known) { |
758 ChromeCFAllocatorRef allocator = const_cast<ChromeCFAllocatorRef>( | 765 ChromeCFAllocatorRef allocator = const_cast<ChromeCFAllocatorRef>( |
759 reinterpret_cast<const ChromeCFAllocator*>(kCFAllocatorSystemDefault)); | 766 reinterpret_cast<const ChromeCFAllocator*>(kCFAllocatorSystemDefault)); |
760 g_old_cfallocator_system_default = allocator->context.allocate; | 767 g_old_cfallocator_system_default = allocator->context.allocate; |
761 CHECK(g_old_cfallocator_system_default) | 768 CHECK(g_old_cfallocator_system_default) |
762 << "Failed to get kCFAllocatorSystemDefault allocation function."; | 769 << "Failed to get kCFAllocatorSystemDefault allocation function."; |
763 allocator->context.allocate = oom_killer_cfallocator_system_default; | 770 allocator->context.allocate = oom_killer_cfallocator_system_default; |
764 | 771 |
765 allocator = const_cast<ChromeCFAllocatorRef>( | 772 allocator = const_cast<ChromeCFAllocatorRef>( |
(...skipping 27 matching lines...) Expand all Loading... | |
793 @selector(allocWithZone:)); | 800 @selector(allocWithZone:)); |
794 g_old_allocWithZone = reinterpret_cast<allocWithZone_t>( | 801 g_old_allocWithZone = reinterpret_cast<allocWithZone_t>( |
795 method_getImplementation(orig_method)); | 802 method_getImplementation(orig_method)); |
796 CHECK(g_old_allocWithZone) | 803 CHECK(g_old_allocWithZone) |
797 << "Failed to get allocWithZone allocation function."; | 804 << "Failed to get allocWithZone allocation function."; |
798 method_setImplementation(orig_method, | 805 method_setImplementation(orig_method, |
799 reinterpret_cast<IMP>(oom_killer_allocWithZone)); | 806 reinterpret_cast<IMP>(oom_killer_allocWithZone)); |
800 } | 807 } |
801 | 808 |
802 } // namespace base | 809 } // namespace base |
OLD | NEW |