OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 19 matching lines...) Expand all Loading... | |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "platform/heap/Heap.h" | 32 #include "platform/heap/Heap.h" |
33 | 33 |
34 #include "platform/ScriptForbiddenScope.h" | 34 #include "platform/ScriptForbiddenScope.h" |
35 #include "platform/Task.h" | 35 #include "platform/Task.h" |
36 #include "platform/TraceEvent.h" | 36 #include "platform/TraceEvent.h" |
37 #include "platform/heap/CallbackStack.h" | 37 #include "platform/heap/CallbackStack.h" |
38 #include "platform/heap/ThreadState.h" | 38 #include "platform/heap/ThreadState.h" |
39 #include "public/platform/Platform.h" | 39 #include "public/platform/Platform.h" |
40 #include "wtf/AddressSpaceRandomization.h" | |
41 #include "wtf/Assertions.h" | 40 #include "wtf/Assertions.h" |
42 #include "wtf/LeakAnnotations.h" | 41 #include "wtf/LeakAnnotations.h" |
42 #include "wtf/PageAllocator.h" | |
43 #include "wtf/PassOwnPtr.h" | 43 #include "wtf/PassOwnPtr.h" |
44 #if ENABLE(GC_PROFILE_MARKING) | 44 #if ENABLE(GC_PROFILE_MARKING) |
45 #include "wtf/HashMap.h" | 45 #include "wtf/HashMap.h" |
46 #include "wtf/HashSet.h" | 46 #include "wtf/HashSet.h" |
47 #include "wtf/text/StringBuilder.h" | 47 #include "wtf/text/StringBuilder.h" |
48 #include "wtf/text/StringHash.h" | 48 #include "wtf/text/StringHash.h" |
49 #include <stdio.h> | 49 #include <stdio.h> |
50 #include <utility> | 50 #include <utility> |
51 #endif | 51 #endif |
52 #if ENABLE(GC_PROFILE_HEAP) | 52 #if ENABLE(GC_PROFILE_HEAP) |
(...skipping 25 matching lines...) Expand all Loading... | |
78 return !!(*reinterpret_cast<Address*>(objectPointer)); | 78 return !!(*reinterpret_cast<Address*>(objectPointer)); |
79 } | 79 } |
80 | 80 |
81 #if OS(WIN) | 81 #if OS(WIN) |
82 static bool IsPowerOf2(size_t power) | 82 static bool IsPowerOf2(size_t power) |
83 { | 83 { |
84 return !((power - 1) & power); | 84 return !((power - 1) & power); |
85 } | 85 } |
86 #endif | 86 #endif |
87 | 87 |
88 static Address roundToBlinkPageBoundary(void* base) | |
89 { | |
90 return reinterpret_cast<Address>((reinterpret_cast<uintptr_t>(base) + blinkP ageOffsetMask) & blinkPageBaseMask); | |
91 } | |
92 | |
93 static size_t roundToOsPageSize(size_t size) | 88 static size_t roundToOsPageSize(size_t size) |
94 { | 89 { |
95 return (size + osPageSize() - 1) & ~(osPageSize() - 1); | 90 return (size + osPageSize() - 1) & ~(osPageSize() - 1); |
96 } | 91 } |
97 | 92 |
98 size_t osPageSize() | 93 size_t osPageSize() |
99 { | 94 { |
100 #if OS(POSIX) | 95 #if OS(POSIX) |
101 static const size_t pageSize = getpagesize(); | 96 static const size_t pageSize = getpagesize(); |
102 #else | 97 #else |
(...skipping 22 matching lines...) Expand all Loading... | |
125 return m_base <= addr && addr < (m_base + m_size); | 120 return m_base <= addr && addr < (m_base + m_size); |
126 } | 121 } |
127 | 122 |
128 bool contains(const MemoryRegion& other) const | 123 bool contains(const MemoryRegion& other) const |
129 { | 124 { |
130 return contains(other.m_base) && contains(other.m_base + other.m_size - 1); | 125 return contains(other.m_base) && contains(other.m_base + other.m_size - 1); |
131 } | 126 } |
132 | 127 |
133 void release() | 128 void release() |
134 { | 129 { |
135 #if OS(POSIX) | 130 WTF::freePages(m_base, m_size); |
136 int err = munmap(m_base, m_size); | |
137 RELEASE_ASSERT(!err); | |
138 #else | |
139 bool success = VirtualFree(m_base, 0, MEM_RELEASE); | |
140 RELEASE_ASSERT(success); | |
141 #endif | |
142 } | 131 } |
143 | 132 |
144 WARN_UNUSED_RETURN bool commit() | 133 WARN_UNUSED_RETURN bool commit() |
145 { | 134 { |
146 #if OS(POSIX) | 135 #if OS(POSIX) |
147 return !mprotect(m_base, m_size, PROT_READ | PROT_WRITE); | 136 return !mprotect(m_base, m_size, PROT_READ | PROT_WRITE); |
148 #else | 137 #else |
149 void* result = VirtualAlloc(m_base, m_size, MEM_COMMIT, PAGE_READWRITE); | 138 void* result = VirtualAlloc(m_base, m_size, MEM_COMMIT, PAGE_READWRITE); |
150 return !!result; | 139 return !!result; |
151 #endif | 140 #endif |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 ASSERT(contains(address)); | 229 ASSERT(contains(address)); |
241 if (m_isLargePage) | 230 if (m_isLargePage) |
242 return 0; | 231 return 0; |
243 size_t offset = blinkPageAddress(address) - base(); | 232 size_t offset = blinkPageAddress(address) - base(); |
244 ASSERT(offset % blinkPageSize == 0); | 233 ASSERT(offset % blinkPageSize == 0); |
245 return offset / blinkPageSize; | 234 return offset / blinkPageSize; |
246 } | 235 } |
247 | 236 |
248 static PageMemoryRegion* allocate(size_t size, unsigned numPages) | 237 static PageMemoryRegion* allocate(size_t size, unsigned numPages) |
249 { | 238 { |
250 // Compute a random blink page aligned address for the page memory | 239 // Round size up to the allocation granularity. |
251 // region and attempt to get the memory there. | 240 size = (size + WTF::kPageAllocationGranularityOffsetMask) & WTF::kPageAl locationGranularityBaseMask; |
252 Address randomAddress = reinterpret_cast<Address>(WTF::getRandomPageBase ()); | 241 Address base = static_cast<Address>(WTF::allocPages(nullptr, size, blink PageSize)); |
253 Address alignedRandomAddress = roundToBlinkPageBoundary(randomAddress); | |
254 | |
255 #if OS(POSIX) | |
256 Address base = static_cast<Address>(mmap(alignedRandomAddress, size, PRO T_NONE, MAP_ANON | MAP_PRIVATE, -1, 0)); | |
257 if (base == roundToBlinkPageBoundary(base)) | |
258 return new PageMemoryRegion(base, size, numPages); | |
259 | |
260 // We failed to get a blink page aligned chunk of memory. | |
261 // Unmap the chunk that we got and fall back to overallocating | |
262 // and selecting an aligned sub part of what we allocate. | |
263 if (base != MAP_FAILED) { | |
264 int error = munmap(base, size); | |
265 RELEASE_ASSERT(!error); | |
266 } | |
267 size_t allocationSize = size + blinkPageSize; | |
268 for (int attempt = 0; attempt < 10; attempt++) { | |
269 base = static_cast<Address>(mmap(alignedRandomAddress, allocationSiz e, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0)); | |
270 if (base != MAP_FAILED) | |
271 break; | |
272 randomAddress = reinterpret_cast<Address>(WTF::getRandomPageBase()); | |
273 alignedRandomAddress = roundToBlinkPageBoundary(randomAddress); | |
274 } | |
275 RELEASE_ASSERT(base != MAP_FAILED); | |
276 | |
277 Address end = base + allocationSize; | |
278 Address alignedBase = roundToBlinkPageBoundary(base); | |
279 Address regionEnd = alignedBase + size; | |
280 | |
281 // If the allocated memory was not blink page aligned release | |
282 // the memory before the aligned address. | |
283 if (alignedBase != base) | |
284 MemoryRegion(base, alignedBase - base).release(); | |
285 | |
286 // Free the additional memory at the end of the page if any. | |
287 if (regionEnd < end) | |
288 MemoryRegion(regionEnd, end - regionEnd).release(); | |
289 | |
290 return new PageMemoryRegion(alignedBase, size, numPages); | |
291 #else | |
292 Address base = static_cast<Address>(VirtualAlloc(alignedRandomAddress, s ize, MEM_RESERVE, PAGE_NOACCESS)); | |
293 if (base) { | |
294 ASSERT(base == alignedRandomAddress); | |
295 return new PageMemoryRegion(base, size, numPages); | |
296 } | |
297 | |
298 // We failed to get the random aligned address that we asked | |
299 // for. Fall back to overallocating. On Windows it is | |
300 // impossible to partially release a region of memory | |
301 // allocated by VirtualAlloc. To avoid wasting virtual address | |
302 // space we attempt to release a large region of memory | |
303 // returned as a whole and then allocate an aligned region | |
304 // inside this larger region. | |
305 size_t allocationSize = size + blinkPageSize; | |
306 for (int attempt = 0; attempt < 3; attempt++) { | |
307 base = static_cast<Address>(VirtualAlloc(0, allocationSize, MEM_RESE RVE, PAGE_NOACCESS)); | |
308 RELEASE_ASSERT(base); | |
309 VirtualFree(base, 0, MEM_RELEASE); | |
310 | |
311 Address alignedBase = roundToBlinkPageBoundary(base); | |
312 base = static_cast<Address>(VirtualAlloc(alignedBase, size, MEM_RESE RVE, PAGE_NOACCESS)); | |
313 if (base) { | |
314 ASSERT(base == alignedBase); | |
315 return new PageMemoryRegion(alignedBase, size, numPages); | |
316 } | |
317 } | |
318 | |
319 // We failed to avoid wasting virtual address space after | |
320 // several attempts. | |
321 base = static_cast<Address>(VirtualAlloc(0, allocationSize, MEM_RESERVE, PAGE_NOACCESS)); | |
322 RELEASE_ASSERT(base); | 242 RELEASE_ASSERT(base); |
323 | 243 WTF::setSystemPagesInaccessible(base, size); |
Jens Widell
2014/11/17 10:20:07
I realized the old code here actually allocated in
| |
324 // FIXME: If base is by accident blink page size aligned | 244 return new PageMemoryRegion(base, size, numPages); |
325 // here then we can create two pages out of reserved | |
326 // space. Do this. | |
327 Address alignedBase = roundToBlinkPageBoundary(base); | |
328 | |
329 return new PageMemoryRegion(alignedBase, size, numPages); | |
330 #endif | |
331 } | 245 } |
332 | 246 |
333 bool m_isLargePage; | 247 bool m_isLargePage; |
334 bool m_inUse[blinkPagesPerRegion]; | 248 bool m_inUse[blinkPagesPerRegion]; |
335 unsigned m_numPages; | 249 unsigned m_numPages; |
336 }; | 250 }; |
337 | 251 |
338 // Representation of the memory used for a Blink heap page. | 252 // Representation of the memory used for a Blink heap page. |
339 // | 253 // |
340 // The representation keeps track of two memory regions: | 254 // The representation keeps track of two memory regions: |
(...skipping 2627 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2968 CallbackStack* Heap::s_weakCallbackStack; | 2882 CallbackStack* Heap::s_weakCallbackStack; |
2969 CallbackStack* Heap::s_ephemeronStack; | 2883 CallbackStack* Heap::s_ephemeronStack; |
2970 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache; | 2884 HeapDoesNotContainCache* Heap::s_heapDoesNotContainCache; |
2971 bool Heap::s_shutdownCalled = false; | 2885 bool Heap::s_shutdownCalled = false; |
2972 bool Heap::s_lastGCWasConservative = false; | 2886 bool Heap::s_lastGCWasConservative = false; |
2973 FreePagePool* Heap::s_freePagePool; | 2887 FreePagePool* Heap::s_freePagePool; |
2974 OrphanedPagePool* Heap::s_orphanedPagePool; | 2888 OrphanedPagePool* Heap::s_orphanedPagePool; |
2975 Heap::RegionTree* Heap::s_regionTree = 0; | 2889 Heap::RegionTree* Heap::s_regionTree = 0; |
2976 | 2890 |
2977 } // namespace blink | 2891 } // namespace blink |
OLD | NEW |