| Index: src/global-handles.cc
|
| diff --git a/src/global-handles.cc b/src/global-handles.cc
|
| index 404f3ad16789c0fae684b6a496dc91b24b83a831..44397febcc7c2685cab36281f8497a182272d3cd 100644
|
| --- a/src/global-handles.cc
|
| +++ b/src/global-handles.cc
|
| @@ -811,6 +811,111 @@ 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 Print();
|
| +
|
| + 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::Print() {
|
| + GlobalHandles* global_handles = isolate_->global_handles();
|
| +
|
| + PrintIsolate(isolate_, "### Tracing object groups:\n");
|
| +
|
| + for (auto group : *(global_handles->object_groups())) {
|
| + PrintObjectGroup(group);
|
| + }
|
| + for (auto group : *(global_handles->implicit_ref_groups())) {
|
| + PrintImplicitRefGroup(group);
|
| + }
|
| +
|
| + PrintIsolate(isolate_, "### Tracing object groups finished.\n");
|
| +}
|
| +
|
| +void ObjectGroupsTracer::PrintObject(Object* object) {
|
| + if (object->IsJSObject()) {
|
| + JSObject* js_object = JSObject::cast(object);
|
| +
|
| + PrintF("{ constructor_name: ");
|
| + PrintConstructor(js_object);
|
| + PrintF(", hidden_fields: [ ");
|
| + PrintInternalFields(js_object);
|
| + PrintF(" ] }\n");
|
| + } else {
|
| + PrintF("object of unexpected type: %p\n", object);
|
| + }
|
| +}
|
| +
|
| +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) {
|
| + 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_).Print();
|
| +}
|
|
|
| void GlobalHandles::InvokeSecondPassPhantomCallbacks(
|
| List<PendingPhantomCallback>* callbacks, Isolate* isolate) {
|
|
|