Chromium Code Reviews| Index: src/global-handles.cc | 
| diff --git a/src/global-handles.cc b/src/global-handles.cc | 
| index 404f3ad16789c0fae684b6a496dc91b24b83a831..b79f4e716cdba6f70d10d3f4ed3561d0e68559d5 100644 | 
| --- a/src/global-handles.cc | 
| +++ b/src/global-handles.cc | 
| @@ -811,6 +811,115 @@ bool GlobalHandles::IterateObjectGroups(ObjectVisitor* v, | 
| return any_group_was_visited; | 
| } | 
| +namespace { | 
| +// Traces the information about object groups and implicit ref groups given by | 
| +// the embedder to the V8 during each gc prologue. | 
| +class ObjectGroupsTracer { | 
| + public: | 
| + explicit ObjectGroupsTracer(Isolate* isolate); | 
| + void CollectTraces(); | 
| 
 
ulan
2016/03/09 14:37:49
Let's rename the method to Print() since that is w
 
Marcel Hlopko
2016/03/09 17:20:23
Done.
 
 | 
| + | 
| + private: | 
| + void PrintObjectGroup(ObjectGroup* group); | 
| + void PrintImplicitRefGroup(ImplicitRefGroup* group); | 
| + void PrintObject(Object* object); | 
| + void PrintConstructor(JSObject* js_object); | 
| + void PrintInternalFields(JSObject* js_object); | 
| + Isolate* isolate_; | 
| + DISALLOW_COPY_AND_ASSIGN(ObjectGroupsTracer); | 
| +}; | 
| + | 
| +ObjectGroupsTracer::ObjectGroupsTracer(Isolate* isolate) : isolate_(isolate) {} | 
| + | 
| +void ObjectGroupsTracer::CollectTraces() { | 
| + GlobalHandles* global_handles = isolate_->global_handles(); | 
| + | 
| + PrintIsolate(isolate_, "### Tracing object groups:\n"); | 
| + | 
| + List<ObjectGroup*>* object_groups = global_handles->object_groups(); | 
| + for (int i = 0; i < object_groups->length(); ++i) { | 
| 
 
ulan
2016/03/09 14:37:49
We can use:
for (auto group : *object_groups) {
..
 
Marcel Hlopko
2016/03/09 17:20:23
Done.
 
 | 
| + PrintObjectGroup(object_groups->at(i)); | 
| + } | 
| + | 
| + List<ImplicitRefGroup*>* implicit_ref_groups = | 
| + global_handles->implicit_ref_groups(); | 
| + for (int i = 0; i < implicit_ref_groups->length(); ++i) { | 
| + PrintImplicitRefGroup(implicit_ref_groups->at(i)); | 
| + } | 
| + | 
| + PrintIsolate(isolate_, "### Tracing object groups finished.\n"); | 
| +} | 
| + | 
| +void ObjectGroupsTracer::PrintObject(Object* o) { | 
| 
 
ulan
2016/03/09 14:37:49
Let's replace "o" with more descriptive "object".
 
Marcel Hlopko
2016/03/09 17:20:23
Done.
 
 | 
| + JSObject* js_object = reinterpret_cast<JSObject*>(o); | 
| 
 
ulan
2016/03/09 14:37:49
if (object->IsJSObject()) {
  JSObject* js_object
 
Marcel Hlopko
2016/03/09 17:20:23
Done.
 
 | 
| + | 
| + PrintF("{ constructor_name: "); | 
| + PrintConstructor(js_object); | 
| + PrintF(", hidden_fields: [ "); | 
| + PrintInternalFields(js_object); | 
| + PrintF(" ] }\n"); | 
| +} | 
| + | 
| +void ObjectGroupsTracer::PrintConstructor(JSObject* js_object) { | 
| + Object* maybe_constructor = js_object->map()->GetConstructor(); | 
| + if (maybe_constructor->IsJSFunction()) { | 
| + JSFunction* constructor = JSFunction::cast(maybe_constructor); | 
| + String* name = String::cast(constructor->shared()->name()); | 
| + if (name->length() == 0) name = constructor->shared()->inferred_name(); | 
| + | 
| + PrintF("%s", name->ToCString().get()); | 
| + } else if (maybe_constructor->IsNull()) { | 
| + if (js_object->IsOddball()) { | 
| + PrintF("<oddball>"); | 
| + } else { | 
| + PrintF("<null>"); | 
| + } | 
| + } else { | 
| + UNREACHABLE(); | 
| + } | 
| +} | 
| + | 
| +void ObjectGroupsTracer::PrintInternalFields(JSObject* js_object) { | 
| + if (js_object->IsOddball()) { | 
| 
 
ulan
2016/03/09 14:37:49
Not needed.
 
Marcel Hlopko
2016/03/09 17:20:23
Done.
 
 | 
| + return; | 
| + } | 
| + | 
| + for (int i = 0; i < js_object->GetInternalFieldCount(); ++i) { | 
| + if (i != 0) { | 
| + PrintF(", "); | 
| + } | 
| + PrintF("%p", js_object->GetInternalField(i)); | 
| + } | 
| +} | 
| + | 
| +void ObjectGroupsTracer::PrintObjectGroup(ObjectGroup* group) { | 
| + PrintIsolate(isolate_, "ObjectGroup (size: %lu)\n", group->length); | 
| + Object*** objects = group->objects; | 
| + | 
| + for (size_t i = 0; i < group->length; ++i) { | 
| + PrintIsolate(isolate_, " - Member: "); | 
| + PrintObject(*objects[i]); | 
| + } | 
| +} | 
| + | 
| +void ObjectGroupsTracer::PrintImplicitRefGroup(ImplicitRefGroup* group) { | 
| + PrintIsolate(isolate_, "ImplicitRefGroup (children count: %lu)\n", | 
| + group->length); | 
| + PrintIsolate(isolate_, " - Parent: "); | 
| + PrintObject(*(group->parent)); | 
| + | 
| + Object*** children = group->children; | 
| + for (size_t i = 0; i < group->length; ++i) { | 
| + PrintIsolate(isolate_, " - Child: "); | 
| + PrintObject(*children[i]); | 
| + } | 
| +} | 
| + | 
| +} // namespace | 
| + | 
| +void GlobalHandles::PrintObjectGroups() { | 
| + ObjectGroupsTracer(isolate_).CollectTraces(); | 
| +} | 
| void GlobalHandles::InvokeSecondPassPhantomCallbacks( | 
| List<PendingPhantomCallback>* callbacks, Isolate* isolate) { |