Chromium Code Reviews| 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 29 matching lines...) Expand all Loading... | |
| 40 #include "wtf/Assertions.h" | 40 #include "wtf/Assertions.h" |
| 41 #include "wtf/Atomics.h" | 41 #include "wtf/Atomics.h" |
| 42 #include "wtf/Forward.h" | 42 #include "wtf/Forward.h" |
| 43 | 43 |
| 44 namespace blink { | 44 namespace blink { |
| 45 | 45 |
| 46 template<typename T> class Member; | 46 template<typename T> class Member; |
| 47 template<typename T> class WeakMember; | 47 template<typename T> class WeakMember; |
| 48 template<typename T> class UntracedMember; | 48 template<typename T> class UntracedMember; |
| 49 | 49 |
| 50 // TODO(peria): Refactor following two sets of template. | |
| 51 | |
| 50 template<typename T, bool = NeedsAdjustAndMark<T>::value> class ObjectAliveTrait ; | 52 template<typename T, bool = NeedsAdjustAndMark<T>::value> class ObjectAliveTrait ; |
| 51 | 53 |
| 52 template<typename T> | 54 template<typename T> |
| 53 class ObjectAliveTrait<T, false> { | 55 class ObjectAliveTrait<T, false> { |
| 54 public: | 56 public: |
| 55 static bool isHeapObjectAlive(T* object) | 57 static bool isHeapObjectAlive(T* object) |
| 56 { | 58 { |
| 57 static_assert(sizeof(T), "T must be fully defined"); | 59 static_assert(sizeof(T), "T must be fully defined"); |
| 58 return HeapObjectHeader::fromPayload(object)->isMarked(); | 60 return HeapObjectHeader::fromPayload(object)->isMarked(); |
| 59 } | 61 } |
| 60 }; | 62 }; |
| 61 | 63 |
| 62 template<typename T> | 64 template<typename T> |
| 63 class ObjectAliveTrait<T, true> { | 65 class ObjectAliveTrait<T, true> { |
| 64 public: | 66 public: |
| 65 static bool isHeapObjectAlive(T* object) | 67 static bool isHeapObjectAlive(T* object) |
| 66 { | 68 { |
| 67 static_assert(sizeof(T), "T must be fully defined"); | 69 static_assert(sizeof(T), "T must be fully defined"); |
| 68 return object->isHeapObjectAlive(); | 70 return object->isHeapObjectAlive(); |
| 69 } | 71 } |
| 70 }; | 72 }; |
| 71 | 73 |
| 74 template<typename T, bool = IsGarbageCollectedMixin<T>::value> class HeapObjectH eaderTrait; | |
| 75 | |
| 76 template<typename T> | |
| 77 class HeapObjectHeaderTrait<T, true> { | |
| 78 public: | |
| 79 static HeapObjectHeader* heapObjectHeader(T* obj) | |
| 80 { | |
|
haraken
2015/11/16 02:47:49
Can you add:
static_assert(sizeof(T), "T must b
peria
2015/11/16 05:33:26
Done.
| |
| 81 return obj->heapObjectHeader(); | |
| 82 } | |
| 83 static uint32_t gcGeneration(T* obj) | |
| 84 { | |
| 85 // While constructing GarbageCollectedMixin classes, we skip looking | |
| 86 // for gcGeneration, because the object may not be fully allocated. | |
| 87 if (ThreadState::current()->isConstructingGCMixin()) | |
| 88 return 0; | |
| 89 return heapObjectHeader(obj)->gcGeneration(); | |
| 90 } | |
| 91 }; | |
| 92 | |
| 93 template<typename T> | |
| 94 class HeapObjectHeaderTrait<T, false> { | |
| 95 public: | |
| 96 static HeapObjectHeader* heapObjectHeader(T* obj) | |
| 97 { | |
|
haraken
2015/11/16 02:47:50
Can you add:
ASSERT(!ThreadState::current()->is
peria
2015/11/16 05:33:26
We did the same discussion in #16
https://coderevi
| |
| 98 return HeapObjectHeader::fromPayload(obj); | |
|
haraken
2015/11/16 02:47:49
Can you add:
ASSERT(header->checkHeader());
fo
peria
2015/11/16 05:33:26
It is called in HeapObjectHeader::fromPayload().
| |
| 99 } | |
| 100 static uint32_t gcGeneration(T* obj) | |
| 101 { | |
| 102 return heapObjectHeader(obj)->gcGeneration(); | |
| 103 } | |
| 104 }; | |
| 105 | |
| 72 class PLATFORM_EXPORT Heap { | 106 class PLATFORM_EXPORT Heap { |
| 73 public: | 107 public: |
| 74 static void init(); | 108 static void init(); |
| 75 static void shutdown(); | 109 static void shutdown(); |
| 76 static void doShutdown(); | 110 static void doShutdown(); |
| 77 | 111 |
| 78 #if ENABLE(ASSERT) | 112 #if ENABLE(ASSERT) |
| 79 static BasePage* findPageFromAddress(Address); | 113 static BasePage* findPageFromAddress(Address); |
| 80 static BasePage* findPageFromAddress(const void* pointer) { return findPageF romAddress(reinterpret_cast<Address>(const_cast<void*>(pointer))); } | 114 static BasePage* findPageFromAddress(const void* pointer) { return findPageF romAddress(reinterpret_cast<Address>(const_cast<void*>(pointer))); } |
| 81 #endif | 115 #endif |
| 82 | 116 |
| 83 template<typename T> | 117 template<typename T> |
| 84 static inline bool isHeapObjectAlive(T* object) | 118 static inline bool isHeapObjectAlive(T* object) |
| 85 { | 119 { |
| 86 static_assert(sizeof(T), "T must be fully defined"); | 120 static_assert(sizeof(T), "T must be fully defined"); |
| 87 // The strongification of collections relies on the fact that once a | 121 // The strongification of collections relies on the fact that once a |
| 88 // collection has been strongified, there is no way that it can contain | 122 // collection has been strongified, there is no way that it can contain |
| 89 // non-live entries, so no entries will be removed. Since you can't set | 123 // non-live entries, so no entries will be removed. Since you can't set |
| 90 // the mark bit on a null pointer, that means that null pointers are | 124 // the mark bit on a null pointer, that means that null pointers are |
| 91 // always 'alive'. | 125 // always 'alive'. |
| 92 if (!object) | 126 if (!object) |
| 93 return true; | 127 return true; |
| 94 return ObjectAliveTrait<T>::isHeapObjectAlive(object); | 128 return ObjectAliveTrait<T>::isHeapObjectAlive(object); |
| 95 } | 129 } |
| 96 template<typename T> | 130 template<typename T> |
| 97 static inline bool isHeapObjectAlive(const Member<T>& member) | 131 static inline bool isHeapObjectAlive(const Member<T>& member) |
| 98 { | 132 { |
| 99 return isHeapObjectAlive(member.get()); | 133 return isHeapObjectAlive(member.unsafeGet()); |
| 100 } | 134 } |
| 101 template<typename T> | 135 template<typename T> |
| 102 static inline bool isHeapObjectAlive(const WeakMember<T>& member) | 136 static inline bool isHeapObjectAlive(const WeakMember<T>& member) |
| 103 { | 137 { |
| 104 return isHeapObjectAlive(member.get()); | 138 return isHeapObjectAlive(member.unsafeGet()); |
| 105 } | 139 } |
| 106 template<typename T> | 140 template<typename T> |
| 107 static inline bool isHeapObjectAlive(const UntracedMember<T>& member) | 141 static inline bool isHeapObjectAlive(const UntracedMember<T>& member) |
| 108 { | 142 { |
| 109 return isHeapObjectAlive(member.get()); | 143 return isHeapObjectAlive(member.unsafeGet()); |
| 110 } | 144 } |
| 111 template<typename T> | 145 template<typename T> |
| 112 static inline bool isHeapObjectAlive(const RawPtr<T>& ptr) | 146 static inline bool isHeapObjectAlive(const RawPtr<T>& ptr) |
| 113 { | 147 { |
| 114 return isHeapObjectAlive(ptr.get()); | 148 return isHeapObjectAlive(ptr.get()); |
| 115 } | 149 } |
| 116 | 150 |
| 117 // Is the finalizable GC object still alive, but slated for lazy sweeping? | 151 // Is the finalizable GC object still alive, but slated for lazy sweeping? |
| 118 // If a lazy sweep is in progress, returns true if the object was found | 152 // If a lazy sweep is in progress, returns true if the object was found |
| 119 // to be not reachable during the marking phase, but it has yet to be swept | 153 // to be not reachable during the marking phase, but it has yet to be swept |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 252 static size_t wrapperCount() { return acquireLoad(&s_wrapperCount); } | 286 static size_t wrapperCount() { return acquireLoad(&s_wrapperCount); } |
| 253 static size_t wrapperCountAtLastGC() { return acquireLoad(&s_wrapperCountAtL astGC); } | 287 static size_t wrapperCountAtLastGC() { return acquireLoad(&s_wrapperCountAtL astGC); } |
| 254 static void increaseCollectedWrapperCount(size_t delta) { atomicAdd(&s_colle ctedWrapperCount, static_cast<long>(delta)); } | 288 static void increaseCollectedWrapperCount(size_t delta) { atomicAdd(&s_colle ctedWrapperCount, static_cast<long>(delta)); } |
| 255 static size_t collectedWrapperCount() { return acquireLoad(&s_collectedWrapp erCount); } | 289 static size_t collectedWrapperCount() { return acquireLoad(&s_collectedWrapp erCount); } |
| 256 static size_t partitionAllocSizeAtLastGC() { return acquireLoad(&s_partition AllocSizeAtLastGC); } | 290 static size_t partitionAllocSizeAtLastGC() { return acquireLoad(&s_partition AllocSizeAtLastGC); } |
| 257 | 291 |
| 258 static double estimatedMarkingTime(); | 292 static double estimatedMarkingTime(); |
| 259 static void reportMemoryUsageHistogram(); | 293 static void reportMemoryUsageHistogram(); |
| 260 static void reportMemoryUsageForTracing(); | 294 static void reportMemoryUsageForTracing(); |
| 261 | 295 |
| 262 #if ENABLE(ASSERT) | 296 static uint32_t gcGeneration() { return s_gcGeneration; } |
| 263 static uint16_t gcGeneration() { return s_gcGeneration; } | |
| 264 #endif | |
| 265 | 297 |
| 266 private: | 298 private: |
| 267 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted | 299 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted |
| 268 // by base addresses. | 300 // by base addresses. |
| 269 class RegionTree { | 301 class RegionTree { |
| 270 public: | 302 public: |
| 271 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (nullptr), m_right(nullptr) { } | 303 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (nullptr), m_right(nullptr) { } |
| 272 ~RegionTree() | 304 ~RegionTree() |
| 273 { | 305 { |
| 274 delete m_left; | 306 delete m_left; |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 301 static size_t s_allocatedSpace; | 333 static size_t s_allocatedSpace; |
| 302 static size_t s_allocatedObjectSize; | 334 static size_t s_allocatedObjectSize; |
| 303 static size_t s_objectSizeAtLastGC; | 335 static size_t s_objectSizeAtLastGC; |
| 304 static size_t s_markedObjectSize; | 336 static size_t s_markedObjectSize; |
| 305 static size_t s_markedObjectSizeAtLastCompleteSweep; | 337 static size_t s_markedObjectSizeAtLastCompleteSweep; |
| 306 static size_t s_wrapperCount; | 338 static size_t s_wrapperCount; |
| 307 static size_t s_wrapperCountAtLastGC; | 339 static size_t s_wrapperCountAtLastGC; |
| 308 static size_t s_collectedWrapperCount; | 340 static size_t s_collectedWrapperCount; |
| 309 static size_t s_partitionAllocSizeAtLastGC; | 341 static size_t s_partitionAllocSizeAtLastGC; |
| 310 static double s_estimatedMarkingTimePerByte; | 342 static double s_estimatedMarkingTimePerByte; |
| 311 #if ENABLE(ASSERT) | 343 static uint32_t s_gcGeneration; |
| 312 static uint16_t s_gcGeneration; | |
| 313 #endif | |
| 314 | 344 |
| 315 friend class ThreadState; | 345 friend class ThreadState; |
| 316 }; | 346 }; |
| 317 | 347 |
| 318 template<typename T> | 348 template<typename T> |
| 319 struct IsEagerlyFinalizedType { | 349 struct IsEagerlyFinalizedType { |
| 320 private: | 350 private: |
| 321 typedef char YesType; | 351 typedef char YesType; |
| 322 struct NoType { | 352 struct NoType { |
| 323 char padding[8]; | 353 char padding[8]; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 448 #define EAGERLY_FINALIZE_WILL_BE_REMOVED() EAGERLY_FINALIZE() | 478 #define EAGERLY_FINALIZE_WILL_BE_REMOVED() EAGERLY_FINALIZE() |
| 449 #else | 479 #else |
| 450 #define EAGERLY_FINALIZE_WILL_BE_REMOVED() | 480 #define EAGERLY_FINALIZE_WILL_BE_REMOVED() |
| 451 #endif | 481 #endif |
| 452 | 482 |
| 453 inline Address Heap::allocateOnHeapIndex(ThreadState* state, size_t size, int he apIndex, size_t gcInfoIndex) | 483 inline Address Heap::allocateOnHeapIndex(ThreadState* state, size_t size, int he apIndex, size_t gcInfoIndex) |
| 454 { | 484 { |
| 455 ASSERT(state->isAllocationAllowed()); | 485 ASSERT(state->isAllocationAllowed()); |
| 456 ASSERT(heapIndex != BlinkGC::LargeObjectHeapIndex); | 486 ASSERT(heapIndex != BlinkGC::LargeObjectHeapIndex); |
| 457 NormalPageHeap* heap = static_cast<NormalPageHeap*>(state->heap(heapIndex)); | 487 NormalPageHeap* heap = static_cast<NormalPageHeap*>(state->heap(heapIndex)); |
| 458 return heap->allocateObject(allocationSizeFromSize(size), gcInfoIndex); | 488 return heap->allocateObject(allocationSizeFromSize(size), gcInfoIndex, gcGen eration()); |
| 459 } | 489 } |
| 460 | 490 |
| 461 template<typename T> | 491 template<typename T> |
| 462 Address Heap::allocate(size_t size, bool eagerlySweep) | 492 Address Heap::allocate(size_t size, bool eagerlySweep) |
| 463 { | 493 { |
| 464 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); | 494 ThreadState* state = ThreadStateFor<ThreadingTrait<T>::Affinity>::state(); |
| 465 return Heap::allocateOnHeapIndex(state, size, eagerlySweep ? BlinkGC::EagerS weepHeapIndex : Heap::heapIndexForObjectSize(size), GCInfoTrait<T>::index()); | 495 return Heap::allocateOnHeapIndex(state, size, eagerlySweep ? BlinkGC::EagerS weepHeapIndex : Heap::heapIndexForObjectSize(size), GCInfoTrait<T>::index()); |
| 466 } | 496 } |
| 467 | 497 |
| 468 template<typename T> | 498 template<typename T> |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 503 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) | 533 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) |
| 504 { | 534 { |
| 505 T** cell = reinterpret_cast<T**>(object); | 535 T** cell = reinterpret_cast<T**>(object); |
| 506 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) | 536 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) |
| 507 *cell = nullptr; | 537 *cell = nullptr; |
| 508 } | 538 } |
| 509 | 539 |
| 510 } // namespace blink | 540 } // namespace blink |
| 511 | 541 |
| 512 #endif // Heap_h | 542 #endif // Heap_h |
| OLD | NEW |