Revision: 11424
Author:   [email protected]
Date:     Tue Apr 24 05:38:58 2012
Log: Refactoring of heap profiler: split ExtractReferences into several functions.

Review URL: https://chromiumcodereview.appspot.com/10198011
http://code.google.com/p/v8/source/detail?r=11424

Modified:
 /branches/bleeding_edge/src/profile-generator.cc
 /branches/bleeding_edge/src/profile-generator.h

=======================================
--- /branches/bleeding_edge/src/profile-generator.cc Mon Apr 23 09:10:35 2012 +++ /branches/bleeding_edge/src/profile-generator.cc Tue Apr 24 05:38:58 2012
@@ -1978,212 +1978,24 @@

   bool extract_indexed_refs = true;
   if (obj->IsJSGlobalProxy()) {
-    // We need to reference JS global objects from snapshot's root.
-    // We use JSGlobalProxy because this is what embedder (e.g. browser)
-    // uses for the global object.
-    JSGlobalProxy* proxy = JSGlobalProxy::cast(obj);
-    Object* object = proxy->map()->prototype();
-    bool is_debug_object = false;
-#ifdef ENABLE_DEBUGGER_SUPPORT
-    is_debug_object = object->IsGlobalObject() &&
- Isolate::Current()->debug()->IsDebugGlobal(GlobalObject::cast(object));
-#endif
-    if (!is_debug_object) {
-      SetUserGlobalReference(object);
-    }
+    ExtractJSGlobalProxy(JSGlobalProxy::cast(obj));
   } else if (obj->IsJSObject()) {
-    JSObject* js_obj = JSObject::cast(obj);
-    ExtractClosureReferences(js_obj, entry);
-    ExtractPropertyReferences(js_obj, entry);
-    ExtractElementReferences(js_obj, entry);
-    ExtractInternalReferences(js_obj, entry);
-    SetPropertyReference(
-        obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype());
-    if (obj->IsJSFunction()) {
-      JSFunction* js_fun = JSFunction::cast(js_obj);
-      Object* proto_or_map = js_fun->prototype_or_initial_map();
-      if (!proto_or_map->IsTheHole()) {
-        if (!proto_or_map->IsMap()) {
-          SetPropertyReference(
-              obj, entry,
-              heap_->prototype_symbol(), proto_or_map,
-              NULL,
-              JSFunction::kPrototypeOrInitialMapOffset);
-        } else {
-          SetPropertyReference(
-              obj, entry,
-              heap_->prototype_symbol(), js_fun->prototype());
-        }
-      }
-      SharedFunctionInfo* shared_info = js_fun->shared();
-      // JSFunction has either bindings or literals and never both.
-      bool bound = shared_info->bound();
-      TagObject(js_fun->literals_or_bindings(),
-                bound ? "(function bindings)" : "(function literals)");
-      SetInternalReference(js_fun, entry,
-                           bound ? "bindings" : "literals",
-                           js_fun->literals_or_bindings(),
-                           JSFunction::kLiteralsOffset);
-      TagObject(shared_info, "(shared function info)");
-      SetInternalReference(js_fun, entry,
-                           "shared", shared_info,
-                           JSFunction::kSharedFunctionInfoOffset);
-      TagObject(js_fun->unchecked_context(), "(context)");
-      SetInternalReference(js_fun, entry,
-                           "context", js_fun->unchecked_context(),
-                           JSFunction::kContextOffset);
-      for (int i = JSFunction::kNonWeakFieldsEndOffset;
-           i < JSFunction::kSize;
-           i += kPointerSize) {
- SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i);
-      }
-    } else if (obj->IsGlobalObject()) {
-      GlobalObject* global_obj = GlobalObject::cast(obj);
-      SetInternalReference(global_obj, entry,
-                           "builtins", global_obj->builtins(),
-                           GlobalObject::kBuiltinsOffset);
-      SetInternalReference(global_obj, entry,
-                           "global_context", global_obj->global_context(),
-                           GlobalObject::kGlobalContextOffset);
-      SetInternalReference(global_obj, entry,
- "global_receiver", global_obj->global_receiver(),
-                           GlobalObject::kGlobalReceiverOffset);
-    }
-    TagObject(js_obj->properties(), "(object properties)");
-    SetInternalReference(obj, entry,
-                         "properties", js_obj->properties(),
-                         JSObject::kPropertiesOffset);
-    TagObject(js_obj->elements(), "(object elements)");
-    SetInternalReference(obj, entry,
-                         "elements", js_obj->elements(),
-                         JSObject::kElementsOffset);
+    ExtractJSObject(entry, JSObject::cast(obj));
   } else if (obj->IsString()) {
-    if (obj->IsConsString()) {
-      ConsString* cs = ConsString::cast(obj);
-      SetInternalReference(obj, entry, 1, cs->first());
-      SetInternalReference(obj, entry, 2, cs->second());
-    }
-    if (obj->IsSlicedString()) {
-      SlicedString* ss = SlicedString::cast(obj);
-      SetInternalReference(obj, entry, "parent", ss->parent());
-    }
+    ExtractString(entry, String::cast(obj));
     extract_indexed_refs = false;
   } else if (obj->IsContext()) {
-    Context* context = Context::cast(obj);
-#define EXTRACT_CONTEXT_FIELD(index, type, name) \
- SetInternalReference(context, entry, #name, context->get(Context::index), \
-        FixedArray::OffsetOfElementAt(Context::index));
-    EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure);
-    EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous);
-    EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension);
-    EXTRACT_CONTEXT_FIELD(GLOBAL_INDEX, GlobalObject, global);
-    if (obj->IsGlobalContext()) {
-      TagObject(context->jsfunction_result_caches(),
-                "(context func. result caches)");
- TagObject(context->normalized_map_cache(), "(context norm. map cache)");
-      TagObject(context->runtime_context(), "(runtime context)");
-      TagObject(context->data(), "(context data)");
-      GLOBAL_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD);
-#undef EXTRACT_CONTEXT_FIELD
-      for (int i = Context::FIRST_WEAK_SLOT;
-           i < Context::GLOBAL_CONTEXT_SLOTS;
-           ++i) {
-        SetWeakReference(obj, entry,
-                         i, context->get(i),
-                         FixedArray::OffsetOfElementAt(i));
-      }
-    }
+    ExtractContext(entry, Context::cast(obj));
   } else if (obj->IsMap()) {
-    Map* map = Map::cast(obj);
-    SetInternalReference(obj, entry,
- "prototype", map->prototype(), Map::kPrototypeOffset);
-    SetInternalReference(obj, entry,
-                         "constructor", map->constructor(),
-                         Map::kConstructorOffset);
-    if (!map->instance_descriptors()->IsEmpty()) {
-      TagObject(map->instance_descriptors(), "(map descriptors)");
-      SetInternalReference(obj, entry,
-                           "descriptors", map->instance_descriptors(),
-                           Map::kInstanceDescriptorsOrBitField3Offset);
-    }
-    TagObject(map->prototype_transitions(), "(prototype transitions)");
-    SetInternalReference(obj, entry,
- "prototype_transitions", map->prototype_transitions(),
-                         Map::kPrototypeTransitionsOffset);
-    SetInternalReference(obj, entry,
-                         "code_cache", map->code_cache(),
-                         Map::kCodeCacheOffset);
+    ExtractMap(entry, Map::cast(obj));
   } else if (obj->IsSharedFunctionInfo()) {
-    SharedFunctionInfo* shared = SharedFunctionInfo::cast(obj);
-    SetInternalReference(obj, entry,
-                         "name", shared->name(),
-                         SharedFunctionInfo::kNameOffset);
-    TagObject(shared->code(), "(code)");
-    SetInternalReference(obj, entry,
-                         "code", shared->code(),
-                         SharedFunctionInfo::kCodeOffset);
-    TagObject(shared->scope_info(), "(function scope info)");
-    SetInternalReference(obj, entry,
-                         "scope_info", shared->scope_info(),
-                         SharedFunctionInfo::kScopeInfoOffset);
-    SetInternalReference(obj, entry,
- "instance_class_name", shared->instance_class_name(),
-                         SharedFunctionInfo::kInstanceClassNameOffset);
-    SetInternalReference(obj, entry,
-                         "script", shared->script(),
-                         SharedFunctionInfo::kScriptOffset);
-    TagObject(shared->construct_stub(), "(code)");
-    SetInternalReference(obj, entry,
-                         "construct_stub", shared->construct_stub(),
-                         SharedFunctionInfo::kConstructStubOffset);
-    SetInternalReference(obj, entry,
-                         "function_data", shared->function_data(),
-                         SharedFunctionInfo::kFunctionDataOffset);
-    SetInternalReference(obj, entry,
-                         "debug_info", shared->debug_info(),
-                         SharedFunctionInfo::kDebugInfoOffset);
-    SetInternalReference(obj, entry,
-                         "inferred_name", shared->inferred_name(),
-                         SharedFunctionInfo::kInferredNameOffset);
-    SetInternalReference(obj, entry,
-                         "this_property_assignments",
-                         shared->this_property_assignments(),
- SharedFunctionInfo::kThisPropertyAssignmentsOffset);
-    SetWeakReference(obj, entry,
-                     1, shared->initial_map(),
-                     SharedFunctionInfo::kInitialMapOffset);
+    ExtractSharedFunctionInfo(entry, SharedFunctionInfo::cast(obj));
   } else if (obj->IsScript()) {
-    Script* script = Script::cast(obj);
-    SetInternalReference(obj, entry,
-                         "source", script->source(),
-                         Script::kSourceOffset);
-    SetInternalReference(obj, entry,
-                         "name", script->name(),
-                         Script::kNameOffset);
-    SetInternalReference(obj, entry,
-                         "data", script->data(),
-                         Script::kDataOffset);
-    SetInternalReference(obj, entry,
-                         "context_data", script->context_data(),
-                         Script::kContextOffset);
-    TagObject(script->line_ends(), "(script line ends)");
-    SetInternalReference(obj, entry,
-                         "line_ends", script->line_ends(),
-                         Script::kLineEndsOffset);
+    ExtractScript(entry, Script::cast(obj));
   } else if (obj->IsCodeCache()) {
-    CodeCache* code_cache = CodeCache::cast(obj);
-    TagObject(code_cache->default_cache(), "(default code cache)");
-    SetInternalReference(obj, entry,
-                         "default_cache", code_cache->default_cache(),
-                         CodeCache::kDefaultCacheOffset);
-    TagObject(code_cache->normal_type_cache(), "(code type cache)");
-    SetInternalReference(obj, entry,
-                         "type_cache", code_cache->normal_type_cache(),
-                         CodeCache::kNormalTypeCacheOffset);
+    ExtractCodeCache(entry, CodeCache::cast(obj));
   } else if (obj->IsCode()) {
-    Code* code = Code::cast(obj);
-    TagObject(code->unchecked_relocation_info(), "(code relocation info)");
-    TagObject(code->unchecked_deoptimization_data(), "(code deopt data)");
+    ExtractCode(entry, Code::cast(obj));
   }
   if (extract_indexed_refs) {
SetInternalReference(obj, entry, "map", obj->map(), HeapObject::kMapOffset);
@@ -2191,6 +2003,234 @@
     obj->Iterate(&refs_extractor);
   }
 }
