Don't intrusively mark in the heap snapshot generator

BUG=

Review URL: https://codereview.chromium.org/1476413002

Cr-Commit-Position: refs/heads/master@{#32369}
This commit is contained in:
verwaest 2015-11-27 04:05:27 -08:00 committed by Commit bot
parent 369778ec55
commit 1779136f5d
2 changed files with 40 additions and 36 deletions

View File

@ -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);
}
}

View File

@ -351,6 +351,8 @@ class V8HeapExplorer : public HeapEntriesAllocator {
typedef bool (V8HeapExplorer::*ExtractReferencesMethod)(int entry,
HeapObject* object);
void MarkVisitedField(HeapObject* obj, int offset);
HeapEntry* AddEntry(HeapObject* object);
HeapEntry* AddEntry(HeapObject* object,
HeapEntry::Type type,
@ -465,6 +467,8 @@ class V8HeapExplorer : public HeapEntriesAllocator {
HeapObjectsSet weak_containers_;
v8::HeapProfiler::ObjectNameResolver* global_object_name_resolver_;
std::vector<bool> marks_;
friend class IndexedReferencesExtractor;
friend class RootsReferencesExtractor;