Chromium Code Reviews| Index: Source/platform/heap/Heap.cpp |
| diff --git a/Source/platform/heap/Heap.cpp b/Source/platform/heap/Heap.cpp |
| index 5b702342bc246f69acd99c5af796ea64a2648cc7..86f046683fba9925a085b29444ba897744e23c57 100644 |
| --- a/Source/platform/heap/Heap.cpp |
| +++ b/Source/platform/heap/Heap.cpp |
| @@ -409,16 +409,15 @@ bool LargeHeapObject<Header>::isMarked() |
| } |
| template<typename Header> |
| -bool LargeHeapObject<Header>::checkAndMarkPointer(Visitor* visitor, Address address) |
| +void LargeHeapObject<Header>::checkAndMarkPointer(Visitor* visitor, Address address) |
| { |
| - if (contains(address)) { |
| + ASSERT(contains(address)); |
| + if (objectContains(address)) { |
| #if ENABLE(GC_TRACING) |
| visitor->setHostInfo(&address, "stack"); |
| #endif |
| mark(visitor); |
| - return true; |
| } |
| - return false; |
| } |
| template<> |
| @@ -541,13 +540,8 @@ BaseHeapPage* ThreadHeap<Header>::heapPageFromAddress(Address address) |
| if (page->contains(address)) |
| return page; |
| } |
| - return 0; |
| -} |
| - |
| -template<typename Header> |
| -BaseHeapPage* ThreadHeap<Header>::largeHeapObjectFromAddress(Address address) |
| -{ |
| for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; current = current->next()) { |
| + ASSERT(reinterpret_cast<Address>(current) == roundToBlinkPageStart(reinterpret_cast<Address>(current))); |
| if (current->contains(address)) |
| return current; |
| } |
| @@ -567,16 +561,6 @@ const GCInfo* ThreadHeap<Header>::findGCInfoOfLargeHeapObject(Address address) |
| #endif |
| template<typename Header> |
| -bool ThreadHeap<Header>::checkAndMarkLargeHeapObject(Visitor* visitor, Address address) |
| -{ |
| - for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; current = current->next()) { |
| - if (current->checkAndMarkPointer(visitor, address)) |
| - return true; |
| - } |
| - return false; |
| -} |
| - |
| -template<typename Header> |
| void ThreadHeap<Header>::addToFreeList(Address address, size_t size) |
| { |
| ASSERT(heapPageFromAddress(address)); |
| @@ -714,7 +698,7 @@ void ThreadHeap<Header>::addPageToPool(HeapPage<Header>* unused) |
| template<typename Header> |
| void ThreadHeap<Header>::allocatePage(const GCInfo* gcInfo) |
| { |
| - heapContainsCache()->flush(); |
| + Heap::flushNotInHeapCache(); |
| PageMemory* pageMemory = takePageFromPool(); |
| if (!pageMemory) { |
| pageMemory = PageMemory::allocate(blinkPagePayloadSize()); |
| @@ -1062,11 +1046,12 @@ Header* HeapPage<Header>::findHeaderFromAddress(Address address) |
| } |
| template<typename Header> |
| -bool HeapPage<Header>::checkAndMarkPointer(Visitor* visitor, Address address) |
| +void HeapPage<Header>::checkAndMarkPointer(Visitor* visitor, Address address) |
| { |
| + ASSERT(contains(address)); |
| Header* header = findHeaderFromAddress(address); |
| if (!header) |
| - return false; |
| + return; |
| #if ENABLE(GC_TRACING) |
| visitor->setHostInfo(&address, "stack"); |
| @@ -1075,7 +1060,6 @@ bool HeapPage<Header>::checkAndMarkPointer(Visitor* visitor, Address address) |
| visitor->markConservatively(header); |
| else |
| visitor->mark(header, traceCallback(header)); |
| - return true; |
| } |
| #if ENABLE(GC_TRACING) |
| @@ -1157,18 +1141,18 @@ void LargeHeapObject<Header>::getStats(HeapStats& stats) |
| stats.increaseObjectSpace(payloadSize()); |
| } |
| -HeapContainsCache::HeapContainsCache() |
| - : m_entries(adoptArrayPtr(new Entry[HeapContainsCache::numberOfEntries])) |
| +template<typename Entry> |
| +void HeapExtentCache<Entry>::flush() |
| { |
| + if (m_hasEntries) { |
| + for (int i = 0; i < numberOfEntries; i++) |
| + m_entries[i] = Entry(); |
| + m_hasEntries = false; |
| + } |
| } |
| -void HeapContainsCache::flush() |
| -{ |
| - for (int i = 0; i < numberOfEntries; i++) |
| - m_entries[i] = Entry(); |
| -} |
| - |
| -size_t HeapContainsCache::hash(Address address) |
| +template<typename Entry> |
| +size_t HeapExtentCache<Entry>::hash(Address address) |
| { |
| size_t value = (reinterpret_cast<size_t>(address) >> blinkPageSizeLog2); |
| value ^= value >> numberOfEntriesLog2; |
| @@ -1177,31 +1161,56 @@ size_t HeapContainsCache::hash(Address address) |
| return value & ~1; // Returns only even number. |
| } |
| -bool HeapContainsCache::lookup(Address address, BaseHeapPage** page) |
| +template<typename Entry> |
| +typename Entry::LookupResult HeapExtentCache<Entry>::lookup(Address address) |
| { |
| - ASSERT(page); |
| size_t index = hash(address); |
| ASSERT(!(index & 1)); |
| Address cachePage = roundToBlinkPageStart(address); |
| - if (m_entries[index].address() == cachePage) { |
| - *page = m_entries[index].containingPage(); |
| - return true; |
| - } |
| - if (m_entries[index + 1].address() == cachePage) { |
| - *page = m_entries[index + 1].containingPage(); |
| - return true; |
| - } |
| - *page = 0; |
| - return false; |
| + if (m_entries[index].address() == cachePage) |
| + return m_entries[index].result(); |
| + if (m_entries[index + 1].address() == cachePage) |
| + return m_entries[index + 1].result(); |
| + return 0; |
| } |
| -void HeapContainsCache::addEntry(Address address, BaseHeapPage* page) |
| +template<typename Entry> |
| +void HeapExtentCache<Entry>::addEntry(Address address, typename Entry::LookupResult entry) |
| { |
| + m_hasEntries = true; |
| size_t index = hash(address); |
| ASSERT(!(index & 1)); |
| Address cachePage = roundToBlinkPageStart(address); |
| m_entries[index + 1] = m_entries[index]; |
| - m_entries[index] = Entry(cachePage, page); |
| + m_entries[index] = Entry(cachePage, entry); |
| +} |
| + |
| +// These should not be needed, but it seems impossible to persuade clang to |
| +// instantiate the template functions and export them from a shared library, so |
| +// we add these in the non-templated subclass, which does not have that issue. |
| +void HeapContainsCache::addEntry(Address address, BaseHeapPage* page) |
| +{ |
| + HeapExtentCache<PositiveEntry>::addEntry(address, page); |
| +} |
| + |
| +BaseHeapPage* HeapContainsCache::lookup(Address address) |
| +{ |
| + return HeapExtentCache<PositiveEntry>::lookup(address); |
| +} |
| + |
| +bool Heap::notInHeap(Address address) |
| +{ |
| + return s_notInHeapCache->lookup(address); |
| +} |
| + |
| +void Heap::addressIsNotInHeap(Address address) |
| +{ |
| + s_notInHeapCache->addEntry(address, true); |
| +} |
| + |
| +void Heap::flushNotInHeapCache() |
| +{ |
| + s_notInHeapCache->flush(); |
| } |
| void CallbackStack::init(CallbackStack** first) |
| @@ -1475,6 +1484,7 @@ void Heap::init() |
| ThreadState::init(); |
| CallbackStack::init(&s_markingStack); |
| CallbackStack::init(&s_weakCallbackStack); |
| + s_notInHeapCache = new HeapDoesNotContainCache(); |
| s_markingVisitor = new MarkingVisitor(); |
| } |
| @@ -1494,6 +1504,8 @@ void Heap::doShutdown() |
| ASSERT(!ThreadState::attachedThreads().size()); |
| delete s_markingVisitor; |
| s_markingVisitor = 0; |
| + delete s_notInHeapCache; |
| + s_notInHeapCache = 0; |
| CallbackStack::shutdown(&s_weakCallbackStack); |
| CallbackStack::shutdown(&s_markingStack); |
| ThreadState::shutdown(); |
| @@ -1514,7 +1526,7 @@ BaseHeapPage* Heap::contains(Address address) |
| Address Heap::checkAndMarkPointer(Visitor* visitor, Address address) |
| { |
| ASSERT(ThreadState::isAnyThreadInGC()); |
| - if (!address) |
| + if (reinterpret_cast<uintptr_t>(address) < blinkPageSize) |
|
haraken
2014/05/08 05:44:58
What is this change for?
Mads Ager (chromium)
2014/05/08 06:52:37
This is an optimization to quickly filter out smal
Erik Corry
2014/05/08 09:26:08
You can't allocate at address 0, so no allocation
Erik Corry
2014/05/08 09:26:08
Removed instead.
|
| return 0; |
| ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads(); |
| @@ -1681,5 +1693,6 @@ template class ThreadHeap<HeapObjectHeader>; |
| Visitor* Heap::s_markingVisitor; |
| CallbackStack* Heap::s_markingStack; |
| CallbackStack* Heap::s_weakCallbackStack; |
| +HeapDoesNotContainCache* Heap::s_notInHeapCache; |
| bool Heap::s_shutdownCalled = false; |
| } |