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 162 matching lines...) Loading... |
173 explicit HeapObjectHeader(size_t encodedSize) | 173 explicit HeapObjectHeader(size_t encodedSize) |
174 : m_size(encodedSize) | 174 : m_size(encodedSize) |
175 #if ENABLE(ASSERT) | 175 #if ENABLE(ASSERT) |
176 , m_magic(magic) | 176 , m_magic(magic) |
177 #endif | 177 #endif |
178 { | 178 { |
179 // sizeof(HeapObjectHeader) must be equal to or smaller than | 179 // sizeof(HeapObjectHeader) must be equal to or smaller than |
180 // allocationGranurarity, because HeapObjectHeader is used as a header | 180 // allocationGranurarity, because HeapObjectHeader is used as a header |
181 // for an freed entry. Given that the smallest entry size is | 181 // for an freed entry. Given that the smallest entry size is |
182 // allocationGranurarity, HeapObjectHeader must fit into the size. | 182 // allocationGranurarity, HeapObjectHeader must fit into the size. |
183 COMPILE_ASSERT(sizeof(HeapObjectHeader) <= allocationGranularity, SizeOf
HeapObjectHeaderMustBeSmallerThanAllocationGranularity); | 183 static_assert(sizeof(HeapObjectHeader) <= allocationGranularity, "size o
f HeapObjectHeader must be smaller than allocationGranularity"); |
184 } | 184 } |
185 | 185 |
186 NO_SANITIZE_ADDRESS | 186 NO_SANITIZE_ADDRESS |
187 HeapObjectHeader(size_t encodedSize, const GCInfo*) | 187 HeapObjectHeader(size_t encodedSize, const GCInfo*) |
188 : m_size(encodedSize) | 188 : m_size(encodedSize) |
189 #if ENABLE(ASSERT) | 189 #if ENABLE(ASSERT) |
190 , m_magic(magic) | 190 , m_magic(magic) |
191 #endif | 191 #endif |
192 { | 192 { |
193 COMPILE_ASSERT(sizeof(HeapObjectHeader) <= allocationGranularity, SizeOf
HeapObjectHeaderMustBeSmallerThanAllocationGranularity); | 193 static_assert(sizeof(HeapObjectHeader) <= allocationGranularity, "size o
f HeapObjectHeader must be smaller than allocationGranularity"); |
194 } | 194 } |
195 | 195 |
196 static size_t freeListEncodedSize(size_t size) { return size | freeListMask;
} | 196 static size_t freeListEncodedSize(size_t size) { return size | freeListMask;
} |
197 | 197 |
198 NO_SANITIZE_ADDRESS | 198 NO_SANITIZE_ADDRESS |
199 bool isFree() { return m_size & freeListMask; } | 199 bool isFree() { return m_size & freeListMask; } |
200 NO_SANITIZE_ADDRESS | 200 NO_SANITIZE_ADDRESS |
201 bool isPromptlyFreed() { return (m_size & promptlyFreedMask) == promptlyFree
dMask; } | 201 bool isPromptlyFreed() { return (m_size & promptlyFreedMask) == promptlyFree
dMask; } |
202 NO_SANITIZE_ADDRESS | 202 NO_SANITIZE_ADDRESS |
203 void markPromptlyFreed() { m_size |= promptlyFreedMask; } | 203 void markPromptlyFreed() { m_size |= promptlyFreedMask; } |
(...skipping 330 matching lines...) Loading... |
534 // object. | 534 // object. |
535 // | 535 // |
536 // The layout of a large heap object is as follows: | 536 // The layout of a large heap object is as follows: |
537 // | 537 // |
538 // | BaseHeapPage | next pointer | GeneralHeapObjectHeader or HeapObjectHeader |
payload | | 538 // | BaseHeapPage | next pointer | GeneralHeapObjectHeader or HeapObjectHeader |
payload | |
539 template<typename Header> | 539 template<typename Header> |
540 class LargeObject final : public BaseHeapPage { | 540 class LargeObject final : public BaseHeapPage { |
541 public: | 541 public: |
542 LargeObject(PageMemory* storage, const GCInfo* gcInfo, ThreadState* state) :
BaseHeapPage(storage, gcInfo, state) | 542 LargeObject(PageMemory* storage, const GCInfo* gcInfo, ThreadState* state) :
BaseHeapPage(storage, gcInfo, state) |
543 { | 543 { |
544 COMPILE_ASSERT(!(sizeof(LargeObject<Header>) & allocationMask), large_he
ap_object_header_misaligned); | 544 static_assert(!(sizeof(LargeObject<Header>) & allocationMask), "LargeObj
ect<Header> misaligned"); |
545 } | 545 } |
546 | 546 |
547 virtual void checkAndMarkPointer(Visitor*, Address) override; | 547 virtual void checkAndMarkPointer(Visitor*, Address) override; |
548 virtual bool isLargeObject() override { return true; } | 548 virtual bool isLargeObject() override { return true; } |
549 | 549 |
550 #if ENABLE(GC_PROFILE_MARKING) | 550 #if ENABLE(GC_PROFILE_MARKING) |
551 virtual const GCInfo* findGCInfo(Address address) | 551 virtual const GCInfo* findGCInfo(Address address) |
552 { | 552 { |
553 if (!objectContains(address)) | 553 if (!objectContains(address)) |
554 return nullptr; | 554 return nullptr; |
(...skipping 1085 matching lines...) Loading... |
1640 void swap(AllocatorProvider& other) { } | 1640 void swap(AllocatorProvider& other) { } |
1641 }; | 1641 }; |
1642 | 1642 |
1643 void deallocate(void* dummy) { } | 1643 void deallocate(void* dummy) { } |
1644 | 1644 |
1645 // This is not a static method even though it could be, because it needs to | 1645 // This is not a static method even though it could be, because it needs to |
1646 // match the one that the (off-heap) ListHashSetAllocator has. The 'this' | 1646 // match the one that the (off-heap) ListHashSetAllocator has. The 'this' |
1647 // pointer will always be null. | 1647 // pointer will always be null. |
1648 void* allocateNode() | 1648 void* allocateNode() |
1649 { | 1649 { |
1650 COMPILE_ASSERT(!WTF::IsWeak<ValueArg>::value, WeakPointersInAListHashSet
WillJustResultInNullEntriesInTheSetThatsNotWhatYouWantConsiderUsingLinkedHashSet
Instead); | 1650 // Consider using a LinkedHashSet instead if this compile-time assert fa
ils: |
| 1651 static_assert(!WTF::IsWeak<ValueArg>::value, "weak pointers in a ListHas
hSet will result in null entries in the set"); |
| 1652 |
1651 return malloc<void*, Node>(sizeof(Node)); | 1653 return malloc<void*, Node>(sizeof(Node)); |
1652 } | 1654 } |
1653 | 1655 |
1654 static void traceValue(Visitor* visitor, Node* node) | 1656 static void traceValue(Visitor* visitor, Node* node) |
1655 { | 1657 { |
1656 traceListHashSetValue(visitor, node->m_value); | 1658 traceListHashSetValue(visitor, node->m_value); |
1657 } | 1659 } |
1658 }; | 1660 }; |
1659 | 1661 |
1660 // FIXME: These should just be template aliases: | 1662 // FIXME: These should just be template aliases: |
(...skipping 468 matching lines...) Loading... |
2129 // Vector backing that needs marking. We don't support weak members in vectors. | 2131 // Vector backing that needs marking. We don't support weak members in vectors. |
2130 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> | 2132 template<ShouldWeakPointersBeMarkedStrongly strongify, typename T, typename Trai
ts> |
2131 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pVectorBacking<T, Traits>, void> { | 2133 struct TraceInCollectionTrait<NoWeakHandlingInCollections, strongify, blink::Hea
pVectorBacking<T, Traits>, void> { |
2132 static bool trace(blink::Visitor* visitor, void* self) | 2134 static bool trace(blink::Visitor* visitor, void* self) |
2133 { | 2135 { |
2134 // The allocator can oversize the allocation a little, according to | 2136 // The allocator can oversize the allocation a little, according to |
2135 // the allocation granularity. The extra size is included in the | 2137 // the allocation granularity. The extra size is included in the |
2136 // payloadSize call below, since there is nowhere to store the | 2138 // payloadSize call below, since there is nowhere to store the |
2137 // originally allocated memory. This assert ensures that visiting the | 2139 // originally allocated memory. This assert ensures that visiting the |
2138 // last bit of memory can't cause trouble. | 2140 // last bit of memory can't cause trouble. |
2139 COMPILE_ASSERT(!ShouldBeTraced<Traits>::value || sizeof(T) > blink::allo
cationGranularity || Traits::canInitializeWithMemset, HeapOverallocationCanCause
SpuriousVisits); | 2141 static_assert(!ShouldBeTraced<Traits>::value || sizeof(T) > blink::alloc
ationGranularity || Traits::canInitializeWithMemset, "heap overallocation can ca
use spurious visits"); |
2140 | 2142 |
2141 T* array = reinterpret_cast<T*>(self); | 2143 T* array = reinterpret_cast<T*>(self); |
2142 blink::GeneralHeapObjectHeader* header = blink::GeneralHeapObjectHeader:
:fromPayload(self); | 2144 blink::GeneralHeapObjectHeader* header = blink::GeneralHeapObjectHeader:
:fromPayload(self); |
2143 // Use the payload size as recorded by the heap to determine how many | 2145 // Use the payload size as recorded by the heap to determine how many |
2144 // elements to mark. | 2146 // elements to mark. |
2145 size_t length = header->payloadSize() / sizeof(T); | 2147 size_t length = header->payloadSize() / sizeof(T); |
2146 for (size_t i = 0; i < length; ++i) | 2148 for (size_t i = 0; i < length; ++i) |
2147 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr
aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[
i]); | 2149 blink::CollectionBackingTraceTrait<ShouldBeTraced<Traits>::value, Tr
aits::weakHandlingFlag, WeakPointersActStrong, T, Traits>::trace(visitor, array[
i]); |
2148 return false; | 2150 return false; |
2149 } | 2151 } |
(...skipping 75 matching lines...) Loading... |
2225 // side is alive, which causes the strong pointer on the key side to be | 2227 // side is alive, which causes the strong pointer on the key side to be |
2226 // marked. If that then results in the object pointed to by the weak | 2228 // marked. If that then results in the object pointed to by the weak |
2227 // pointer on the value side being marked live, then the whole | 2229 // pointer on the value side being marked live, then the whole |
2228 // key-value entry is leaked. To avoid unexpected leaking, we disallow | 2230 // key-value entry is leaked. To avoid unexpected leaking, we disallow |
2229 // this case, but if you run into this assert, please reach out to Blink | 2231 // this case, but if you run into this assert, please reach out to Blink |
2230 // reviewers, and we may relax it. | 2232 // reviewers, and we may relax it. |
2231 const bool keyIsWeak = Traits::KeyTraits::weakHandlingFlag == WeakHandli
ngInCollections; | 2233 const bool keyIsWeak = Traits::KeyTraits::weakHandlingFlag == WeakHandli
ngInCollections; |
2232 const bool valueIsWeak = Traits::ValueTraits::weakHandlingFlag == WeakHa
ndlingInCollections; | 2234 const bool valueIsWeak = Traits::ValueTraits::weakHandlingFlag == WeakHa
ndlingInCollections; |
2233 const bool keyHasStrongRefs = ShouldBeTraced<typename Traits::KeyTraits>
::value; | 2235 const bool keyHasStrongRefs = ShouldBeTraced<typename Traits::KeyTraits>
::value; |
2234 const bool valueHasStrongRefs = ShouldBeTraced<typename Traits::ValueTra
its>::value; | 2236 const bool valueHasStrongRefs = ShouldBeTraced<typename Traits::ValueTra
its>::value; |
2235 COMPILE_ASSERT(!keyIsWeak || !valueIsWeak || !keyHasStrongRefs || !value
HasStrongRefs, ThisConfigurationWasDisallowedToAvoidUnexpectedLeaks); | 2237 static_assert(!keyIsWeak || !valueIsWeak || !keyHasStrongRefs || !valueH
asStrongRefs, "this configuration is disallowed to avoid unexpected leaks"); |
2236 if ((valueIsWeak && !keyIsWeak) || (valueIsWeak && keyIsWeak && !valueHa
sStrongRefs)) { | 2238 if ((valueIsWeak && !keyIsWeak) || (valueIsWeak && keyIsWeak && !valueHa
sStrongRefs)) { |
2237 // Check value first. | 2239 // Check value first. |
2238 bool deadWeakObjectsFoundOnValueSide = blink::CollectionBackingTrace
Trait<ShouldBeTraced<typename Traits::ValueTraits>::value, Traits::ValueTraits::
weakHandlingFlag, strongify, Value, typename Traits::ValueTraits>::trace(visitor
, self.value); | 2240 bool deadWeakObjectsFoundOnValueSide = blink::CollectionBackingTrace
Trait<ShouldBeTraced<typename Traits::ValueTraits>::value, Traits::ValueTraits::
weakHandlingFlag, strongify, Value, typename Traits::ValueTraits>::trace(visitor
, self.value); |
2239 if (deadWeakObjectsFoundOnValueSide) | 2241 if (deadWeakObjectsFoundOnValueSide) |
2240 return true; | 2242 return true; |
2241 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Tr
aits::KeyTraits>::value, Traits::KeyTraits::weakHandlingFlag, strongify, Key, ty
pename Traits::KeyTraits>::trace(visitor, self.key); | 2243 return blink::CollectionBackingTraceTrait<ShouldBeTraced<typename Tr
aits::KeyTraits>::value, Traits::KeyTraits::weakHandlingFlag, strongify, Key, ty
pename Traits::KeyTraits>::trace(visitor, self.key); |
2242 } | 2244 } |
2243 // Check key first. | 2245 // Check key first. |
2244 bool deadWeakObjectsFoundOnKeySide = blink::CollectionBackingTraceTrait<
ShouldBeTraced<typename Traits::KeyTraits>::value, Traits::KeyTraits::weakHandli
ngFlag, strongify, Key, typename Traits::KeyTraits>::trace(visitor, self.key); | 2246 bool deadWeakObjectsFoundOnKeySide = blink::CollectionBackingTraceTrait<
ShouldBeTraced<typename Traits::KeyTraits>::value, Traits::KeyTraits::weakHandli
ngFlag, strongify, Key, typename Traits::KeyTraits>::trace(visitor, self.key); |
2245 if (deadWeakObjectsFoundOnKeySide) | 2247 if (deadWeakObjectsFoundOnKeySide) |
(...skipping 53 matching lines...) Loading... |
2299 }; | 2301 }; |
2300 | 2302 |
2301 template<typename T> | 2303 template<typename T> |
2302 static void verifyGarbageCollectedIfMember(T*) | 2304 static void verifyGarbageCollectedIfMember(T*) |
2303 { | 2305 { |
2304 } | 2306 } |
2305 | 2307 |
2306 template<typename T> | 2308 template<typename T> |
2307 static void verifyGarbageCollectedIfMember(Member<T>* t) | 2309 static void verifyGarbageCollectedIfMember(Member<T>* t) |
2308 { | 2310 { |
2309 COMPILE_ASSERT_IS_GARBAGE_COLLECTED(T, NonGarbageCollectedObjectInMember); | 2311 STATIC_ASSERT_IS_GARBAGE_COLLECTED(T, "non garbage collected object in membe
r"); |
2310 } | 2312 } |
2311 | 2313 |
2312 // Specialization for things that either need marking or have weak pointers or | 2314 // Specialization for things that either need marking or have weak pointers or |
2313 // both. | 2315 // both. |
2314 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> | 2316 template<bool needsTracing, WTF::WeakHandlingFlag weakHandlingFlag, WTF::ShouldW
eakPointersBeMarkedStrongly strongify, typename T, typename Traits> |
2315 struct CollectionBackingTraceTrait { | 2317 struct CollectionBackingTraceTrait { |
2316 static bool trace(Visitor* visitor, T&t) | 2318 static bool trace(Visitor* visitor, T&t) |
2317 { | 2319 { |
2318 verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); | 2320 verifyGarbageCollectedIfMember(reinterpret_cast<T*>(0)); |
2319 return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Trait
s>::trace(visitor, t); | 2321 return WTF::TraceInCollectionTrait<weakHandlingFlag, strongify, T, Trait
s>::trace(visitor, t); |
(...skipping 24 matching lines...) Loading... |
2344 { | 2346 { |
2345 return t.traceInCollection(visitor, strongify); | 2347 return t.traceInCollection(visitor, strongify); |
2346 } | 2348 } |
2347 }; | 2349 }; |
2348 | 2350 |
2349 template<typename T, typename Traits> | 2351 template<typename T, typename Traits> |
2350 struct TraceTrait<HeapVectorBacking<T, Traits>> { | 2352 struct TraceTrait<HeapVectorBacking<T, Traits>> { |
2351 using Backing = HeapVectorBacking<T, Traits>; | 2353 using Backing = HeapVectorBacking<T, Traits>; |
2352 static void trace(Visitor* visitor, void* self) | 2354 static void trace(Visitor* visitor, void* self) |
2353 { | 2355 { |
2354 COMPILE_ASSERT(!WTF::IsWeak<T>::value, WeDontSupportWeaknessInHeapVector
sOrDeques); | 2356 static_assert(!WTF::IsWeak<T>::value, "weakness in HeapVectors and Deque
s are not supported"); |
2355 if (WTF::ShouldBeTraced<Traits>::value) | 2357 if (WTF::ShouldBeTraced<Traits>::value) |
2356 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); | 2358 WTF::TraceInCollectionTrait<WTF::NoWeakHandlingInCollections, WTF::W
eakPointersActWeak, HeapVectorBacking<T, Traits>, void>::trace(visitor, self); |
2357 } | 2359 } |
2358 static void mark(Visitor* visitor, const Backing* backing) | 2360 static void mark(Visitor* visitor, const Backing* backing) |
2359 { | 2361 { |
2360 visitor->mark(backing, &trace); | 2362 visitor->mark(backing, &trace); |
2361 } | 2363 } |
2362 static void checkGCInfo(Visitor* visitor, const Backing* backing) | 2364 static void checkGCInfo(Visitor* visitor, const Backing* backing) |
2363 { | 2365 { |
2364 #if ENABLE(ASSERT) | 2366 #if ENABLE(ASSERT) |
(...skipping 59 matching lines...) Loading... |
2424 template<typename T, size_t inlineCapacity> | 2426 template<typename T, size_t inlineCapacity> |
2425 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; | 2427 struct GCInfoTrait<HeapVector<T, inlineCapacity>> : public GCInfoTrait<Vector<T,
inlineCapacity, HeapAllocator>> { }; |
2426 template<typename T, size_t inlineCapacity> | 2428 template<typename T, size_t inlineCapacity> |
2427 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; | 2429 struct GCInfoTrait<HeapDeque<T, inlineCapacity>> : public GCInfoTrait<Deque<T, i
nlineCapacity, HeapAllocator>> { }; |
2428 template<typename T, typename U, typename V> | 2430 template<typename T, typename U, typename V> |
2429 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; | 2431 struct GCInfoTrait<HeapHashCountedSet<T, U, V>> : public GCInfoTrait<HashCounted
Set<T, U, V, HeapAllocator>> { }; |
2430 | 2432 |
2431 } // namespace blink | 2433 } // namespace blink |
2432 | 2434 |
2433 #endif // Heap_h | 2435 #endif // Heap_h |
OLD | NEW |