| OLD | NEW |
| 1 // Copyright (c) 2005, 2007, Google Inc. | 1 // Copyright (c) 2005, 2007, Google Inc. |
| 2 // All rights reserved. | 2 // All rights reserved. |
| 3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserv
ed. | 3 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2011 Apple Inc. All rights reserv
ed. |
| 4 // | 4 // |
| 5 // Redistribution and use in source and binary forms, with or without | 5 // Redistribution and use in source and binary forms, with or without |
| 6 // modification, are permitted provided that the following conditions are | 6 // modification, are permitted provided that the following conditions are |
| 7 // met: | 7 // met: |
| 8 // | 8 // |
| 9 // * Redistributions of source code must retain the above copyright | 9 // * Redistributions of source code must retain the above copyright |
| 10 // notice, this list of conditions and the following disclaimer. | 10 // notice, this list of conditions and the following disclaimer. |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 71 // | 71 // |
| 72 // 9/28/2003 (new page-level allocator replaces ptmalloc2): | 72 // 9/28/2003 (new page-level allocator replaces ptmalloc2): |
| 73 // * malloc/free of small objects goes from ~300 ns to ~50 ns. | 73 // * malloc/free of small objects goes from ~300 ns to ~50 ns. |
| 74 // * allocation of a reasonably complicated struct | 74 // * allocation of a reasonably complicated struct |
| 75 // goes from about 1100 ns to about 300 ns. | 75 // goes from about 1100 ns to about 300 ns. |
| 76 | 76 |
| 77 #include "config.h" | 77 #include "config.h" |
| 78 #include "FastMalloc.h" | 78 #include "FastMalloc.h" |
| 79 | 79 |
| 80 #include "Assertions.h" | 80 #include "Assertions.h" |
| 81 #include "CurrentTime.h" | |
| 82 | 81 |
| 83 #include <limits> | 82 #include <limits> |
| 84 #if OS(WINDOWS) | 83 #if OS(WINDOWS) |
| 85 #include <windows.h> | 84 #include <windows.h> |
| 86 #else | 85 #else |
| 87 #include <pthread.h> | 86 #include <pthread.h> |
| 88 #endif | 87 #endif |
| 89 #include <string.h> | 88 #include <string.h> |
| 90 #include <wtf/StdLibExtras.h> | 89 #include <wtf/StdLibExtras.h> |
| 91 #include <wtf/UnusedParam.h> | 90 #include <wtf/UnusedParam.h> |
| 92 | 91 |
| 93 #ifndef NO_TCMALLOC_SAMPLES | 92 #ifndef NO_TCMALLOC_SAMPLES |
| 94 #ifdef WTF_CHANGES | 93 #ifdef WTF_CHANGES |
| 95 #define NO_TCMALLOC_SAMPLES | 94 #define NO_TCMALLOC_SAMPLES |
| 96 #endif | 95 #endif |
| 97 #endif | 96 #endif |
| 98 | 97 |
| 99 #if !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) && defined(NDEBUG) | 98 #if !(defined(USE_SYSTEM_MALLOC) && USE_SYSTEM_MALLOC) && defined(NDEBUG) |
| 100 #define FORCE_SYSTEM_MALLOC 0 | 99 #define FORCE_SYSTEM_MALLOC 0 |
| 101 #else | 100 #else |
| 102 #define FORCE_SYSTEM_MALLOC 1 | 101 #define FORCE_SYSTEM_MALLOC 1 |
| 103 #endif | 102 #endif |
| 104 | 103 |
| 105 // Harden the pointers stored in the TCMalloc linked lists | 104 // Harden the pointers stored in the TCMalloc linked lists |
| 106 #if COMPILER(GCC) && !PLATFORM(QT) | 105 #if COMPILER(GCC) |
| 107 #define ENABLE_TCMALLOC_HARDENING 1 | 106 #define ENABLE_TCMALLOC_HARDENING 1 |
| 108 #endif | 107 #endif |
| 109 | 108 |
| 110 // Use a background thread to periodically scavenge memory to release back to th
e system | 109 // Use a background thread to periodically scavenge memory to release back to th
e system |
| 111 #if PLATFORM(IOS) | |
| 112 #define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 0 | |
| 113 #else | |
| 114 #define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 1 | 110 #define USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY 1 |
| 115 #endif | |
| 116 | 111 |
| 117 #ifndef NDEBUG | 112 #ifndef NDEBUG |
| 118 namespace WTF { | 113 namespace WTF { |
| 119 | 114 |
| 120 #if OS(WINDOWS) | 115 #if OS(WINDOWS) |
| 121 | 116 |
| 122 // TLS_OUT_OF_INDEXES is not defined on WinCE. | 117 // TLS_OUT_OF_INDEXES is not defined on WinCE. |
| 123 #ifndef TLS_OUT_OF_INDEXES | 118 #ifndef TLS_OUT_OF_INDEXES |
| 124 #define TLS_OUT_OF_INDEXES 0xffffffff | 119 #define TLS_OUT_OF_INDEXES 0xffffffff |
| 125 #endif | 120 #endif |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 | 648 |
| 654 // Maximum length we allow a per-thread free-list to have before we | 649 // Maximum length we allow a per-thread free-list to have before we |
| 655 // move objects from it into the corresponding central free-list. We | 650 // move objects from it into the corresponding central free-list. We |
| 656 // want this big to avoid locking the central free-list too often. It | 651 // want this big to avoid locking the central free-list too often. It |
| 657 // should not hurt to make this list somewhat big because the | 652 // should not hurt to make this list somewhat big because the |
| 658 // scavenging code will shrink it down when its contents are not in use. | 653 // scavenging code will shrink it down when its contents are not in use. |
| 659 static const int kMaxFreeListLength = 256; | 654 static const int kMaxFreeListLength = 256; |
| 660 | 655 |
| 661 // Lower and upper bounds on the per-thread cache sizes | 656 // Lower and upper bounds on the per-thread cache sizes |
| 662 static const size_t kMinThreadCacheSize = kMaxSize * 2; | 657 static const size_t kMinThreadCacheSize = kMaxSize * 2; |
| 663 #if PLATFORM(IOS) | |
| 664 static const size_t kMaxThreadCacheSize = 512 * 1024; | |
| 665 #else | |
| 666 static const size_t kMaxThreadCacheSize = 2 << 20; | 658 static const size_t kMaxThreadCacheSize = 2 << 20; |
| 667 #endif | |
| 668 | 659 |
| 669 // Default bound on the total amount of thread caches | 660 // Default bound on the total amount of thread caches |
| 670 static const size_t kDefaultOverallThreadCacheSize = 16 << 20; | 661 static const size_t kDefaultOverallThreadCacheSize = 16 << 20; |
| 671 | 662 |
| 672 // For all span-lengths < kMaxPages we keep an exact-size list. | 663 // For all span-lengths < kMaxPages we keep an exact-size list. |
| 673 // REQUIRED: kMaxPages >= kMinSystemAlloc; | 664 // REQUIRED: kMaxPages >= kMinSystemAlloc; |
| 674 static const size_t kMaxPages = kMinSystemAlloc; | 665 static const size_t kMaxPages = kMinSystemAlloc; |
| 675 | 666 |
| 676 /* The smallest prime > 2^n */ | 667 /* The smallest prime > 2^n */ |
| 677 static int primes_list[] = { | 668 static int primes_list[] = { |
| (...skipping 1607 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2285 | 2276 |
| 2286 ASSERT(Check()); | 2277 ASSERT(Check()); |
| 2287 } | 2278 } |
| 2288 | 2279 |
| 2289 #if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY | 2280 #if !USE_BACKGROUND_THREAD_TO_SCAVENGE_MEMORY |
| 2290 void TCMalloc_PageHeap::IncrementalScavenge(Length n) { | 2281 void TCMalloc_PageHeap::IncrementalScavenge(Length n) { |
| 2291 // Fast path; not yet time to release memory | 2282 // Fast path; not yet time to release memory |
| 2292 scavenge_counter_ -= n; | 2283 scavenge_counter_ -= n; |
| 2293 if (scavenge_counter_ >= 0) return; // Not yet time to scavenge | 2284 if (scavenge_counter_ >= 0) return; // Not yet time to scavenge |
| 2294 | 2285 |
| 2295 #if PLATFORM(IOS) | |
| 2296 static const size_t kDefaultReleaseDelay = 64; | |
| 2297 #else | |
| 2298 // If there is nothing to release, wait for so many pages before | 2286 // If there is nothing to release, wait for so many pages before |
| 2299 // scavenging again. With 4K pages, this comes to 16MB of memory. | 2287 // scavenging again. With 4K pages, this comes to 16MB of memory. |
| 2300 static const size_t kDefaultReleaseDelay = 1 << 8; | 2288 static const size_t kDefaultReleaseDelay = 1 << 8; |
| 2301 #endif | |
| 2302 | 2289 |
| 2303 // Find index of free list to scavenge | 2290 // Find index of free list to scavenge |
| 2304 size_t index = scavenge_index_ + 1; | 2291 size_t index = scavenge_index_ + 1; |
| 2305 uintptr_t entropy = entropy_; | 2292 uintptr_t entropy = entropy_; |
| 2306 for (size_t i = 0; i < kMaxPages+1; i++) { | 2293 for (size_t i = 0; i < kMaxPages+1; i++) { |
| 2307 if (index > kMaxPages) index = 0; | 2294 if (index > kMaxPages) index = 0; |
| 2308 SpanList* slist = (index == kMaxPages) ? &large_ : &free_[index]; | 2295 SpanList* slist = (index == kMaxPages) ? &large_ : &free_[index]; |
| 2309 if (!DLL_IsEmpty(&slist->normal, entropy)) { | 2296 if (!DLL_IsEmpty(&slist->normal, entropy)) { |
| 2310 // Release the last span on the normal portion of this list | 2297 // Release the last span on the normal portion of this list |
| 2311 Span* s = slist->normal.prev(entropy); | 2298 Span* s = slist->normal.prev(entropy); |
| 2312 DLL_Remove(s, entropy_); | 2299 DLL_Remove(s, entropy_); |
| 2313 TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift), | 2300 TCMalloc_SystemRelease(reinterpret_cast<void*>(s->start << kPageShift), |
| 2314 static_cast<size_t>(s->length << kPageShift)); | 2301 static_cast<size_t>(s->length << kPageShift)); |
| 2315 s->decommitted = true; | 2302 s->decommitted = true; |
| 2316 DLL_Prepend(&slist->returned, s, entropy); | 2303 DLL_Prepend(&slist->returned, s, entropy); |
| 2317 | 2304 |
| 2318 #if PLATFORM(IOS) | |
| 2319 scavenge_counter_ = std::max<size_t>(16UL, std::min<size_t>(kDefaultReleas
eDelay, kDefaultReleaseDelay - (free_pages_ / kDefaultReleaseDelay))); | |
| 2320 #else | |
| 2321 scavenge_counter_ = std::max<size_t>(64UL, std::min<size_t>(kDefaultReleas
eDelay, kDefaultReleaseDelay - (free_pages_ / kDefaultReleaseDelay))); | 2305 scavenge_counter_ = std::max<size_t>(64UL, std::min<size_t>(kDefaultReleas
eDelay, kDefaultReleaseDelay - (free_pages_ / kDefaultReleaseDelay))); |
| 2322 #endif | |
| 2323 | 2306 |
| 2324 if (index == kMaxPages && !DLL_IsEmpty(&slist->normal, entropy)) | 2307 if (index == kMaxPages && !DLL_IsEmpty(&slist->normal, entropy)) |
| 2325 scavenge_index_ = index - 1; | 2308 scavenge_index_ = index - 1; |
| 2326 else | 2309 else |
| 2327 scavenge_index_ = index; | 2310 scavenge_index_ = index; |
| 2328 return; | 2311 return; |
| 2329 } | 2312 } |
| 2330 index++; | 2313 index++; |
| 2331 } | 2314 } |
| 2332 | 2315 |
| (...skipping 2669 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5002 { | 4985 { |
| 5003 static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Cen
tral_FreeListPadded*>(central_cache), &span_allocator, &threadheap_allocator); | 4986 static FastMallocZone zone(pageheap, &thread_heaps, static_cast<TCMalloc_Cen
tral_FreeListPadded*>(central_cache), &span_allocator, &threadheap_allocator); |
| 5004 } | 4987 } |
| 5005 | 4988 |
| 5006 #endif // OS(DARWIN) | 4989 #endif // OS(DARWIN) |
| 5007 | 4990 |
| 5008 } // namespace WTF | 4991 } // namespace WTF |
| 5009 #endif // WTF_CHANGES | 4992 #endif // WTF_CHANGES |
| 5010 | 4993 |
| 5011 #endif // FORCE_SYSTEM_MALLOC | 4994 #endif // FORCE_SYSTEM_MALLOC |
| OLD | NEW |