| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 bool isHashTableDeletedValue() const { return first == reinterpret_cast<IntW
rapper*>(-1); } | 136 bool isHashTableDeletedValue() const { return first == reinterpret_cast<IntW
rapper*>(-1); } |
| 137 | 137 |
| 138 // Since we don't allocate independent objects of this type, we don't need | 138 // Since we don't allocate independent objects of this type, we don't need |
| 139 // a regular trace method. Instead, we use a traceInCollection method. If | 139 // a regular trace method. Instead, we use a traceInCollection method. If |
| 140 // the entry should be deleted from the collection we return true and don't | 140 // the entry should be deleted from the collection we return true and don't |
| 141 // trace the strong pointer. | 141 // trace the strong pointer. |
| 142 template<typename VisitorDispatcher> | 142 template<typename VisitorDispatcher> |
| 143 bool traceInCollection(VisitorDispatcher visitor, WTF::ShouldWeakPointersBeM
arkedStrongly strongify) | 143 bool traceInCollection(VisitorDispatcher visitor, WTF::ShouldWeakPointersBeM
arkedStrongly strongify) |
| 144 { | 144 { |
| 145 visitor->traceInCollection(second, strongify); | 145 visitor->traceInCollection(second, strongify); |
| 146 if (!visitor->isHeapObjectAlive(second)) | 146 if (!Heap::isHeapObjectAlive(second)) |
| 147 return true; | 147 return true; |
| 148 // FIXME: traceInCollection is also called from WeakProcessing to check
if the entry is dead. | 148 // FIXME: traceInCollection is also called from WeakProcessing to check
if the entry is dead. |
| 149 // The below if avoids calling trace in that case by only calling trace
when |first| is not yet marked. | 149 // The below if avoids calling trace in that case by only calling trace
when |first| is not yet marked. |
| 150 if (!visitor->isHeapObjectAlive(first)) | 150 if (!Heap::isHeapObjectAlive(first)) |
| 151 visitor->trace(first); | 151 visitor->trace(first); |
| 152 return false; | 152 return false; |
| 153 } | 153 } |
| 154 }; | 154 }; |
| 155 | 155 |
| 156 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { | 156 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { |
| 157 // We want to treat the object as a weak object in the sense that it can | 157 // We want to treat the object as a weak object in the sense that it can |
| 158 // disappear from hash sets and hash maps. | 158 // disappear from hash sets and hash maps. |
| 159 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 159 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
| 160 // Normally whether or not an object needs tracing is inferred | 160 // Normally whether or not an object needs tracing is inferred |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 289 virtual void registerDelayedMarkNoTracing(const void*) override { } | 289 virtual void registerDelayedMarkNoTracing(const void*) override { } |
| 290 virtual void registerWeakMembers(const void*, const void*, WeakCallback) ove
rride { } | 290 virtual void registerWeakMembers(const void*, const void*, WeakCallback) ove
rride { } |
| 291 virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCall
back) override { } | 291 virtual void registerWeakTable(const void*, EphemeronCallback, EphemeronCall
back) override { } |
| 292 #if ENABLE(ASSERT) | 292 #if ENABLE(ASSERT) |
| 293 virtual bool weakTableRegistered(const void*) override { return false; } | 293 virtual bool weakTableRegistered(const void*) override { return false; } |
| 294 #endif | 294 #endif |
| 295 virtual void registerWeakCellWithCallback(void**, WeakCallback) override { } | 295 virtual void registerWeakCellWithCallback(void**, WeakCallback) override { } |
| 296 #if ENABLE(GC_PROFILING) | 296 #if ENABLE(GC_PROFILING) |
| 297 virtual void recordObjectGraphEdge(const void*) override { } | 297 virtual void recordObjectGraphEdge(const void*) override { } |
| 298 #endif | 298 #endif |
| 299 virtual bool isMarked(const void*) override { return false; } | |
| 300 virtual bool ensureMarked(const void* objectPointer) override | 299 virtual bool ensureMarked(const void* objectPointer) override |
| 301 { | 300 { |
| 302 if (!objectPointer || isMarked(objectPointer)) | 301 if (!objectPointer || HeapObjectHeader::fromPayload(objectPointer)->isMa
rked()) |
| 303 return false; | 302 return false; |
| 304 markNoTracing(objectPointer); | 303 markNoTracing(objectPointer); |
| 305 return true; | 304 return true; |
| 306 } | 305 } |
| 307 | 306 |
| 308 size_t count() { return m_count; } | 307 size_t count() { return m_count; } |
| 309 void reset() { m_count = 0; } | 308 void reset() { m_count = 0; } |
| 310 | 309 |
| 311 private: | 310 private: |
| 312 StackFrameDepthScope m_scope; | 311 StackFrameDepthScope m_scope; |
| (...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 | 713 |
| 715 class ClassWithMember : public GarbageCollected<ClassWithMember> { | 714 class ClassWithMember : public GarbageCollected<ClassWithMember> { |
| 716 public: | 715 public: |
| 717 static ClassWithMember* create() | 716 static ClassWithMember* create() |
| 718 { | 717 { |
| 719 return new ClassWithMember(); | 718 return new ClassWithMember(); |
| 720 } | 719 } |
| 721 | 720 |
| 722 DEFINE_INLINE_TRACE() | 721 DEFINE_INLINE_TRACE() |
| 723 { | 722 { |
| 724 EXPECT_TRUE(visitor->isMarked(this)); | 723 EXPECT_TRUE(Heap::isHeapObjectAlive(this)); |
| 725 if (!traceCount()) | 724 if (!traceCount()) |
| 726 EXPECT_FALSE(visitor->isMarked(m_traceCounter)); | 725 EXPECT_FALSE(Heap::isHeapObjectAlive(m_traceCounter)); |
| 727 else | 726 else |
| 728 EXPECT_TRUE(visitor->isMarked(m_traceCounter)); | 727 EXPECT_TRUE(Heap::isHeapObjectAlive(m_traceCounter)); |
| 729 | 728 |
| 730 visitor->trace(m_traceCounter); | 729 visitor->trace(m_traceCounter); |
| 731 } | 730 } |
| 732 | 731 |
| 733 int traceCount() { return m_traceCounter->traceCount(); } | 732 int traceCount() { return m_traceCounter->traceCount(); } |
| 734 | 733 |
| 735 private: | 734 private: |
| 736 ClassWithMember() | 735 ClassWithMember() |
| 737 : m_traceCounter(TraceCounter::create()) | 736 : m_traceCounter(TraceCounter::create()) |
| 738 { } | 737 { } |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 } | 1091 } |
| 1093 | 1092 |
| 1094 DEFINE_INLINE_VIRTUAL_TRACE() | 1093 DEFINE_INLINE_VIRTUAL_TRACE() |
| 1095 { | 1094 { |
| 1096 visitor->trace(m_strongBar); | 1095 visitor->trace(m_strongBar); |
| 1097 visitor->template registerWeakMembers<Weak, &Weak::zapWeakMembers>(this)
; | 1096 visitor->template registerWeakMembers<Weak, &Weak::zapWeakMembers>(this)
; |
| 1098 } | 1097 } |
| 1099 | 1098 |
| 1100 void zapWeakMembers(Visitor* visitor) | 1099 void zapWeakMembers(Visitor* visitor) |
| 1101 { | 1100 { |
| 1102 if (!visitor->isHeapObjectAlive(m_weakBar)) | 1101 if (!Heap::isHeapObjectAlive(m_weakBar)) |
| 1103 m_weakBar = 0; | 1102 m_weakBar = 0; |
| 1104 } | 1103 } |
| 1105 | 1104 |
| 1106 bool strongIsThere() { return !!m_strongBar; } | 1105 bool strongIsThere() { return !!m_strongBar; } |
| 1107 bool weakIsThere() { return !!m_weakBar; } | 1106 bool weakIsThere() { return !!m_weakBar; } |
| 1108 | 1107 |
| 1109 private: | 1108 private: |
| 1110 Weak(Bar* strongBar, Bar* weakBar) | 1109 Weak(Bar* strongBar, Bar* weakBar) |
| 1111 : Bar() | 1110 : Bar() |
| 1112 , m_strongBar(strongBar) | 1111 , m_strongBar(strongBar) |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1211 static FinalizationObserver* create(T* data) { return new FinalizationObserv
er(data); } | 1210 static FinalizationObserver* create(T* data) { return new FinalizationObserv
er(data); } |
| 1212 bool didCallWillFinalize() const { return m_didCallWillFinalize; } | 1211 bool didCallWillFinalize() const { return m_didCallWillFinalize; } |
| 1213 | 1212 |
| 1214 DEFINE_INLINE_TRACE() | 1213 DEFINE_INLINE_TRACE() |
| 1215 { | 1214 { |
| 1216 visitor->template registerWeakMembers<FinalizationObserver<T>, &Finaliza
tionObserver<T>::zapWeakMembers>(this); | 1215 visitor->template registerWeakMembers<FinalizationObserver<T>, &Finaliza
tionObserver<T>::zapWeakMembers>(this); |
| 1217 } | 1216 } |
| 1218 | 1217 |
| 1219 void zapWeakMembers(Visitor* visitor) | 1218 void zapWeakMembers(Visitor* visitor) |
| 1220 { | 1219 { |
| 1221 if (m_data && !visitor->isHeapObjectAlive(m_data)) { | 1220 if (m_data && !Heap::isHeapObjectAlive(m_data)) { |
| 1222 m_data->willFinalize(); | 1221 m_data->willFinalize(); |
| 1223 m_data = nullptr; | 1222 m_data = nullptr; |
| 1224 m_didCallWillFinalize = true; | 1223 m_didCallWillFinalize = true; |
| 1225 } | 1224 } |
| 1226 } | 1225 } |
| 1227 | 1226 |
| 1228 private: | 1227 private: |
| 1229 FinalizationObserver(T* data) | 1228 FinalizationObserver(T* data) |
| 1230 : m_data(data) | 1229 : m_data(data) |
| 1231 , m_didCallWillFinalize(false) | 1230 , m_didCallWillFinalize(false) |
| (...skipping 3529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4761 | 4760 |
| 4762 // These special traits will remove a set from a map when the set is empty. | 4761 // These special traits will remove a set from a map when the set is empty. |
| 4763 struct EmptyClearingHashSetTraits : HashTraits<WeakSet> { | 4762 struct EmptyClearingHashSetTraits : HashTraits<WeakSet> { |
| 4764 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 4763 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
| 4765 template<typename VisitorDispatcher> | 4764 template<typename VisitorDispatcher> |
| 4766 static bool traceInCollection(VisitorDispatcher visitor, WeakSet& set, WTF::
ShouldWeakPointersBeMarkedStrongly strongify) | 4765 static bool traceInCollection(VisitorDispatcher visitor, WeakSet& set, WTF::
ShouldWeakPointersBeMarkedStrongly strongify) |
| 4767 { | 4766 { |
| 4768 bool liveEntriesFound = false; | 4767 bool liveEntriesFound = false; |
| 4769 WeakSet::iterator end = set.end(); | 4768 WeakSet::iterator end = set.end(); |
| 4770 for (WeakSet::iterator it = set.begin(); it != end; ++it) { | 4769 for (WeakSet::iterator it = set.begin(); it != end; ++it) { |
| 4771 if (visitor->isHeapObjectAlive(*it)) { | 4770 if (Heap::isHeapObjectAlive(*it)) { |
| 4772 liveEntriesFound = true; | 4771 liveEntriesFound = true; |
| 4773 break; | 4772 break; |
| 4774 } | 4773 } |
| 4775 } | 4774 } |
| 4776 // If there are live entries in the set then the set cannot be removed | 4775 // If there are live entries in the set then the set cannot be removed |
| 4777 // from the map it is contained in, and we need to mark it (and its | 4776 // from the map it is contained in, and we need to mark it (and its |
| 4778 // backing) live. We just trace normally, which will invoke the normal | 4777 // backing) live. We just trace normally, which will invoke the normal |
| 4779 // weak handling for any entries that are not live. | 4778 // weak handling for any entries that are not live. |
| 4780 if (liveEntriesFound) | 4779 if (liveEntriesFound) |
| 4781 set.trace(visitor); | 4780 set.trace(visitor); |
| (...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6111 { | 6110 { |
| 6112 Persistent<ClassWithMember> object = ClassWithMember::create(); | 6111 Persistent<ClassWithMember> object = ClassWithMember::create(); |
| 6113 EXPECT_EQ(0, object->traceCount()); | 6112 EXPECT_EQ(0, object->traceCount()); |
| 6114 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object.
get()); | 6113 TestMixinAllocatingObject* mixin = TestMixinAllocatingObject::create(object.
get()); |
| 6115 EXPECT_TRUE(mixin); | 6114 EXPECT_TRUE(mixin); |
| 6116 EXPECT_GT(object->traceCount(), 0); | 6115 EXPECT_GT(object->traceCount(), 0); |
| 6117 EXPECT_GT(mixin->traceCount(), 0); | 6116 EXPECT_GT(mixin->traceCount(), 0); |
| 6118 } | 6117 } |
| 6119 | 6118 |
| 6120 } // namespace blink | 6119 } // namespace blink |
| OLD | NEW |