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 GarbageColl ectedMixinTrait; | |
75 | |
76 template<typename T> | |
77 class GarbageCollectedMixinTrait<T, true> { | |
haraken
2015/11/11 10:03:16
I'd rename this to HeapObjectHeaderTrait since thi
peria
2015/11/12 14:38:41
Done.
| |
78 public: | |
79 static HeapObjectHeader* heapObjectHeader(T* obj) | |
80 { | |
haraken
2015/11/11 10:03:16
Add ASSERT(!ThreadState::current()->isConstructing
peria
2015/11/12 14:38:42
This method may be called in Member<>::get(), and
haraken
2015/11/16 06:20:30
Isn't it unsafe? If obj->heapObjectHeader() is cal
peria
2015/11/16 07:04:42
If an object which is being constructed is an argu
| |
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 GarbageCollectedMixinTrait<T, false> { | |
95 public: | |
96 static HeapObjectHeader* heapObjectHeader(T* obj) | |
97 { | |
haraken
2015/11/11 10:03:16
Add ASSERT(!ThreadState::current()->isConstructing
peria
2015/11/12 14:38:42
ditto.
| |
98 return HeapObjectHeader::fromPayload(obj); | |
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 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 #if ENABLE(ASSERT) |
263 static uint16_t gcGeneration() { return s_gcGeneration; } | 297 static uint32_t gcGeneration() { return s_gcGeneration; } |
264 #endif | 298 #endif |
265 | 299 |
266 private: | 300 private: |
267 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted | 301 // A RegionTree is a simple binary search tree of PageMemoryRegions sorted |
268 // by base addresses. | 302 // by base addresses. |
269 class RegionTree { | 303 class RegionTree { |
270 public: | 304 public: |
271 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (nullptr), m_right(nullptr) { } | 305 explicit RegionTree(PageMemoryRegion* region) : m_region(region), m_left (nullptr), m_right(nullptr) { } |
272 ~RegionTree() | 306 ~RegionTree() |
273 { | 307 { |
(...skipping 28 matching lines...) Expand all Loading... | |
302 static size_t s_allocatedObjectSize; | 336 static size_t s_allocatedObjectSize; |
303 static size_t s_objectSizeAtLastGC; | 337 static size_t s_objectSizeAtLastGC; |
304 static size_t s_markedObjectSize; | 338 static size_t s_markedObjectSize; |
305 static size_t s_markedObjectSizeAtLastCompleteSweep; | 339 static size_t s_markedObjectSizeAtLastCompleteSweep; |
306 static size_t s_wrapperCount; | 340 static size_t s_wrapperCount; |
307 static size_t s_wrapperCountAtLastGC; | 341 static size_t s_wrapperCountAtLastGC; |
308 static size_t s_collectedWrapperCount; | 342 static size_t s_collectedWrapperCount; |
309 static size_t s_partitionAllocSizeAtLastGC; | 343 static size_t s_partitionAllocSizeAtLastGC; |
310 static double s_estimatedMarkingTimePerByte; | 344 static double s_estimatedMarkingTimePerByte; |
311 #if ENABLE(ASSERT) | 345 #if ENABLE(ASSERT) |
312 static uint16_t s_gcGeneration; | 346 static uint32_t s_gcGeneration; |
313 #endif | 347 #endif |
314 | 348 |
315 friend class ThreadState; | 349 friend class ThreadState; |
316 }; | 350 }; |
317 | 351 |
318 template<typename T> | 352 template<typename T> |
319 struct IsEagerlyFinalizedType { | 353 struct IsEagerlyFinalizedType { |
320 private: | 354 private: |
321 typedef char YesType; | 355 typedef char YesType; |
322 struct NoType { | 356 struct NoType { |
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
503 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) | 537 void VisitorHelper<Derived>::handleWeakCell(Visitor* self, void* object) |
504 { | 538 { |
505 T** cell = reinterpret_cast<T**>(object); | 539 T** cell = reinterpret_cast<T**>(object); |
506 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) | 540 if (*cell && !ObjectAliveTrait<T>::isHeapObjectAlive(*cell)) |
507 *cell = nullptr; | 541 *cell = nullptr; |
508 } | 542 } |
509 | 543 |
510 } // namespace blink | 544 } // namespace blink |
511 | 545 |
512 #endif // Heap_h | 546 #endif // Heap_h |
OLD | NEW |