| Index: src/heap/heap.cc
|
| diff --git a/src/heap/heap.cc b/src/heap/heap.cc
|
| index 4e84264762d0e3e2e471da1034e353ccdb44bbeb..1679c8d29254cbfaa6bd00850c074a344be6dbfe 100644
|
| --- a/src/heap/heap.cc
|
| +++ b/src/heap/heap.cc
|
| @@ -4,6 +4,9 @@
|
|
|
| #include "src/heap/heap.h"
|
|
|
| +#include <unordered_map>
|
| +#include <unordered_set>
|
| +
|
| #include "src/accessors.h"
|
| #include "src/api.h"
|
| #include "src/assembler-inl.h"
|
| @@ -6241,18 +6244,34 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
|
| }
|
|
|
| ~UnreachableObjectsFilter() {
|
| - heap_->mark_compact_collector()->ClearMarkbits();
|
| + for (auto it : reachable_) {
|
| + delete it.second;
|
| + it.second = nullptr;
|
| + }
|
| }
|
|
|
| bool SkipObject(HeapObject* object) {
|
| if (object->IsFiller()) return true;
|
| - return ObjectMarking::IsWhite(object, MarkingState::Internal(object));
|
| + MemoryChunk* chunk = MemoryChunk::FromAddress(object->address());
|
| + if (reachable_.count(chunk) == 0) return true;
|
| + return reachable_[chunk]->count(object) == 0;
|
| }
|
|
|
| private:
|
| + bool MarkAsReachable(HeapObject* object) {
|
| + MemoryChunk* chunk = MemoryChunk::FromAddress(object->address());
|
| + if (reachable_.count(chunk) == 0) {
|
| + reachable_[chunk] = new std::unordered_set<HeapObject*>();
|
| + }
|
| + if (reachable_[chunk]->count(object)) return false;
|
| + reachable_[chunk]->insert(object);
|
| + return true;
|
| + }
|
| +
|
| class MarkingVisitor : public ObjectVisitor, public RootVisitor {
|
| public:
|
| - MarkingVisitor() : marking_stack_(10) {}
|
| + explicit MarkingVisitor(UnreachableObjectsFilter* filter)
|
| + : filter_(filter), marking_stack_(10) {}
|
|
|
| void VisitPointers(HeapObject* host, Object** start,
|
| Object** end) override {
|
| @@ -6275,27 +6294,26 @@ class UnreachableObjectsFilter : public HeapObjectsFilter {
|
| for (Object** p = start; p < end; p++) {
|
| if (!(*p)->IsHeapObject()) continue;
|
| HeapObject* obj = HeapObject::cast(*p);
|
| - // Use Marking instead of ObjectMarking to avoid adjusting live bytes
|
| - // counter.
|
| - MarkBit mark_bit =
|
| - ObjectMarking::MarkBitFrom(obj, MarkingState::Internal(obj));
|
| - if (Marking::IsWhite(mark_bit)) {
|
| - Marking::WhiteToBlack(mark_bit);
|
| + if (filter_->MarkAsReachable(obj)) {
|
| marking_stack_.Add(obj);
|
| }
|
| }
|
| }
|
| + UnreachableObjectsFilter* filter_;
|
| List<HeapObject*> marking_stack_;
|
| };
|
|
|
| + friend class MarkingVisitor;
|
| +
|
| void MarkReachableObjects() {
|
| - MarkingVisitor visitor;
|
| + MarkingVisitor visitor(this);
|
| heap_->IterateRoots(&visitor, VISIT_ALL);
|
| visitor.TransitiveClosure();
|
| }
|
|
|
| Heap* heap_;
|
| DisallowHeapAllocation no_allocation_;
|
| + std::unordered_map<MemoryChunk*, std::unordered_set<HeapObject*>*> reachable_;
|
| };
|
|
|
| HeapIterator::HeapIterator(Heap* heap,
|
|
|