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 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
178 | 178 |
179 virtual void checkAndMarkPointer(Visitor*, Address) override; | 179 virtual void checkAndMarkPointer(Visitor*, Address) override; |
180 virtual bool isLargeObject() override { return true; } | 180 virtual bool isLargeObject() override { return true; } |
181 | 181 |
182 #if ENABLE(GC_PROFILE_MARKING) | 182 #if ENABLE(GC_PROFILE_MARKING) |
183 virtual const GCInfo* findGCInfo(Address address) | 183 virtual const GCInfo* findGCInfo(Address address) |
184 { | 184 { |
185 if (!objectContains(address)) | 185 if (!objectContains(address)) |
186 return nullptr; | 186 return nullptr; |
187 return gcInfo(); | 187 return gcInfo(); |
188 } | 188 h |
189 #endif | 189 #endif |
190 | 190 |
191 #if ENABLE(GC_PROFILE_HEAP) | 191 #if ENABLE(GC_PROFILE_HEAP) |
192 void snapshot(TracedValue*, ThreadState::SnapshotInfo*); | 192 void snapshot(TracedValue*, ThreadState::SnapshotInfo*); |
193 #endif | 193 #endif |
194 | 194 |
195 void link(LargeObject<Header>** previousNext) | 195 void link(LargeObject<Header>** previousNext) |
196 { | 196 { |
197 m_next = *previousNext; | 197 m_next = *previousNext; |
198 *previousNext = this; | 198 *previousNext = this; |
(...skipping 1227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1426 return ThreadState::current()->isAllocationAllowed(); | 1426 return ThreadState::current()->isAllocationAllowed(); |
1427 } | 1427 } |
1428 | 1428 |
1429 static void markUsingGCInfo(Visitor* visitor, const void* buffer) | 1429 static void markUsingGCInfo(Visitor* visitor, const void* buffer) |
1430 { | 1430 { |
1431 visitor->mark(buffer, GeneralHeapObjectHeader::fromPayload(buffer)->trac
eCallback()); | 1431 visitor->mark(buffer, GeneralHeapObjectHeader::fromPayload(buffer)->trac
eCallback()); |
1432 } | 1432 } |
1433 | 1433 |
1434 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo
Tracing(t); } | 1434 static void markNoTracing(Visitor* visitor, const void* t) { visitor->markNo
Tracing(t); } |
1435 | 1435 |
1436 template<typename T, typename Traits> | 1436 template<typename T, typename Traits, typename VisitorDispatcher> |
1437 static void trace(Visitor* visitor, T& t) | 1437 static void trace(VisitorDispatcher visitor, T& t) |
1438 { | 1438 { |
1439 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
weakHandlingFlag, WTF::WeakPointersActWeak, T, Traits>::trace(visitor, t); | 1439 CollectionBackingTraceTrait<WTF::ShouldBeTraced<Traits>::value, Traits::
weakHandlingFlag, WTF::WeakPointersActWeak, T, Traits>::trace(visitor, t); |
1440 } | 1440 } |
1441 | 1441 |
1442 static void registerDelayedMarkNoTracing(Visitor* visitor, const void* objec
t) | 1442 static void registerDelayedMarkNoTracing(Visitor* visitor, const void* objec
t) |
1443 { | 1443 { |
1444 visitor->registerDelayedMarkNoTracing(object); | 1444 visitor->registerDelayedMarkNoTracing(object); |
1445 } | 1445 } |
1446 | 1446 |
1447 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) | 1447 static void registerWeakMembers(Visitor* visitor, const void* closure, const
void* object, WeakPointerCallback callback) |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2000 namespace WTF { | 2000 namespace WTF { |
2001 | 2001 |
2002 // Catch-all for types that have a way to trace that don't have special | 2002 // Catch-all for types that have a way to trace that don't have special |
2003 // handling for weakness in collections. This means that if this type | 2003 // handling for weakness in collections. This means that if this type |
2004 // contains WeakMember fields, they will simply be zeroed, but the entry | 2004 // contains WeakMember fields, they will simply be zeroed, but the entry |
2005 // will not be removed from the collection. This always happens for | 2005 // will not be removed from the collection. This always happens for |
2006 // things in vectors, which don't currently support special handling of | 2006 // things in vectors, which don't currently support special handling of |
2007 // weak elements. | 2007 // weak elements. |
2008 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2008 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
2009 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits>
{ | 2009 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, T, Traits>
{ |
2010 static bool trace(blink::Visitor* visitor, T& t) | 2010 template<typename VisitorDispatcher> |
| 2011 static bool trace(VisitorDispatcher visitor, T& t) |
2011 { | 2012 { |
2012 blink::TraceTrait<T>::trace(visitor, &t); | 2013 blink::TraceTrait<T>::trace(visitor, &t); |
2013 return false; | 2014 return false; |
2014 } | 2015 } |
2015 }; | 2016 }; |
2016 | 2017 |
2017 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2018 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
2018 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Mem
ber<T>, Traits> { | 2019 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Mem
ber<T>, Traits> { |
2019 static bool trace(blink::Visitor* visitor, blink::Member<T>& t) | 2020 template<typename VisitorDispatcher> |
| 2021 static bool trace(VisitorDispatcher visitor, blink::Member<T>& t) |
2020 { | 2022 { |
2021 blink::TraceTrait<T>::mark(visitor, const_cast<typename RemoveConst<T>::
Type*>(t.get())); | 2023 blink::TraceTrait<T>::mark(visitor, const_cast<typename RemoveConst<T>::
Type*>(t.get())); |
2022 return false; | 2024 return false; |
2023 } | 2025 } |
2024 }; | 2026 }; |
2025 | 2027 |
2026 // Catch-all for things that have HashTrait support for tracing with weakness. | 2028 // Catch-all for things that have HashTrait support for tracing with weakness. |
2027 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2029 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
2028 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> { | 2030 struct TraceInCollectionTrait<WeakHandlingInCollections, strongify, T, Traits> { |
2029 static bool trace(blink::Visitor* visitor, T& t) | 2031 static bool trace(blink::Visitor* visitor, T& t) |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2194 | 2196 |
2195 namespace blink { | 2197 namespace blink { |
2196 | 2198 |
2197 // CollectionBackingTraceTrait. Do nothing for things in collections that don't | 2199 // CollectionBackingTraceTrait. Do nothing for things in collections that don't |
2198 // need tracing, or call TraceInCollectionTrait for those that do. | 2200 // need tracing, or call TraceInCollectionTrait for those that do. |
2199 | 2201 |
2200 // Specialization for things that don't need marking and have no weak pointers. | 2202 // Specialization for things that don't need marking and have no weak pointers. |
2201 // We do nothing, even if WTF::WeakPointersActStrong. | 2203 // We do nothing, even if WTF::WeakPointersActStrong. |
2202 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> | 2204 template<WTF::ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename
Traits> |
2203 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { | 2205 struct CollectionBackingTraceTrait<false, WTF::NoWeakHandlingInCollections, stro
ngify, T, Traits> { |
2204 static bool trace(Visitor*, T&) { return false; } | 2206 template<typename VisitorDispatcher> static bool trace(VisitorDispatcher, T&
) { return false; } |
2205 }; | 2207 }; |
2206 | 2208 |
2207 template<typename T> | 2209 template<typename T> |
2208 static void verifyGarbageCollectedIfMember(T*) | 2210 static void verifyGarbageCollectedIfMember(T*) |
2209 { | 2211 { |
2210 } | 2212 } |
2211 | 2213 |
2212 template<typename T> | 2214 template<typename T> |
2213 static void verifyGarbageCollectedIfMember(Member<T>* t) | 2215 static void verifyGarbageCollectedIfMember(Member<T>* t) |
2214 { | 2216 { |
2215 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember); | 2217 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember); |
2216 } | 2218 } |
2217 | 2219 |
2218 // Specialization for things that either need marking or have weak pointers or | 2220 // Specialization for things that either need marking or have weak pointers or |
2219 // both. | 2221 // both. |
2220 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> | 2222 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> |
2221 struct CollectionBackingTraceTrait { | 2223 struct CollectionBackingTraceTrait { |
2222 static bool trace(Visitor* visitor, T&t) | 2224 template<typename VisitorDispatcher> static bool trace(VisitorDispatcher vis
itor, T& t) |
2223 { | 2225 { |
2224 verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); | 2226 verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); |
2225 return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Trait
s>::trace(visitor, t); | 2227 return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Trait
s>::trace(visitor, t); |
2226 } | 2228 } |
2227 }; | 2229 }; |
2228 | 2230 |
2229 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { | 2231 template<typename T> struct WeakHandlingHashTraits : WTF::SimpleClassHashTraits<
T> { |
2230 // We want to treat the object as a weak object in the sense that it can | 2232 // We want to treat the object as a weak object in the sense that it can |
2231 // disappear from hash sets and hash maps. | 2233 // disappear from hash sets and hash maps. |
2232 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; | 2234 static const WTF::WeakHandlingFlag weakHandlingFlag = WTF::WeakHandlingInCol
lections; |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2327 struct GCInfoTrait<HeapLinkedHashSet<T, U, V>> : public GCInfoTrait<LinkedHashSe
t<T, U, V, HeapAllocator>> { }; | 2329 struct GCInfoTrait<HeapLinkedHashSet<T, U, V>> : public GCInfoTrait<LinkedHashSe
t<T, U, V, HeapAllocator>> { }; |
2328 template<typename T, size_t inlineCapacity, typename U> | 2330 template<typename T, size_t inlineCapacity, typename U> |
2329 struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U>> : public GCInfoTrait<L
istHashSet<T, inlineCapacity, U, HeapListHashSetAllocator<T, inlineCapacity>> >
{ }; | 2331 struct GCInfoTrait<HeapListHashSet<T, inlineCapacity, U>> : public GCInfoTrait<L
istHashSet<T, inlineCapacity, U, HeapListHashSetAllocator<T, inlineCapacity>> >
{ }; |
2330 template<typename T, size_t inlineCapacity> | 2332 template<typename T, size_t inlineCapacity> |
2331 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; | 2333 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; |
2332 template<typename T, size_t inlineCapacity> | 2334 template<typename T, size_t inlineCapacity> |
2333 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; | 2335 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; |
2334 template<typename T, typename U, typename V> | 2336 template<typename T, typename U, typename V> |
2335 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; | 2337 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; |
2336 | 2338 |
| 2339 NO_SANITIZE_ADDRESS inline |
| 2340 bool HeapObjectHeader::isMarked() const |
| 2341 { |
| 2342 checkHeader(); |
| 2343 return m_size & markBitMask; |
| 2344 } |
| 2345 |
| 2346 NO_SANITIZE_ADDRESS inline |
| 2347 void HeapObjectHeader::mark() |
| 2348 { |
| 2349 checkHeader(); |
| 2350 ASSERT(!isMarked()); |
| 2351 m_size = m_size | markBitMask; |
| 2352 } |
| 2353 |
| 2354 ALWAYS_INLINE bool InlinedGlobalMarkingVisitor::isMarked(const void* objectPoint
er) |
| 2355 { |
| 2356 return GeneralHeapObjectHeader::fromPayload(objectPointer)->isMarked(); |
| 2357 } |
| 2358 |
| 2359 ALWAYS_INLINE void InlinedGlobalMarkingVisitor::visitHeader(HeapObjectHeader* he
ader, const void* objectPointer, TraceCallback callback) |
| 2360 { |
| 2361 ASSERT(header); |
| 2362 ASSERT(objectPointer); |
| 2363 // Check that we are not marking objects that are outside |
| 2364 // the heap by calling Heap::contains. However we cannot |
| 2365 // call Heap::contains when outside a GC and we call mark |
| 2366 // when doing weakness for ephemerons. Hence we only check |
| 2367 // when called within. |
| 2368 ASSERT(!ThreadState::current()->isInGC() || Heap::containedInHeapOrOrphanedP
age(header)); |
| 2369 |
| 2370 // If you hit this ASSERT, it means that there is a dangling pointer |
| 2371 // from a live thread heap to a dead thread heap. We must eliminate |
| 2372 // the dangling pointer. |
| 2373 // Release builds don't have the ASSERT, but it is OK because |
| 2374 // release builds will crash in the following header->isMarked() |
| 2375 // because all the entries of the orphaned heaps are zapped. |
| 2376 ASSERT(!pageFromObject(objectPointer)->orphaned()); |
| 2377 |
| 2378 if (header->isMarked()) |
| 2379 return; |
| 2380 header->mark(); |
| 2381 |
| 2382 #if ENABLE(GC_PROFILE_MARKING) |
| 2383 QUACK! |
| 2384 #endif |
| 2385 if (callback) |
| 2386 m_visitor->pushTraceCallback(const_cast<void*>(objectPointer), callback)
; |
| 2387 } |
| 2388 |
| 2389 ALWAYS_INLINE void InlinedGlobalMarkingVisitor::mark(const void* objectPointer,
TraceCallback callback) |
| 2390 { |
| 2391 if (!objectPointer) |
| 2392 return; |
| 2393 GeneralHeapObjectHeader* header = GeneralHeapObjectHeader::fromPayload(objec
tPointer); |
| 2394 visitHeader(header, header->payload(), callback); |
| 2395 } |
| 2396 |
| 2397 ALWAYS_INLINE bool InlinedGlobalMarkingVisitor::ensureMarked(const void* objectP
ointer) |
| 2398 { |
| 2399 if (!objectPointer) |
| 2400 return false; |
| 2401 #if ENABLE(ASSERT) |
| 2402 if (isMarked(objectPointer)) |
| 2403 return false; |
| 2404 |
| 2405 markNoTracing(objectPointer); |
| 2406 #else |
| 2407 // Inline what the above markNoTracing() call expands to, |
| 2408 // so as to make sure that we do get all the benefits. |
| 2409 GeneralHeapObjectHeader* header = |
| 2410 GeneralHeapObjectHeader::fromPayload(objectPointer); |
| 2411 if (header->isMarked()) |
| 2412 return false; |
| 2413 header->mark(); |
| 2414 #endif |
| 2415 return true; |
| 2416 } |
| 2417 |
2337 } // namespace blink | 2418 } // namespace blink |
2338 | 2419 |
2339 #endif // Heap_h | 2420 #endif // Heap_h |
OLD | NEW |