+
+
+void V8HeapExplorer::ExtractJSGlobalProxy(JSGlobalProxy* proxy) {
+  // We need to reference JS global objects from snapshot's root.
+  // We use JSGlobalProxy because this is what embedder (e.g. browser)
+  // uses for the global object.
+  Object* object = proxy->map()->prototype();
+  bool is_debug_object = false;
+#ifdef ENABLE_DEBUGGER_SUPPORT
+  is_debug_object = object->IsGlobalObject() &&
+ Isolate::Current()->debug()->IsDebugGlobal(GlobalObject::cast(object));
+#endif
+  if (!is_debug_object) {
+    SetUserGlobalReference(object);
+  }
+}
+
+
+void V8HeapExplorer::ExtractJSObject(HeapEntry* entry, JSObject* js_obj) {
+  HeapObject* obj = js_obj;
+  ExtractClosureReferences(js_obj, entry);
+  ExtractPropertyReferences(js_obj, entry);
+  ExtractElementReferences(js_obj, entry);
+  ExtractInternalReferences(js_obj, entry);
+  SetPropertyReference(
+      obj, entry, heap_->Proto_symbol(), js_obj->GetPrototype());
+  if (obj->IsJSFunction()) {
+    JSFunction* js_fun = JSFunction::cast(js_obj);
+    Object* proto_or_map = js_fun->prototype_or_initial_map();
+    if (!proto_or_map->IsTheHole()) {
+      if (!proto_or_map->IsMap()) {
+        SetPropertyReference(
+            obj, entry,
+            heap_->prototype_symbol(), proto_or_map,
+            NULL,
+            JSFunction::kPrototypeOrInitialMapOffset);
+      } else {
+        SetPropertyReference(
+            obj, entry,
+            heap_->prototype_symbol(), js_fun->prototype());
+      }
+    }
+    SharedFunctionInfo* shared_info = js_fun->shared();
+    // JSFunction has either bindings or literals and never both.
+    bool bound = shared_info->bound();
+    TagObject(js_fun->literals_or_bindings(),
+              bound ? "(function bindings)" : "(function literals)");
+    SetInternalReference(js_fun, entry,
+                         bound ? "bindings" : "literals",
+                         js_fun->literals_or_bindings(),
+                         JSFunction::kLiteralsOffset);
+    TagObject(shared_info, "(shared function info)");
+    SetInternalReference(js_fun, entry,
+                         "shared", shared_info,
+                         JSFunction::kSharedFunctionInfoOffset);
+    TagObject(js_fun->unchecked_context(), "(context)");
+    SetInternalReference(js_fun, entry,
+                         "context", js_fun->unchecked_context(),
+                         JSFunction::kContextOffset);
+    for (int i = JSFunction::kNonWeakFieldsEndOffset;
+         i < JSFunction::kSize;
+         i += kPointerSize) {
+ SetWeakReference(js_fun, entry, i, *HeapObject::RawField(js_fun, i), i);
+    }
+  } else if (obj->IsGlobalObject()) {
+    GlobalObject* global_obj = GlobalObject::cast(obj);
+    SetInternalReference(global_obj, entry,
+                         "builtins", global_obj->builtins(),
+                         GlobalObject::kBuiltinsOffset);
+    SetInternalReference(global_obj, entry,
+                         "global_context", global_obj->global_context(),
+                         GlobalObject::kGlobalContextOffset);
+    SetInternalReference(global_obj, entry,
+                         "global_receiver", global_obj->global_receiver(),
+                         GlobalObject::kGlobalReceiverOffset);
+  }
+  TagObject(js_obj->properties(), "(object properties)");
+  SetInternalReference(obj, entry,
+                       "properties", js_obj->properties(),
+                       JSObject::kPropertiesOffset);
+  TagObject(js_obj->elements(), "(object elements)");
+  SetInternalReference(obj, entry,
+                       "elements", js_obj->elements(),
+                       JSObject::kElementsOffset);
+}
+
+
+void V8HeapExplorer::ExtractString(HeapEntry* entry, String* string) {
+  if (string->IsConsString()) {
+    ConsString* cs = ConsString::cast(string);
+    SetInternalReference(cs, entry, 1, cs->first());
+    SetInternalReference(cs, entry, 2, cs->second());
+  }
+  if (string->IsSlicedString()) {
+    SlicedString* ss = SlicedString::cast(string);
+    SetInternalReference(ss, entry, "parent", ss->parent());
+  }
+}
+
+
+void V8HeapExplorer::ExtractContext(HeapEntry* entry, Context* context) {
+#define EXTRACT_CONTEXT_FIELD(index, type, name) \
+ SetInternalReference(context, entry, #name, context->get(Context::index), \
+      FixedArray::OffsetOfElementAt(Context::index));
+  EXTRACT_CONTEXT_FIELD(CLOSURE_INDEX, JSFunction, closure);
+  EXTRACT_CONTEXT_FIELD(PREVIOUS_INDEX, Context, previous);
+  EXTRACT_CONTEXT_FIELD(EXTENSION_INDEX, Object, extension);
+  EXTRACT_CONTEXT_FIELD(GLOBAL_INDEX, GlobalObject, global);
+  if (context->IsGlobalContext()) {
+    TagObject(context->jsfunction_result_caches(),
+              "(context func. result caches)");
+ TagObject(context->normalized_map_cache(), "(context norm. map cache)");
+    TagObject(context->runtime_context(), "(runtime context)");
+    TagObject(context->data(), "(context data)");
+    GLOBAL_CONTEXT_FIELDS(EXTRACT_CONTEXT_FIELD);
+#undef EXTRACT_CONTEXT_FIELD
+    for (int i = Context::FIRST_WEAK_SLOT;
+         i < Context::GLOBAL_CONTEXT_SLOTS;
+         ++i) {
+      SetWeakReference(context, entry, i, context->get(i),
+          FixedArray::OffsetOfElementAt(i));
+    }
+  }
+}
+
+
+void V8HeapExplorer::ExtractMap(HeapEntry* entry, Map* map) {
+  SetInternalReference(map, entry,
+ "prototype", map->prototype(), Map::kPrototypeOffset);
+  SetInternalReference(map, entry,
+                       "constructor", map->constructor(),
+                       Map::kConstructorOffset);
+  if (!map->instance_descriptors()->IsEmpty()) {
+    TagObject(map->instance_descriptors(), "(map descriptors)");
+    SetInternalReference(map, entry,
+                         "descriptors", map->instance_descriptors(),
+                         Map::kInstanceDescriptorsOrBitField3Offset);
+  }
+  TagObject(map->prototype_transitions(), "(prototype transitions)");
+  SetInternalReference(map, entry,
+ "prototype_transitions", map->prototype_transitions(),
+                       Map::kPrototypeTransitionsOffset);
+  SetInternalReference(map, entry,
+                       "code_cache", map->code_cache(),
+                       Map::kCodeCacheOffset);
+}
+
+
+void V8HeapExplorer::ExtractSharedFunctionInfo(
+    HeapEntry* entry, SharedFunctionInfo* shared) {
+  HeapObject* obj = shared;
+  SetInternalReference(obj, entry,
+                       "name", shared->name(),
+                       SharedFunctionInfo::kNameOffset);
+  TagObject(shared->code(), "(code)");
+  SetInternalReference(obj, entry,
+                       "code", shared->code(),
+                       SharedFunctionInfo::kCodeOffset);
+  TagObject(shared->scope_info(), "(function scope info)");
+  SetInternalReference(obj, entry,
+                       "scope_info", shared->scope_info(),
+                       SharedFunctionInfo::kScopeInfoOffset);
+  SetInternalReference(obj, entry,
+ "instance_class_name", shared->instance_class_name(),
+                       SharedFunctionInfo::kInstanceClassNameOffset);
+  SetInternalReference(obj, entry,
+                       "script", shared->script(),
+                       SharedFunctionInfo::kScriptOffset);
+  TagObject(shared->construct_stub(), "(code)");
+  SetInternalReference(obj, entry,
+                       "construct_stub", shared->construct_stub(),
+                       SharedFunctionInfo::kConstructStubOffset);
+  SetInternalReference(obj, entry,
+                       "function_data", shared->function_data(),
+                       SharedFunctionInfo::kFunctionDataOffset);
+  SetInternalReference(obj, entry,
+                       "debug_info", shared->debug_info(),
+                       SharedFunctionInfo::kDebugInfoOffset);
+  SetInternalReference(obj, entry,
+                       "inferred_name", shared->inferred_name(),
+                       SharedFunctionInfo::kInferredNameOffset);
+  SetInternalReference(obj, entry,
+                       "this_property_assignments",
+                       shared->this_property_assignments(),
+                       SharedFunctionInfo::kThisPropertyAssignmentsOffset);
+  SetWeakReference(obj, entry,
+                   1, shared->initial_map(),
+                   SharedFunctionInfo::kInitialMapOffset);
+}
+
+
+void V8HeapExplorer::ExtractScript(HeapEntry* entry, Script* script) {
+  HeapObject* obj = script;
+  SetInternalReference(obj, entry,
+                       "source", script->source(),
+                       Script::kSourceOffset);
+  SetInternalReference(obj, entry,
+                       "name", script->name(),
+                       Script::kNameOffset);
+  SetInternalReference(obj, entry,
+                       "data", script->data(),
+                       Script::kDataOffset);
+  SetInternalReference(obj, entry,
+                       "context_data", script->context_data(),
+                       Script::kContextOffset);
+  TagObject(script->line_ends(), "(script line ends)");
+  SetInternalReference(obj, entry,
+                       "line_ends", script->line_ends(),
+                       Script::kLineEndsOffset);
+}
+
+
+void V8HeapExplorer::ExtractCodeCache(HeapEntry* entry, CodeCache* code_cache) {
+  TagObject(code_cache->default_cache(), "(default code cache)");
+  SetInternalReference(code_cache, entry,
+                       "default_cache", code_cache->default_cache(),
+                       CodeCache::kDefaultCacheOffset);
+  TagObject(code_cache->normal_type_cache(), "(code type cache)");
+  SetInternalReference(code_cache, entry,
+                       "type_cache", code_cache->normal_type_cache(),
+                       CodeCache::kNormalTypeCacheOffset);
+}
+
+
+void V8HeapExplorer::ExtractCode(HeapEntry* entry, Code* code) {
+  TagObject(code->unchecked_relocation_info(), "(code relocation info)");
+  TagObject(code->unchecked_deoptimization_data(), "(code deopt data)");
+}


 void V8HeapExplorer::ExtractClosureReferences(JSObject* js_obj,
=======================================
--- /branches/bleeding_edge/src/profile-generator.h     Fri Apr 20 07:03:06 2012
+++ /branches/bleeding_edge/src/profile-generator.h     Tue Apr 24 05:38:58 2012
@@ -975,7 +975,17 @@
                       int children_count,
                       int retainers_count);
   const char* GetSystemEntryName(HeapObject* object);
+
   void ExtractReferences(HeapObject* obj);
+  void ExtractJSGlobalProxy(JSGlobalProxy* proxy);
+  void ExtractJSObject(HeapEntry* entry, JSObject* js_obj);
+  void ExtractString(HeapEntry* entry, String* obj);
+  void ExtractContext(HeapEntry* entry, Context* context);
+  void ExtractMap(HeapEntry* entry, Map* map);
+ void ExtractSharedFunctionInfo(HeapEntry* entry, SharedFunctionInfo* shared);
+  void ExtractScript(HeapEntry* entry, Script* script);
+  void ExtractCodeCache(HeapEntry* entry, CodeCache* code_cache);
+  void ExtractCode(HeapEntry* entry, Code* code);
   void ExtractClosureReferences(JSObject* js_obj, HeapEntry* entry);
   void ExtractPropertyReferences(JSObject* js_obj, HeapEntry* entry);
   void ExtractElementReferences(JSObject* js_obj, HeapEntry* entry);

--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to