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 |