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