| Index: Source/heap/Heap.cpp
|
| diff --git a/Source/heap/Heap.cpp b/Source/heap/Heap.cpp
|
| index 1b777efdfb525f8c0cca8337cf41b9db682ad3f5..5d0ca2d0118eda448e200689337e27111a1e1335 100644
|
| --- a/Source/heap/Heap.cpp
|
| +++ b/Source/heap/Heap.cpp
|
| @@ -471,29 +471,29 @@ bool LargeHeapObject<Header>::isMarked()
|
| }
|
|
|
| template<typename Header>
|
| -bool LargeHeapObject<Header>::checkAndVisitPointer(Visitor* visitor, Address address)
|
| +bool LargeHeapObject<Header>::checkAndMarkPointer(Visitor* visitor, Address address)
|
| {
|
| if (contains(address)) {
|
| #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING
|
| visitor->setHostInfo(&address, "stack");
|
| #endif
|
| - visit(visitor);
|
| + mark(visitor);
|
| return true;
|
| }
|
| return false;
|
| }
|
|
|
| template<>
|
| -void LargeHeapObject<FinalizedHeapObjectHeader>::visit(Visitor* visitor)
|
| +void LargeHeapObject<FinalizedHeapObjectHeader>::mark(Visitor* visitor)
|
| {
|
| - visitor->visit(heapObjectHeader(), heapObjectHeader()->traceCallback());
|
| + visitor->mark(heapObjectHeader(), heapObjectHeader()->traceCallback());
|
| }
|
|
|
| template<>
|
| -void LargeHeapObject<HeapObjectHeader>::visit(Visitor* visitor)
|
| +void LargeHeapObject<HeapObjectHeader>::mark(Visitor* visitor)
|
| {
|
| ASSERT(gcInfo());
|
| - visitor->visit(heapObjectHeader(), gcInfo()->m_trace);
|
| + visitor->mark(heapObjectHeader(), gcInfo()->m_trace);
|
| }
|
|
|
| template<>
|
| @@ -605,13 +605,13 @@ bool Heap::contains(Address address)
|
| return false;
|
| }
|
|
|
| -Address Heap::checkAndVisitPointer(Visitor* visitor, Address address)
|
| +Address Heap::checkAndMarkPointer(Visitor* visitor, Address address)
|
| {
|
| ASSERT(ThreadState::isAnyThreadInGC());
|
| ThreadState::AttachedThreadStateSet& threads = ThreadState::attachedThreads();
|
| for (ThreadState::AttachedThreadStateSet::iterator it = threads.begin(), end = threads.end(); it != end; ++it) {
|
| - if ((*it)->checkAndVisitPointer(visitor, address)) {
|
| - // Pointer found and visited
|
| + if ((*it)->checkAndMarkPointer(visitor, address)) {
|
| + // Pointer found and marked.
|
| return address;
|
| }
|
| }
|
| @@ -639,10 +639,10 @@ BaseHeapPage* ThreadHeap<Header>::largeHeapObjectFromAddress(Address address)
|
| }
|
|
|
| template<typename Header>
|
| -bool ThreadHeap<Header>::checkAndVisitLargeHeapObjects(Visitor* visitor, Address address)
|
| +bool ThreadHeap<Header>::checkAndMarkLargeHeapObjects(Visitor* visitor, Address address)
|
| {
|
| for (LargeHeapObject<Header>* current = m_firstLargeHeapObject; current; current = current->next()) {
|
| - if (current->checkAndVisitPointer(visitor, address))
|
| + if (current->checkAndMarkPointer(visitor, address))
|
| return true;
|
| }
|
| return false;
|
| @@ -880,157 +880,6 @@ void Heap::getStats(HeapStats* stats)
|
| }
|
| }
|
|
|
| -#ifndef NDEBUG
|
| -// #define ENABLE_TRACE_CHECKER
|
| -#endif
|
| -
|
| -#ifdef ENABLE_TRACE_CHECKER
|
| -class TraceChecker {
|
| -public:
|
| - TraceChecker(void* object, TraceCallback callback, TraceRequirement requirement)
|
| - : m_object(object)
|
| - , m_callback(callback)
|
| - , m_traceRequirement(requirement)
|
| - , m_previous(s_current)
|
| - {
|
| - s_current = this;
|
| - // Unmark the object pointed to by each intra-heap pointer we find by
|
| - // conservative scanning.
|
| - iteratePointers(clearMarksAction);
|
| - }
|
| -
|
| - ~TraceChecker()
|
| - {
|
| - // Check the marks on the objects pointed to by each intra-heap pointer
|
| - // we find by conservative scanning.
|
| - if (m_traceRequirement == AllPointersMustBeVisited)
|
| - iteratePointers(checkDebugMarksAction);
|
| - else if (m_traceRequirement == AllPointersMustBeMarked)
|
| - iteratePointers(checkMarkedAction);
|
| - s_current = m_previous;
|
| - }
|
| -
|
| - static void rememberedToVisit(HeapObjectHeader* header)
|
| - {
|
| - header->setDebugMark();
|
| - }
|
| -
|
| - static void registerWeakPointers()
|
| - {
|
| - s_current->m_traceRequirement = NoRequirement;
|
| - }
|
| -
|
| - static void init()
|
| - {
|
| - s_current = 0;
|
| - }
|
| -
|
| -private:
|
| - typedef void (*IntraHeapPointerAction)(TraceChecker* self, Address);
|
| -
|
| - // Find the intra-heap pointers by scanning the allocated object
|
| - // conservatively.
|
| - void iteratePointers(IntraHeapPointerAction action)
|
| - {
|
| - HeapObjectHeader* header = HeapObjectHeader::fromPayload(m_object);
|
| - Address* start = reinterpret_cast<Address*>(m_object);
|
| - Address* limit = reinterpret_cast<Address*>(header->payloadEnd());
|
| -
|
| - for (Address* p = start; p < limit; p++) {
|
| - Address address = *p;
|
| - Address* castAddress = reinterpret_cast<Address*>(address);
|
| - // Find out whether the pointer looks like a pointer to another
|
| - // object on the heap. We ignore pointers within the object itself.
|
| - // We assume that things that are not object aligned are not
|
| - // actually pointers.
|
| - if ((castAddress < start || castAddress >= limit)
|
| - && Heap::contains(address) && isObjectAligned(address))
|
| - action(this, address);
|
| - }
|
| - }
|
| -
|
| - static void clearMarksAction(TraceChecker* self, Address address)
|
| - {
|
| - HeapObjectHeader* header = HeapObjectHeader::fromPayload(address);
|
| - // Unmark the object (if it was already marked) so that we can check
|
| - // the mark after the trace method to see if it has been marked again.
|
| - header->clearDebugMark();
|
| - }
|
| -
|
| - static void checkDebugMarksAction(TraceChecker* self, Address address)
|
| - {
|
| - HeapObjectHeader* header = HeapObjectHeader::fromPayload(address);
|
| - if (!header->hasDebugMark()) {
|
| - self->reportMishandledPointer(
|
| - address,
|
| - "Failure to visit all intra-heap pointers in trace method");
|
| - }
|
| - }
|
| -
|
| - static void checkMarkedAction(TraceChecker* self, Address address)
|
| - {
|
| - HeapObjectHeader* header = HeapObjectHeader::fromPayload(address);
|
| - if (!header->isMarked()) {
|
| - self->reportMishandledPointer(
|
| - address,
|
| - "Failure to visit all strong pointers or clear all weak pointers to dead objects");
|
| - }
|
| - }
|
| -
|
| -
|
| - void reportMishandledPointer(Address unvisitedAddress, const char* reason)
|
| - {
|
| - // Getting an assert in this method means either the trace method
|
| - // failed to visit a strong pointer, or the weak pointer callback failed
|
| - // to clear a weak pointer to an object that is dead.
|
| - class YouForgotToVisitAllPointersVisitor : public Visitor {
|
| - public:
|
| - virtual void visit(const void* objectPointer, TraceCallback callback)
|
| - {
|
| - ASSERT_NOT_REACHED(); // See comment below.
|
| - }
|
| - };
|
| -
|
| - YouForgotToVisitAllPointersVisitor youForgotToVisitAllPointersVisitor;
|
| - // If the callback calls the visitor at least once it will assert, and
|
| - // we can catch the assert in the debugger with the offending callback
|
| - // on the stack, and the object that was insufficiently visited/cleared
|
| - // as its argument. In this frame, 'address' will tell you the pointer
|
| - // that was in the object, but which was not visited.
|
| - m_callback(&youForgotToVisitAllPointersVisitor, m_object);
|
| - // If we get here the callback did not even visit one pointer. Cause an
|
| - // assert here, and in the debugger you can get the address of the
|
| - // offending callback from the this->m_callback variable, and the
|
| - // unvisited/uncleared pointer from the 'address' argument. The object that
|
| - // contained the unvisited pointer is in this->m_object.
|
| - ASSERT_NOT_REACHED();
|
| - }
|
| -
|
| - static bool isObjectAligned(Address address)
|
| - {
|
| - return !(reinterpret_cast<uintptr_t>(address) & allocationMask);
|
| - }
|
| -
|
| - void* m_object;
|
| - TraceCallback m_callback;
|
| - TraceRequirement m_traceRequirement;
|
| - TraceChecker* m_previous;
|
| - static TraceChecker* s_current;
|
| -};
|
| -
|
| -TraceChecker* TraceChecker::s_current;
|
| -
|
| -#else // !ENABLE_TRACE_CHECKER
|
| -
|
| -class TraceChecker {
|
| -public:
|
| - TraceChecker(void*, TraceCallback, TraceRequirement) { }
|
| - static void rememberedToVisit(const HeapObjectHeader*) { }
|
| - static void init() { }
|
| - static void registerWeakPointers() { }
|
| -};
|
| -#endif // ENABLE_TRACE_CHECKER
|
| -
|
| #if TRACE_GC_USING_CLASSOF
|
| static const char* classOf(const void* object)
|
| {
|
| @@ -1058,7 +907,6 @@ public:
|
| {
|
| ASSERT(header);
|
| ASSERT(objectPointer);
|
| - TraceChecker::rememberedToVisit(header);
|
| if (header->isMarked())
|
| return;
|
| header->mark();
|
| @@ -1071,21 +919,21 @@ public:
|
| Heap::pushTraceCallback(const_cast<void*>(objectPointer), callback);
|
| }
|
|
|
| - virtual void visit(HeapObjectHeader* header, TraceCallback callback)
|
| + virtual void mark(HeapObjectHeader* header, TraceCallback callback)
|
| {
|
| // We need both the HeapObjectHeader and FinalizedHeapObjectHeader version to
|
| // correctly find the payload.
|
| visitHeader(header, header->payload(), callback);
|
| }
|
|
|
| - virtual void visit(FinalizedHeapObjectHeader* header, TraceCallback callback)
|
| + virtual void mark(FinalizedHeapObjectHeader* header, TraceCallback callback)
|
| {
|
| // We need both the HeapObjectHeader and FinalizedHeapObjectHeader version to
|
| // correctly find the payload.
|
| visitHeader(header, header->payload(), callback);
|
| }
|
|
|
| - virtual void visit(const void* objectPointer, TraceCallback callback)
|
| + virtual void mark(const void* objectPointer, TraceCallback callback)
|
| {
|
| if (!objectPointer)
|
| return;
|
| @@ -1095,7 +943,6 @@ public:
|
|
|
| virtual void registerWeakPointers(const void* containingObject, WeakPointerCallback callback)
|
| {
|
| - TraceChecker::registerWeakPointers();
|
| Heap::pushWeakCallback(const_cast<void*>(containingObject), callback);
|
| }
|
|
|
| @@ -1106,7 +953,7 @@ public:
|
|
|
| // Macro to help defining the necessary visitor methods for typed heaps
|
| #define DEFINE_VISITOR_METHODS(Type) \
|
| - virtual void visit(const Type* objectPointer, TraceCallback callback) \
|
| + virtual void mark(const Type* objectPointer, TraceCallback callback) \
|
| { \
|
| if (!objectPointer) \
|
| return; \
|
| @@ -1280,7 +1127,7 @@ static int numberOfLeadingZeroes(uint8_t byte)
|
| }
|
|
|
| template<typename Header>
|
| -bool HeapPage<Header>::checkAndVisitPointer(Visitor* visitor, Address addr)
|
| +bool HeapPage<Header>::checkAndMarkPointer(Visitor* visitor, Address addr)
|
| {
|
| if (addr < payload())
|
| return false;
|
| @@ -1307,7 +1154,7 @@ bool HeapPage<Header>::checkAndVisitPointer(Visitor* visitor, Address addr)
|
| #if defined(TRACE_GC_MARKING) && TRACE_GC_MARKING
|
| visitor->setHostInfo(&addr, "stack");
|
| #endif
|
| - visitor->visit(header, traceCallback(header));
|
| + visitor->mark(header, traceCallback(header));
|
| return true;
|
| }
|
|
|
| @@ -1407,7 +1254,7 @@ static void markingTrampoline(VisitorCallback callback, Visitor* visitor, void*
|
|
|
| bool Heap::popAndTraceMarkingStack(Visitor* visitor)
|
| {
|
| - return s_markingStack->popAndTrace(&s_markingStack, visitor, AllPointersMustBeVisited, markingTrampoline);
|
| + return s_markingStack->popAndTrace(&s_markingStack, visitor, markingTrampoline);
|
| }
|
|
|
| static void weakTrampoline(VisitorCallback callback, Visitor* visitor, void* p)
|
| @@ -1417,7 +1264,7 @@ static void weakTrampoline(VisitorCallback callback, Visitor* visitor, void* p)
|
|
|
| bool Heap::popAndCallbackWeakPointer(Visitor* visitor)
|
| {
|
| - return s_weakCallbackStack->popAndTrace(&s_weakCallbackStack, visitor, AllPointersMustBeMarked, weakTrampoline);
|
| + return s_weakCallbackStack->popAndTrace(&s_weakCallbackStack, visitor, weakTrampoline);
|
| }
|
|
|
| class GCScope {
|
| @@ -1539,7 +1386,7 @@ void Heap::collectGarbage(ThreadState::StackState stackState, CollectionType col
|
| // objects.
|
| while (popAndCallbackWeakPointer(&marker)) { }
|
| }
|
| - // It is not permitted to visit pointers of live objects in the weak
|
| + // It is not permitted to trace pointers of live objects in the weak
|
| // callback phase, so the marking stack should still be empty here.
|
| s_markingStack->assertIsEmpty();
|
| }
|
| @@ -1560,7 +1407,6 @@ void Heap::pushWeakCallback(void* object, WeakPointerCallback callback)
|
| bool CallbackStack::popAndTrace(
|
| CallbackStack** first,
|
| Visitor* visitor,
|
| - TraceRequirement requirement,
|
| TraceTrampoline trampoline)
|
| {
|
| if (m_current == &(m_buffer[0])) {
|
| @@ -1573,10 +1419,9 @@ bool CallbackStack::popAndTrace(
|
| CallbackStack* nextStack = m_next;
|
| *first = nextStack;
|
| delete this;
|
| - return nextStack->popAndTrace(first, visitor, requirement, trampoline);
|
| + return nextStack->popAndTrace(first, visitor, trampoline);
|
| }
|
| Item* item = --m_current;
|
| - TraceChecker checker(item->object(), item->callback(), requirement);
|
| trampoline(item->callback(), visitor, item->object());
|
|
|
| return true;
|
|
|