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 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 allocationHook(address, size, typeName); | 61 allocationHook(address, size, typeName); |
62 } | 62 } |
63 | 63 |
64 static void freeHookIfEnabled(Address address) | 64 static void freeHookIfEnabled(Address address) |
65 { | 65 { |
66 FreeHook* freeHook = m_freeHook; | 66 FreeHook* freeHook = m_freeHook; |
67 if (UNLIKELY(!!freeHook)) | 67 if (UNLIKELY(!!freeHook)) |
68 freeHook(address); | 68 freeHook(address); |
69 } | 69 } |
70 | 70 |
71 static void reallocHookIfEnabled(Address oldAddress, Address newAddress, siz
e_t size, const char* typeName) | |
72 { | |
73 // Report a reallocation as a free followed by an allocation. | |
74 AllocationHook* allocationHook = m_allocationHook; | |
75 FreeHook* freeHook = m_freeHook; | |
76 if (UNLIKELY(allocationHook && freeHook)) { | |
77 freeHook(oldAddress); | |
78 allocationHook(newAddress, size, typeName); | |
79 } | |
80 } | |
81 | |
82 private: | 71 private: |
83 static AllocationHook* m_allocationHook; | 72 static AllocationHook* m_allocationHook; |
84 static FreeHook* m_freeHook; | 73 static FreeHook* m_freeHook; |
85 }; | 74 }; |
86 | 75 |
87 class CrossThreadPersistentRegion; | 76 class CrossThreadPersistentRegion; |
88 template<typename T> class Member; | 77 template<typename T> class Member; |
89 template<typename T> class WeakMember; | 78 template<typename T> class WeakMember; |
90 template<typename T> class UntracedMember; | 79 template<typename T> class UntracedMember; |
91 | 80 |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
232 // allocation size calculation can overflow for large sizes and the chec
k | 221 // allocation size calculation can overflow for large sizes and the chec
k |
233 // therefore has to happen before any calculation on the size. | 222 // therefore has to happen before any calculation on the size. |
234 RELEASE_ASSERT(size < maxHeapObjectSize); | 223 RELEASE_ASSERT(size < maxHeapObjectSize); |
235 | 224 |
236 // Add space for header. | 225 // Add space for header. |
237 size_t allocationSize = size + sizeof(HeapObjectHeader); | 226 size_t allocationSize = size + sizeof(HeapObjectHeader); |
238 // Align size with allocation granularity. | 227 // Align size with allocation granularity. |
239 allocationSize = (allocationSize + allocationMask) & ~allocationMask; | 228 allocationSize = (allocationSize + allocationMask) & ~allocationMask; |
240 return allocationSize; | 229 return allocationSize; |
241 } | 230 } |
242 static Address allocateOnArenaIndex(ThreadState*, size_t, int arenaIndex, si
ze_t gcInfoIndex); | 231 static Address allocateOnArenaIndex(ThreadState*, size_t, int arenaIndex, si
ze_t gcInfoIndex, const char* typeName); |
243 template<typename T> static Address allocate(size_t, bool eagerlySweep = fal
se); | 232 template<typename T> static Address allocate(size_t, bool eagerlySweep = fal
se); |
244 template<typename T> static Address reallocate(void* previous, size_t); | 233 template<typename T> static Address reallocate(void* previous, size_t); |
245 | 234 |
246 static const char* gcReasonString(BlinkGC::GCReason); | 235 static const char* gcReasonString(BlinkGC::GCReason); |
247 static void collectGarbage(BlinkGC::StackState, BlinkGC::GCType, BlinkGC::GC
Reason); | 236 static void collectGarbage(BlinkGC::StackState, BlinkGC::GCType, BlinkGC::GC
Reason); |
248 static void collectGarbageForTerminatingThread(ThreadState*); | 237 static void collectGarbageForTerminatingThread(ThreadState*); |
249 static void collectAllGarbage(); | 238 static void collectAllGarbage(); |
250 | 239 |
251 static void processMarkingStack(Visitor*); | 240 static void processMarkingStack(Visitor*); |
252 static void postMarkingProcessing(Visitor*); | 241 static void postMarkingProcessing(Visitor*); |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 #else | 467 #else |
479 #define EAGERLY_FINALIZE() typedef int IsEagerlyFinalizedMarker | 468 #define EAGERLY_FINALIZE() typedef int IsEagerlyFinalizedMarker |
480 #endif | 469 #endif |
481 | 470 |
482 #if !ENABLE(OILPAN) | 471 #if !ENABLE(OILPAN) |
483 #define EAGERLY_FINALIZE_WILL_BE_REMOVED() EAGERLY_FINALIZE() | 472 #define EAGERLY_FINALIZE_WILL_BE_REMOVED() EAGERLY_FINALIZE() |
484 #else | 473 #else |
485 #define EAGERLY_FINALIZE_WILL_BE_REMOVED() | 474 #define EAGERLY_FINALIZE_WILL_BE_REMOVED() |
486 #endif | 475 #endif |
487 | 476 |
488 inline Address Heap::allocateOnArenaIndex(ThreadState* state, size_t size, int a
renaIndex, size_t gcInfoIndex) | 477 inline Address Heap::allocateOnArenaIndex(ThreadState* state, size_t size, int a
renaIndex, size_t gcInfoIndex, const char* typeName) |
489 { | 478 { |
490 ASSERT(state->isAllocationAllowed()); | 479 ASSERT(state->isAllocationAllowed()); |
491 ASSERT(arenaIndex != BlinkGC::LargeObjectArenaIndex); | 480 ASSERT(arenaIndex != BlinkGC::LargeObjectArenaIndex); |
492 NormalPageArena* arena = static_cast<NormalPageArena*>(state->arena(arenaInd
ex)); | 481 NormalPageArena* arena = static_cast<NormalPageArena*>(state->arena(arenaInd
ex)); |
493 return arena->allocateObject(allocationSizeFromSize(size), gcInfoIndex); | 482 Address address = arena->allocateObject(allocationSizeFromSize(size), gcInfo
Index); |
| 483 HeapAllocHooks::allocationHookIfEnabled(address, size, typeName); |
| 484 return address; |
494 } | 485 } |
495 | 486 |
496 template<typename T> | 487 template<typename T> |
497 Address Heap::allocate(size_t size, bool eagerlySweep) | 488 Address Heap::allocate(size_t size, bool eagerlySweep) |
498 { | 489 { |
499 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); | 490 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
500 Address address = Heap::allocateOnArenaIndex(state, size, eagerlySweep ? Bli
nkGC::EagerSweepArenaIndex : Heap::arenaIndexForObjectSize(size), GCInfoTrait<T>
::index()); | |
501 const char* typeName = WTF_HEAP_PROFILER_TYPE_NAME(T); | 491 const char* typeName = WTF_HEAP_PROFILER_TYPE_NAME(T); |
502 HeapAllocHooks::allocationHookIfEnabled(address, size, typeName); | 492 return Heap::allocateOnArenaIndex(state, size, eagerlySweep ? BlinkGC::Eager
SweepArenaIndex : Heap::arenaIndexForObjectSize(size), GCInfoTrait<T>::index(),
typeName); |
503 return address; | |
504 } | 493 } |
505 | 494 |
506 template<typename T> | 495 template<typename T> |
507 Address Heap::reallocate(void* previous, size_t size) | 496 Address Heap::reallocate(void* previous, size_t size) |
508 { | 497 { |
509 // Not intended to be a full C realloc() substitute; | 498 // Not intended to be a full C realloc() substitute; |
510 // realloc(nullptr, size) is not a supported alias for malloc(size). | 499 // realloc(nullptr, size) is not a supported alias for malloc(size). |
511 | 500 |
512 // TODO(sof): promptly free the previous object. | 501 // TODO(sof): promptly free the previous object. |
513 if (!size) { | 502 if (!size) { |
514 // If the new size is 0 this is considered equivalent to free(previous). | 503 // If the new size is 0 this is considered equivalent to free(previous). |
515 return nullptr; | 504 return nullptr; |
516 } | 505 } |
517 | 506 |
518 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); | 507 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
519 HeapObjectHeader* previousHeader = HeapObjectHeader::fromPayload(previous); | 508 HeapObjectHeader* previousHeader = HeapObjectHeader::fromPayload(previous); |
520 BasePage* page = pageFromObject(previousHeader); | 509 BasePage* page = pageFromObject(previousHeader); |
521 ASSERT(page); | 510 ASSERT(page); |
522 int arenaIndex = page->arena()->arenaIndex(); | 511 int arenaIndex = page->arena()->arenaIndex(); |
523 // Recompute the effective heap index if previous allocation | 512 // Recompute the effective heap index if previous allocation |
524 // was on the normal arenas or a large object. | 513 // was on the normal arenas or a large object. |
525 if (isNormalArenaIndex(arenaIndex) || arenaIndex == BlinkGC::LargeObjectAren
aIndex) | 514 if (isNormalArenaIndex(arenaIndex) || arenaIndex == BlinkGC::LargeObjectAren
aIndex) |
526 arenaIndex = arenaIndexForObjectSize(size); | 515 arenaIndex = arenaIndexForObjectSize(size); |
527 | 516 |
528 // TODO(haraken): We don't support reallocate() for finalizable objects. | 517 // TODO(haraken): We don't support reallocate() for finalizable objects. |
529 ASSERT(!Heap::gcInfo(previousHeader->gcInfoIndex())->hasFinalizer()); | 518 ASSERT(!Heap::gcInfo(previousHeader->gcInfoIndex())->hasFinalizer()); |
530 ASSERT(previousHeader->gcInfoIndex() == GCInfoTrait<T>::index()); | 519 ASSERT(previousHeader->gcInfoIndex() == GCInfoTrait<T>::index()); |
531 Address address = Heap::allocateOnArenaIndex(state, size, arenaIndex, GCInfo
Trait<T>::index()); | 520 const char* typeName = WTF_HEAP_PROFILER_TYPE_NAME(T); |
| 521 HeapAllocHooks::freeHookIfEnabled(static_cast<Address>(previous)); |
| 522 Address address = Heap::allocateOnArenaIndex(state, size, arenaIndex, GCInfo
Trait<T>::index(), typeName); |
532 size_t copySize = previousHeader->payloadSize(); | 523 size_t copySize = previousHeader->payloadSize(); |
533 if (copySize > size) | 524 if (copySize > size) |
534 copySize = size; | 525 copySize = size; |
535 memcpy(address, previous, copySize); | 526 memcpy(address, previous, copySize); |
536 const char* typeName = WTF_HEAP_PROFILER_TYPE_NAME(T); | |
537 HeapAllocHooks::reallocHookIfEnabled(static_cast<Address>(previous), address
, size, typeName); | |
538 return address; | 527 return address; |
539 } | 528 } |
540 | 529 |
541 template<typename Derived> | 530 template<typename Derived> |
542 template<typename T> | 531 template<typename T> |
543 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) | 532 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) |
544 { | 533 { |
545 T** cell = reinterpret_cast<T**>(object); | 534 T** cell = reinterpret_cast<T**>(object); |
546 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) | 535 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) |
547 *cell = nullptr; | 536 *cell = nullptr; |
548 } | 537 } |
549 | 538 |
550 } // namespace blink | 539 } // namespace blink |
551 | 540 |
552 #endif // Heap_h | 541 #endif // Heap_h |
OLD | NEW |