| Index: src/profiler/heap-snapshot-generator.cc
|
| diff --git a/src/profiler/heap-snapshot-generator.cc b/src/profiler/heap-snapshot-generator.cc
|
| index 566ebe3820df70716ca72feb070e03d35cb7b250..322b164c5ea74be1c6b6a2c244df942be95c3ee4 100644
|
| --- a/src/profiler/heap-snapshot-generator.cc
|
| +++ b/src/profiler/heap-snapshot-generator.cc
|
| @@ -988,14 +988,14 @@ int V8HeapExplorer::EstimateObjectsCount(HeapIterator* iterator) {
|
|
|
| class IndexedReferencesExtractor : public ObjectVisitor {
|
| public:
|
| - IndexedReferencesExtractor(V8HeapExplorer* generator,
|
| - HeapObject* parent_obj,
|
| + IndexedReferencesExtractor(V8HeapExplorer* generator, HeapObject* parent_obj,
|
| int parent)
|
| : generator_(generator),
|
| parent_obj_(parent_obj),
|
| + parent_start_(HeapObject::RawField(parent_obj_, 0)),
|
| + parent_end_(HeapObject::RawField(parent_obj_, parent_obj_->Size())),
|
| parent_(parent),
|
| - next_index_(0) {
|
| - }
|
| + next_index_(0) {}
|
| void VisitCodeEntry(Address entry_address) override {
|
| Code* code = Code::cast(Code::GetObjectFromEntryAddress(entry_address));
|
| generator_->SetInternalReference(parent_obj_, parent_, "code", code);
|
| @@ -1003,40 +1003,24 @@ class IndexedReferencesExtractor : public ObjectVisitor {
|
| }
|
| void VisitPointers(Object** start, Object** end) override {
|
| for (Object** p = start; p < end; p++) {
|
| + intptr_t index =
|
| + static_cast<intptr_t>(p - HeapObject::RawField(parent_obj_, 0));
|
| ++next_index_;
|
| - if (CheckVisitedAndUnmark(p)) continue;
|
| + // |p| could be outside of the object, e.g., while visiting RelocInfo of
|
| + // code objects.
|
| + if (p >= parent_start_ && p < parent_end_ && generator_->marks_[index]) {
|
| + generator_->marks_[index] = false;
|
| + continue;
|
| + }
|
| generator_->SetHiddenReference(parent_obj_, parent_, next_index_, *p);
|
| }
|
| }
|
| - static void MarkVisitedField(HeapObject* obj, int offset) {
|
| - if (offset < 0) return;
|
| - Address field = obj->address() + offset;
|
| - DCHECK(Memory::Object_at(field)->IsHeapObject());
|
| - intptr_t p = reinterpret_cast<intptr_t>(Memory::Object_at(field));
|
| - DCHECK(!IsMarked(p));
|
| - intptr_t p_tagged = p | kTag;
|
| - Memory::Object_at(field) = reinterpret_cast<Object*>(p_tagged);
|
| - }
|
|
|
| private:
|
| - bool CheckVisitedAndUnmark(Object** field) {
|
| - intptr_t p = reinterpret_cast<intptr_t>(*field);
|
| - if (IsMarked(p)) {
|
| - intptr_t p_untagged = (p & ~kTaggingMask) | kHeapObjectTag;
|
| - *field = reinterpret_cast<Object*>(p_untagged);
|
| - DCHECK((*field)->IsHeapObject());
|
| - return true;
|
| - }
|
| - return false;
|
| - }
|
| -
|
| - static const intptr_t kTaggingMask = 3;
|
| - static const intptr_t kTag = 3;
|
| -
|
| - static bool IsMarked(intptr_t p) { return (p & kTaggingMask) == kTag; }
|
| -
|
| V8HeapExplorer* generator_;
|
| HeapObject* parent_obj_;
|
| + Object** parent_start_;
|
| + Object** parent_end_;
|
| int parent_;
|
| int next_index_;
|
| };
|
| @@ -1871,6 +1855,14 @@ bool V8HeapExplorer::IterateAndExtractSinglePass() {
|
| obj = iterator.next(), progress_->ProgressStep()) {
|
| if (interrupted) continue;
|
|
|
| + size_t max_pointer = obj->Size() / kPointerSize;
|
| + if (max_pointer > marks_.size()) {
|
| + // Clear the current bits.
|
| + std::vector<bool>().swap(marks_);
|
| + // Reallocate to right size.
|
| + marks_.resize(max_pointer, false);
|
| + }
|
| +
|
| HeapEntry* heap_entry = GetEntry(obj);
|
| int entry = heap_entry->index();
|
| if ((this->*extractor)(entry, obj)) {
|
| @@ -1915,11 +1907,19 @@ void V8HeapExplorer::SetContextReference(HeapObject* parent_obj,
|
| parent_entry,
|
| names_->GetName(reference_name),
|
| child_entry);
|
| - IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
| + MarkVisitedField(parent_obj, field_offset);
|
| }
|
| }
|
|
|
|
|
| +void V8HeapExplorer::MarkVisitedField(HeapObject* obj, int offset) {
|
| + if (offset < 0) return;
|
| + int index = offset / kPointerSize;
|
| + DCHECK(!marks_[index]);
|
| + marks_[index] = true;
|
| +}
|
| +
|
| +
|
| void V8HeapExplorer::SetNativeBindReference(HeapObject* parent_obj,
|
| int parent_entry,
|
| const char* reference_name,
|
| @@ -1964,7 +1964,7 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
|
| reference_name,
|
| child_entry);
|
| }
|
| - IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
| + MarkVisitedField(parent_obj, field_offset);
|
| }
|
|
|
|
|
| @@ -1982,7 +1982,7 @@ void V8HeapExplorer::SetInternalReference(HeapObject* parent_obj,
|
| names_->GetName(index),
|
| child_entry);
|
| }
|
| - IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
| + MarkVisitedField(parent_obj, field_offset);
|
| }
|
|
|
|
|
| @@ -2015,7 +2015,7 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
|
| reference_name,
|
| child_entry);
|
| }
|
| - IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
| + MarkVisitedField(parent_obj, field_offset);
|
| }
|
|
|
|
|
| @@ -2033,7 +2033,7 @@ void V8HeapExplorer::SetWeakReference(HeapObject* parent_obj,
|
| names_->GetFormatted("%d", index),
|
| child_entry);
|
| }
|
| - IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
| + MarkVisitedField(parent_obj, field_offset);
|
| }
|
|
|
|
|
| @@ -2074,7 +2074,7 @@ void V8HeapExplorer::SetPropertyReference(HeapObject* parent_obj,
|
| parent_entry,
|
| name,
|
| child_entry);
|
| - IndexedReferencesExtractor::MarkVisitedField(parent_obj, field_offset);
|
| + MarkVisitedField(parent_obj, field_offset);
|
| }
|
| }
|
|
|
|
|