Commit f4c15c4e authored by alexeif@chromium.org's avatar alexeif@chromium.org

External references should not affect dominance relation.

Separate objects into two groups: reachable from a window (user),
and unreachable (system). Then do not take into account links
that come from system group to the user group when calculating
dominance relation.

Review URL: https://chromiumcodereview.appspot.com/10086006

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11335 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9641607f
...@@ -5998,7 +5998,7 @@ Handle<Value> HeapGraphEdge::GetName() const { ...@@ -5998,7 +5998,7 @@ Handle<Value> HeapGraphEdge::GetName() const {
const HeapGraphNode* HeapGraphEdge::GetFromNode() const { const HeapGraphNode* HeapGraphEdge::GetFromNode() const {
i::Isolate* isolate = i::Isolate::Current(); i::Isolate* isolate = i::Isolate::Current();
IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode"); IsDeadCheck(isolate, "v8::HeapGraphEdge::GetFromNode");
const i::HeapEntry* from = ToInternal(this)->From(); const i::HeapEntry* from = ToInternal(this)->from();
return reinterpret_cast<const HeapGraphNode*>(from); return reinterpret_cast<const HeapGraphNode*>(from);
} }
......
...@@ -95,6 +95,12 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) { ...@@ -95,6 +95,12 @@ CodeEntry* ProfileGenerator::EntryForVMState(StateTag tag) {
} }
HeapEntry* HeapGraphEdge::from() const {
return const_cast<HeapEntry*>(
reinterpret_cast<const HeapEntry*>(this - child_index_) - 1);
}
SnapshotObjectId HeapObjectsMap::GetNthGcSubrootId(int delta) { SnapshotObjectId HeapObjectsMap::GetNthGcSubrootId(int delta) {
return kGcRootsFirstSubrootId + delta * kObjectIdStep; return kGcRootsFirstSubrootId + delta * kObjectIdStep;
} }
......
...@@ -957,11 +957,6 @@ void HeapGraphEdge::Init(int child_index, int index, HeapEntry* to) { ...@@ -957,11 +957,6 @@ void HeapGraphEdge::Init(int child_index, int index, HeapEntry* to) {
} }
HeapEntry* HeapGraphEdge::From() {
return reinterpret_cast<HeapEntry*>(this - child_index_) - 1;
}
void HeapEntry::Init(HeapSnapshot* snapshot, void HeapEntry::Init(HeapSnapshot* snapshot,
Type type, Type type,
const char* name, const char* name,
...@@ -972,6 +967,7 @@ void HeapEntry::Init(HeapSnapshot* snapshot, ...@@ -972,6 +967,7 @@ void HeapEntry::Init(HeapSnapshot* snapshot,
snapshot_ = snapshot; snapshot_ = snapshot;
type_ = type; type_ = type;
painted_ = false; painted_ = false;
reachable_from_window_ = false;
name_ = name; name_ = name;
self_size_ = self_size; self_size_ = self_size;
retained_size_ = 0; retained_size_ = 0;
...@@ -1991,7 +1987,7 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) { ...@@ -1991,7 +1987,7 @@ void V8HeapExplorer::ExtractReferences(HeapObject* obj) {
// We use JSGlobalProxy because this is what embedder (e.g. browser) // We use JSGlobalProxy because this is what embedder (e.g. browser)
// uses for the global object. // uses for the global object.
JSGlobalProxy* proxy = JSGlobalProxy::cast(obj); JSGlobalProxy* proxy = JSGlobalProxy::cast(obj);
SetRootShortcutReference(proxy->map()->prototype()); SetWindowReference(proxy->map()->prototype());
} else if (obj->IsJSObject()) { } else if (obj->IsJSObject()) {
JSObject* js_obj = JSObject::cast(obj); JSObject* js_obj = JSObject::cast(obj);
ExtractClosureReferences(js_obj, entry); ExtractClosureReferences(js_obj, entry);
...@@ -2259,15 +2255,15 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj, ...@@ -2259,15 +2255,15 @@ void V8HeapExplorer::ExtractPropertyReferences(JSObject* js_obj,
Object* k = dictionary->KeyAt(i); Object* k = dictionary->KeyAt(i);
if (dictionary->IsKey(k)) { if (dictionary->IsKey(k)) {
Object* target = dictionary->ValueAt(i); Object* target = dictionary->ValueAt(i);
SetPropertyReference(
js_obj, entry, String::cast(k), target);
// We assume that global objects can only have slow properties. // We assume that global objects can only have slow properties.
if (target->IsJSGlobalPropertyCell()) { Object* value = target->IsJSGlobalPropertyCell()
SetPropertyShortcutReference(js_obj, ? JSGlobalPropertyCell::cast(target)->value()
entry, : target;
String::cast(k), if (String::cast(k)->length() > 0) {
JSGlobalPropertyCell::cast( SetPropertyReference(js_obj, entry, String::cast(k), value);
target)->value()); } else {
TagObject(value, "(hidden properties)");
SetInternalReference(js_obj, entry, "hidden_properties", value);
} }
} }
} }
...@@ -2636,7 +2632,7 @@ void V8HeapExplorer::SetRootGcRootsReference() { ...@@ -2636,7 +2632,7 @@ void V8HeapExplorer::SetRootGcRootsReference() {
} }
void V8HeapExplorer::SetRootShortcutReference(Object* child_obj) { void V8HeapExplorer::SetWindowReference(Object* child_obj) {
HeapEntry* child_entry = GetEntry(child_obj); HeapEntry* child_entry = GetEntry(child_obj);
ASSERT(child_entry != NULL); ASSERT(child_entry != NULL);
filler_->SetNamedAutoIndexReference( filler_->SetNamedAutoIndexReference(
...@@ -2718,7 +2714,7 @@ void V8HeapExplorer::TagGlobalObjects() { ...@@ -2718,7 +2714,7 @@ void V8HeapExplorer::TagGlobalObjects() {
Handle<JSGlobalObject> global_obj = enumerator.at(i); Handle<JSGlobalObject> global_obj = enumerator.at(i);
Object* obj_document; Object* obj_document;
if (global_obj->GetProperty(*document_string)->ToObject(&obj_document) && if (global_obj->GetProperty(*document_string)->ToObject(&obj_document) &&
obj_document->IsJSObject()) { obj_document->IsJSObject()) {
JSObject* document = JSObject::cast(obj_document); JSObject* document = JSObject::cast(obj_document);
Object* obj_url; Object* obj_url;
if (document->GetProperty(*url_string)->ToObject(&obj_url) && if (document->GetProperty(*url_string)->ToObject(&obj_url) &&
...@@ -3272,19 +3268,61 @@ bool HeapSnapshotGenerator::FillReferences() { ...@@ -3272,19 +3268,61 @@ bool HeapSnapshotGenerator::FillReferences() {
} }
void HeapSnapshotGenerator::FillReversePostorderIndexes( bool HeapSnapshotGenerator::IsWindowReference(const HeapGraphEdge& edge) {
ASSERT(edge.from() == snapshot_->root());
return edge.type() == HeapGraphEdge::kShortcut;
}
void HeapSnapshotGenerator::MarkWindowReachableObjects() {
List<HeapEntry*> worklist;
Vector<HeapGraphEdge> children = snapshot_->root()->children();
for (int i = 0; i < children.length(); ++i) {
if (IsWindowReference(children[i])) {
worklist.Add(children[i].to());
}
}
while (!worklist.is_empty()) {
HeapEntry* entry = worklist.RemoveLast();
if (entry->reachable_from_window()) continue;
entry->set_reachable_from_window();
Vector<HeapGraphEdge> children = entry->children();
for (int i = 0; i < children.length(); ++i) {
HeapEntry* child = children[i].to();
if (!child->reachable_from_window()) {
worklist.Add(child);
}
}
}
}
static bool IsRetainingEdge(HeapGraphEdge* edge) {
if (edge->type() == HeapGraphEdge::kShortcut) return false;
// The edge is not retaining if it goes from system domain
// (i.e. an object not reachable from window) to the user domain
// (i.e. a reachable object).
return edge->from()->reachable_from_window()
|| !edge->to()->reachable_from_window();
}
void HeapSnapshotGenerator::FillPostorderIndexes(
Vector<HeapEntry*>* entries) { Vector<HeapEntry*>* entries) {
snapshot_->ClearPaint(); snapshot_->ClearPaint();
int current_entry = 0; int current_entry = 0;
List<HeapEntry*> nodes_to_visit; List<HeapEntry*> nodes_to_visit;
nodes_to_visit.Add(snapshot_->root()); HeapEntry* root = snapshot_->root();
nodes_to_visit.Add(root);
snapshot_->root()->paint(); snapshot_->root()->paint();
while (!nodes_to_visit.is_empty()) { while (!nodes_to_visit.is_empty()) {
HeapEntry* entry = nodes_to_visit.last(); HeapEntry* entry = nodes_to_visit.last();
Vector<HeapGraphEdge> children = entry->children(); Vector<HeapGraphEdge> children = entry->children();
bool has_new_edges = false; bool has_new_edges = false;
for (int i = 0; i < children.length(); ++i) { for (int i = 0; i < children.length(); ++i) {
if (children[i].type() == HeapGraphEdge::kShortcut) continue; if (entry != root && !IsRetainingEdge(&children[i])) continue;
HeapEntry* child = children[i].to(); HeapEntry* child = children[i].to();
if (!child->painted()) { if (!child->painted()) {
nodes_to_visit.Add(child); nodes_to_visit.Add(child);
...@@ -3319,6 +3357,7 @@ bool HeapSnapshotGenerator::BuildDominatorTree( ...@@ -3319,6 +3357,7 @@ bool HeapSnapshotGenerator::BuildDominatorTree(
const Vector<HeapEntry*>& entries, const Vector<HeapEntry*>& entries,
Vector<int>* dominators) { Vector<int>* dominators) {
if (entries.length() == 0) return true; if (entries.length() == 0) return true;
HeapEntry* root = snapshot_->root();
const int entries_length = entries.length(), root_index = entries_length - 1; const int entries_length = entries.length(), root_index = entries_length - 1;
static const int kNoDominator = -1; static const int kNoDominator = -1;
for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator; for (int i = 0; i < root_index; ++i) (*dominators)[i] = kNoDominator;
...@@ -3347,8 +3386,8 @@ bool HeapSnapshotGenerator::BuildDominatorTree( ...@@ -3347,8 +3386,8 @@ bool HeapSnapshotGenerator::BuildDominatorTree(
int new_idom_index = kNoDominator; int new_idom_index = kNoDominator;
Vector<HeapGraphEdge*> rets = entries[i]->retainers(); Vector<HeapGraphEdge*> rets = entries[i]->retainers();
for (int j = 0; j < rets.length(); ++j) { for (int j = 0; j < rets.length(); ++j) {
if (rets[j]->type() == HeapGraphEdge::kShortcut) continue; if (rets[j]->from() != root && !IsRetainingEdge(rets[j])) continue;
int ret_index = rets[j]->From()->ordered_index(); int ret_index = rets[j]->from()->ordered_index();
if (dominators->at(ret_index) != kNoDominator) { if (dominators->at(ret_index) != kNoDominator) {
new_idom_index = new_idom_index == kNoDominator new_idom_index = new_idom_index == kNoDominator
? ret_index ? ret_index
...@@ -3374,9 +3413,10 @@ bool HeapSnapshotGenerator::BuildDominatorTree( ...@@ -3374,9 +3413,10 @@ bool HeapSnapshotGenerator::BuildDominatorTree(
bool HeapSnapshotGenerator::SetEntriesDominators() { bool HeapSnapshotGenerator::SetEntriesDominators() {
// This array is used for maintaining reverse postorder of nodes. MarkWindowReachableObjects();
// This array is used for maintaining postorder of nodes.
ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length()); ScopedVector<HeapEntry*> ordered_entries(snapshot_->entries()->length());
FillReversePostorderIndexes(&ordered_entries); FillPostorderIndexes(&ordered_entries);
ScopedVector<int> dominators(ordered_entries.length()); ScopedVector<int> dominators(ordered_entries.length());
if (!BuildDominatorTree(ordered_entries, &dominators)) return false; if (!BuildDominatorTree(ordered_entries, &dominators)) return false;
for (int i = 0; i < ordered_entries.length(); ++i) { for (int i = 0; i < ordered_entries.length(); ++i) {
......
...@@ -464,21 +464,20 @@ class HeapGraphEdge BASE_EMBEDDED { ...@@ -464,21 +464,20 @@ class HeapGraphEdge BASE_EMBEDDED {
void Init(int child_index, Type type, int index, HeapEntry* to); void Init(int child_index, Type type, int index, HeapEntry* to);
void Init(int child_index, int index, HeapEntry* to); void Init(int child_index, int index, HeapEntry* to);
Type type() { return static_cast<Type>(type_); } Type type() const { return static_cast<Type>(type_); }
int index() { int index() const {
ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak); ASSERT(type_ == kElement || type_ == kHidden || type_ == kWeak);
return index_; return index_;
} }
const char* name() { const char* name() const {
ASSERT(type_ == kContextVariable ASSERT(type_ == kContextVariable
|| type_ == kProperty || type_ == kProperty
|| type_ == kInternal || type_ == kInternal
|| type_ == kShortcut); || type_ == kShortcut);
return name_; return name_;
} }
HeapEntry* to() { return to_; } HeapEntry* to() const { return to_; }
INLINE(HeapEntry* from() const);
HeapEntry* From();
private: private:
int child_index_ : 29; int child_index_ : 29;
...@@ -564,6 +563,8 @@ class HeapEntry BASE_EMBEDDED { ...@@ -564,6 +563,8 @@ class HeapEntry BASE_EMBEDDED {
void clear_paint() { painted_ = false; } void clear_paint() { painted_ = false; }
bool painted() { return painted_; } bool painted() { return painted_; }
void paint() { painted_ = true; } void paint() { painted_ = true; }
bool reachable_from_window() { return reachable_from_window_; }
void set_reachable_from_window() { reachable_from_window_ = true; }
void SetIndexedReference(HeapGraphEdge::Type type, void SetIndexedReference(HeapGraphEdge::Type type,
int child_index, int child_index,
...@@ -600,8 +601,9 @@ class HeapEntry BASE_EMBEDDED { ...@@ -600,8 +601,9 @@ class HeapEntry BASE_EMBEDDED {
const char* TypeAsString(); const char* TypeAsString();
unsigned painted_: 1; unsigned painted_: 1;
unsigned reachable_from_window_: 1;
unsigned type_: 4; unsigned type_: 4;
int children_count_: 27; int children_count_: 26;
int retainers_count_; int retainers_count_;
int self_size_; int self_size_;
union { union {
...@@ -1016,7 +1018,7 @@ class V8HeapExplorer : public HeapEntriesAllocator { ...@@ -1016,7 +1018,7 @@ class V8HeapExplorer : public HeapEntriesAllocator {
HeapEntry* parent, HeapEntry* parent,
String* reference_name, String* reference_name,
Object* child); Object* child);
void SetRootShortcutReference(Object* child); void SetWindowReference(Object* window);
void SetRootGcRootsReference(); void SetRootGcRootsReference();
void SetGcRootsReference(VisitorSynchronization::SyncTag tag); void SetGcRootsReference(VisitorSynchronization::SyncTag tag);
void SetGcSubrootReference( void SetGcSubrootReference(
...@@ -1120,7 +1122,9 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface { ...@@ -1120,7 +1122,9 @@ class HeapSnapshotGenerator : public SnapshottingProgressReportingInterface {
bool CalculateRetainedSizes(); bool CalculateRetainedSizes();
bool CountEntriesAndReferences(); bool CountEntriesAndReferences();
bool FillReferences(); bool FillReferences();
void FillReversePostorderIndexes(Vector<HeapEntry*>* entries); void FillPostorderIndexes(Vector<HeapEntry*>* entries);
bool IsWindowReference(const HeapGraphEdge& edge);
void MarkWindowReachableObjects();
void ProgressStep(); void ProgressStep();
bool ProgressReport(bool force = false); bool ProgressReport(bool force = false);
bool SetEntriesDominators(); bool SetEntriesDominators();
......
...@@ -109,13 +109,13 @@ TEST(HeapSnapshot) { ...@@ -109,13 +109,13 @@ TEST(HeapSnapshot) {
// Verify, that JS global object of env2 has '..2' properties. // Verify, that JS global object of env2 has '..2' properties.
const v8::HeapGraphNode* a2_node = const v8::HeapGraphNode* a2_node =
GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "a2"); GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "a2");
CHECK_NE(NULL, a2_node); CHECK_NE(NULL, a2_node);
CHECK_NE( CHECK_NE(
NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_1")); NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_1"));
CHECK_NE( CHECK_NE(
NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "b2_2")); NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "b2_2"));
CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kShortcut, "c2")); CHECK_NE(NULL, GetProperty(global_env2, v8::HeapGraphEdge::kProperty, "c2"));
// Paint all nodes reachable from global object. // Paint all nodes reachable from global object.
NamedEntriesDetector det; NamedEntriesDetector det;
...@@ -137,12 +137,13 @@ TEST(HeapSnapshotObjectSizes) { ...@@ -137,12 +137,13 @@ TEST(HeapSnapshotObjectSizes) {
CompileRun( CompileRun(
"function X(a, b) { this.a = a; this.b = b; }\n" "function X(a, b) { this.a = a; this.b = b; }\n"
"x = new X(new X(), new X());\n" "x = new X(new X(), new X());\n"
"dummy = new X();\n"
"(function() { x.a.a = x.b; })();"); "(function() { x.a.a = x.b; })();");
const v8::HeapSnapshot* snapshot = const v8::HeapSnapshot* snapshot =
v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); v8::HeapProfiler::TakeSnapshot(v8_str("sizes"));
const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
const v8::HeapGraphNode* x = const v8::HeapGraphNode* x =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "x"); GetProperty(global, v8::HeapGraphEdge::kProperty, "x");
CHECK_NE(NULL, x); CHECK_NE(NULL, x);
const v8::HeapGraphNode* x1 = const v8::HeapGraphNode* x1 =
GetProperty(x, v8::HeapGraphEdge::kProperty, "a"); GetProperty(x, v8::HeapGraphEdge::kProperty, "a");
...@@ -169,7 +170,7 @@ TEST(BoundFunctionInSnapshot) { ...@@ -169,7 +170,7 @@ TEST(BoundFunctionInSnapshot) {
v8::HeapProfiler::TakeSnapshot(v8_str("sizes")); v8::HeapProfiler::TakeSnapshot(v8_str("sizes"));
const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
const v8::HeapGraphNode* f = const v8::HeapGraphNode* f =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "boundFunction"); GetProperty(global, v8::HeapGraphEdge::kProperty, "boundFunction");
CHECK(f); CHECK(f);
CHECK_EQ(v8::String::New("native_bind"), f->GetName()); CHECK_EQ(v8::String::New("native_bind"), f->GetName());
const v8::HeapGraphNode* bindings = const v8::HeapGraphNode* bindings =
...@@ -233,15 +234,15 @@ TEST(HeapSnapshotCodeObjects) { ...@@ -233,15 +234,15 @@ TEST(HeapSnapshotCodeObjects) {
const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
const v8::HeapGraphNode* compiled = const v8::HeapGraphNode* compiled =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "compiled"); GetProperty(global, v8::HeapGraphEdge::kProperty, "compiled");
CHECK_NE(NULL, compiled); CHECK_NE(NULL, compiled);
CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType()); CHECK_EQ(v8::HeapGraphNode::kClosure, compiled->GetType());
const v8::HeapGraphNode* lazy = const v8::HeapGraphNode* lazy =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "lazy"); GetProperty(global, v8::HeapGraphEdge::kProperty, "lazy");
CHECK_NE(NULL, lazy); CHECK_NE(NULL, lazy);
CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType()); CHECK_EQ(v8::HeapGraphNode::kClosure, lazy->GetType());
const v8::HeapGraphNode* anonymous = const v8::HeapGraphNode* anonymous =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "anonymous"); GetProperty(global, v8::HeapGraphEdge::kProperty, "anonymous");
CHECK_NE(NULL, anonymous); CHECK_NE(NULL, anonymous);
CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType()); CHECK_EQ(v8::HeapGraphNode::kClosure, anonymous->GetType());
v8::String::AsciiValue anonymous_name(anonymous->GetName()); v8::String::AsciiValue anonymous_name(anonymous->GetName());
...@@ -293,9 +294,9 @@ TEST(HeapSnapshotHeapNumbers) { ...@@ -293,9 +294,9 @@ TEST(HeapSnapshotHeapNumbers) {
const v8::HeapSnapshot* snapshot = const v8::HeapSnapshot* snapshot =
v8::HeapProfiler::TakeSnapshot(v8_str("numbers")); v8::HeapProfiler::TakeSnapshot(v8_str("numbers"));
const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kShortcut, "a")); CHECK_EQ(NULL, GetProperty(global, v8::HeapGraphEdge::kProperty, "a"));
const v8::HeapGraphNode* b = const v8::HeapGraphNode* b =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "b"); GetProperty(global, v8::HeapGraphEdge::kProperty, "b");
CHECK_NE(NULL, b); CHECK_NE(NULL, b);
CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType()); CHECK_EQ(v8::HeapGraphNode::kHeapNumber, b->GetType());
} }
...@@ -313,10 +314,10 @@ TEST(HeapSnapshotSlicedString) { ...@@ -313,10 +314,10 @@ TEST(HeapSnapshotSlicedString) {
v8::HeapProfiler::TakeSnapshot(v8_str("strings")); v8::HeapProfiler::TakeSnapshot(v8_str("strings"));
const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
const v8::HeapGraphNode* parent_string = const v8::HeapGraphNode* parent_string =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "parent_string"); GetProperty(global, v8::HeapGraphEdge::kProperty, "parent_string");
CHECK_NE(NULL, parent_string); CHECK_NE(NULL, parent_string);
const v8::HeapGraphNode* child_string = const v8::HeapGraphNode* child_string =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "child_string"); GetProperty(global, v8::HeapGraphEdge::kProperty, "child_string");
CHECK_NE(NULL, child_string); CHECK_NE(NULL, child_string);
const v8::HeapGraphNode* parent = const v8::HeapGraphNode* parent =
GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent"); GetProperty(child_string, v8::HeapGraphEdge::kInternal, "parent");
...@@ -384,24 +385,17 @@ TEST(HeapEntryIdsAndArrayShift) { ...@@ -384,24 +385,17 @@ TEST(HeapEntryIdsAndArrayShift) {
const v8::HeapGraphNode* a1 = const v8::HeapGraphNode* a1 =
GetProperty(global1, v8::HeapGraphEdge::kProperty, "a"); GetProperty(global1, v8::HeapGraphEdge::kProperty, "a");
CHECK_NE(NULL, a1); CHECK_NE(NULL, a1);
const v8::HeapGraphNode* e1 =
GetProperty(a1, v8::HeapGraphEdge::kHidden, "1");
CHECK_NE(NULL, e1);
const v8::HeapGraphNode* k1 = const v8::HeapGraphNode* k1 =
GetProperty(e1, v8::HeapGraphEdge::kInternal, "elements"); GetProperty(a1, v8::HeapGraphEdge::kInternal, "elements");
CHECK_NE(NULL, k1); CHECK_NE(NULL, k1);
const v8::HeapGraphNode* a2 = const v8::HeapGraphNode* a2 =
GetProperty(global2, v8::HeapGraphEdge::kProperty, "a"); GetProperty(global2, v8::HeapGraphEdge::kProperty, "a");
CHECK_NE(NULL, a2); CHECK_NE(NULL, a2);
const v8::HeapGraphNode* e2 =
GetProperty(a2, v8::HeapGraphEdge::kHidden, "1");
CHECK_NE(NULL, e2);
const v8::HeapGraphNode* k2 = const v8::HeapGraphNode* k2 =
GetProperty(e2, v8::HeapGraphEdge::kInternal, "elements"); GetProperty(a2, v8::HeapGraphEdge::kInternal, "elements");
CHECK_NE(NULL, k2); CHECK_NE(NULL, k2);
CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId()); CHECK_EQ_SNAPSHOT_OBJECT_ID(a1->GetId(), a2->GetId());
CHECK_EQ_SNAPSHOT_OBJECT_ID(e1->GetId(), e2->GetId());
CHECK_EQ_SNAPSHOT_OBJECT_ID(k1->GetId(), k2->GetId()); CHECK_EQ_SNAPSHOT_OBJECT_ID(k1->GetId(), k2->GetId());
} }
...@@ -514,7 +508,7 @@ TEST(HeapEntryDominator) { ...@@ -514,7 +508,7 @@ TEST(HeapEntryDominator) {
const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
CHECK_NE(NULL, global); CHECK_NE(NULL, global);
const v8::HeapGraphNode* node6 = const v8::HeapGraphNode* node6 =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "node6"); GetProperty(global, v8::HeapGraphEdge::kProperty, "node6");
CHECK_NE(NULL, node6); CHECK_NE(NULL, node6);
const v8::HeapGraphNode* node5 = const v8::HeapGraphNode* node5 =
GetProperty(node6, v8::HeapGraphEdge::kProperty, "a"); GetProperty(node6, v8::HeapGraphEdge::kProperty, "a");
...@@ -659,7 +653,7 @@ TEST(HeapSnapshotJSONSerialization) { ...@@ -659,7 +653,7 @@ TEST(HeapSnapshotJSONSerialization) {
" GetChildPosByProperty(" " GetChildPosByProperty("
" parsed.edges[parsed.nodes[edges_index_offset]" " parsed.edges[parsed.nodes[edges_index_offset]"
" + edge_to_node_offset]," " + edge_to_node_offset],"
" \"b\", shortcut_type),\n" " \"b\", property_type),\n"
" \"x\", property_type)," " \"x\", property_type),"
" \"s\", property_type)"); " \"s\", property_type)");
CHECK(!string_obj_pos_val.IsEmpty()); CHECK(!string_obj_pos_val.IsEmpty());
...@@ -1153,9 +1147,8 @@ TEST(HeapSnapshotImplicitReferences) { ...@@ -1153,9 +1147,8 @@ TEST(HeapSnapshotImplicitReferences) {
v8::HeapProfiler::TakeSnapshot(v8_str("implicit_refs")); v8::HeapProfiler::TakeSnapshot(v8_str("implicit_refs"));
const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot); const v8::HeapGraphNode* global_object = GetGlobalObject(snapshot);
// Use kShortcut type to skip intermediate JSGlobalPropertyCell
const v8::HeapGraphNode* obj0 = GetProperty( const v8::HeapGraphNode* obj0 = GetProperty(
global_object, v8::HeapGraphEdge::kShortcut, "root_object"); global_object, v8::HeapGraphEdge::kProperty, "root_object");
CHECK(obj0); CHECK(obj0);
CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType()); CHECK_EQ(v8::HeapGraphNode::kObject, obj0->GetType());
const v8::HeapGraphNode* obj1 = GetProperty( const v8::HeapGraphNode* obj1 = GetProperty(
...@@ -1328,7 +1321,7 @@ TEST(GetHeapValue) { ...@@ -1328,7 +1321,7 @@ TEST(GetHeapValue) {
env->Global()->GetPrototype().As<v8::Object>(); env->Global()->GetPrototype().As<v8::Object>();
CHECK(js_global == global->GetHeapValue()); CHECK(js_global == global->GetHeapValue());
const v8::HeapGraphNode* obj = GetProperty( const v8::HeapGraphNode* obj = GetProperty(
global, v8::HeapGraphEdge::kShortcut, "a"); global, v8::HeapGraphEdge::kProperty, "a");
CHECK(obj->GetHeapValue()->IsObject()); CHECK(obj->GetHeapValue()->IsObject());
v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>(); v8::Local<v8::Object> js_obj = js_global->Get(v8_str("a")).As<v8::Object>();
CHECK(js_obj == obj->GetHeapValue()); CHECK(js_obj == obj->GetHeapValue());
...@@ -1357,7 +1350,7 @@ TEST(GetHeapValueForDeletedObject) { ...@@ -1357,7 +1350,7 @@ TEST(GetHeapValueForDeletedObject) {
v8::HeapProfiler::TakeSnapshot(v8_str("snapshot")); v8::HeapProfiler::TakeSnapshot(v8_str("snapshot"));
const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
const v8::HeapGraphNode* obj = GetProperty( const v8::HeapGraphNode* obj = GetProperty(
global, v8::HeapGraphEdge::kShortcut, "a"); global, v8::HeapGraphEdge::kProperty, "a");
const v8::HeapGraphNode* prop = GetProperty( const v8::HeapGraphNode* prop = GetProperty(
obj, v8::HeapGraphEdge::kProperty, "p"); obj, v8::HeapGraphEdge::kProperty, "p");
{ {
...@@ -1444,7 +1437,7 @@ TEST(FastCaseGetter) { ...@@ -1444,7 +1437,7 @@ TEST(FastCaseGetter) {
const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
CHECK_NE(NULL, global); CHECK_NE(NULL, global);
const v8::HeapGraphNode* obj1 = const v8::HeapGraphNode* obj1 =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "obj1"); GetProperty(global, v8::HeapGraphEdge::kProperty, "obj1");
CHECK_NE(NULL, obj1); CHECK_NE(NULL, obj1);
const v8::HeapGraphNode* getterFunction = const v8::HeapGraphNode* getterFunction =
GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter"); GetProperty(obj1, v8::HeapGraphEdge::kProperty, "get-propWithGetter");
...@@ -1526,7 +1519,7 @@ TEST(SfiAndJsFunctionWeakRefs) { ...@@ -1526,7 +1519,7 @@ TEST(SfiAndJsFunctionWeakRefs) {
const v8::HeapGraphNode* global = GetGlobalObject(snapshot); const v8::HeapGraphNode* global = GetGlobalObject(snapshot);
CHECK_NE(NULL, global); CHECK_NE(NULL, global);
const v8::HeapGraphNode* fun = const v8::HeapGraphNode* fun =
GetProperty(global, v8::HeapGraphEdge::kShortcut, "fun"); GetProperty(global, v8::HeapGraphEdge::kProperty, "fun");
CHECK(HasWeakEdge(fun)); CHECK(HasWeakEdge(fun));
const v8::HeapGraphNode* shared = const v8::HeapGraphNode* shared =
GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared"); GetProperty(fun, v8::HeapGraphEdge::kInternal, "shared");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment