Improve generalization / migration tracing.
authorverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 19 Aug 2013 12:32:50 +0000 (12:32 +0000)
committerverwaest@chromium.org <verwaest@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Mon, 19 Aug 2013 12:32:50 +0000 (12:32 +0000)
R=yangguo@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@16219 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects-inl.h
src/objects.cc
src/objects.h

index 1694757..6c1ecbb 100644 (file)
@@ -1567,14 +1567,27 @@ MaybeObject* JSObject::MigrateInstance() {
   // Converting any field to the most specific type will cause the
   // GeneralizeFieldRepresentation algorithm to create the most general existing
   // transition that matches the object. This achieves what is needed.
-  return GeneralizeFieldRepresentation(0, Representation::None());
+  Map* original_map = map();
+  MaybeObject* maybe_result = GeneralizeFieldRepresentation(
+      0, Representation::None());
+  JSObject* result;
+  if (FLAG_trace_migration && maybe_result->To(&result)) {
+    PrintInstanceMigration(stdout, original_map, result->map());
+  }
+  return maybe_result;
 }
 
 
 MaybeObject* JSObject::TryMigrateInstance() {
   Map* new_map = map()->CurrentMapForDeprecated();
   if (new_map == NULL) return Smi::FromInt(0);
-  return MigrateToMap(new_map);
+  Map* original_map = map();
+  MaybeObject* maybe_result = MigrateToMap(new_map);
+  JSObject* result;
+  if (FLAG_trace_migration && maybe_result->To(&result)) {
+    PrintInstanceMigration(stdout, original_map, result->map());
+  }
+  return maybe_result;
 }
 
 
index 38d8647..7e15f30 100644 (file)
@@ -1449,6 +1449,54 @@ void JSObject::PrintElementsTransition(
 }
 
 
+void Map::PrintGeneralization(FILE* file,
+                              int modify_index,
+                              int split,
+                              int descriptors,
+                              Representation old_representation,
+                              Representation new_representation) {
+  PrintF(file, "[generalizing ");
+  constructor_name()->PrintOn(file);
+  PrintF(file, "] ");
+  String::cast(instance_descriptors()->GetKey(modify_index))->PrintOn(file);
+  PrintF(file, ":%s->%s (+%i maps) [",
+         old_representation.Mnemonic(),
+         new_representation.Mnemonic(),
+         descriptors - split);
+  JavaScriptFrame::PrintTop(GetIsolate(), file, false, true);
+  PrintF(file, "]\n");
+}
+
+
+void JSObject::PrintInstanceMigration(FILE* file,
+                                      Map* original_map,
+                                      Map* new_map) {
+  PrintF(file, "[migrating ");
+  map()->constructor_name()->PrintOn(file);
+  PrintF(file, "] ");
+  DescriptorArray* o = original_map->instance_descriptors();
+  DescriptorArray* n = new_map->instance_descriptors();
+  for (int i = 0; i < original_map->NumberOfOwnDescriptors(); i++) {
+    Representation o_r = o->GetDetails(i).representation();
+    Representation n_r = n->GetDetails(i).representation();
+    if (!o_r.Equals(n_r)) {
+      String::cast(o->GetKey(i))->PrintOn(file);
+      PrintF(file, ":%s->%s ", o_r.Mnemonic(), n_r.Mnemonic());
+    } else if (o->GetDetails(i).type() == CONSTANT &&
+               n->GetDetails(i).type() == FIELD) {
+      Name* name = o->GetKey(i);
+      if (name->IsString()) {
+        String::cast(name)->PrintOn(file);
+      } else {
+        PrintF(file, "???");
+      }
+      PrintF(file, " ");
+    }
+  }
+  PrintF(file, "\n");
+}
+
+
 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) {
   Heap* heap = GetHeap();
   if (!heap->Contains(this)) {
@@ -1783,14 +1831,14 @@ String* JSReceiver::class_name() {
 }
 
 
-String* JSReceiver::constructor_name() {
-  if (map()->constructor()->IsJSFunction()) {
-    JSFunction* constructor = JSFunction::cast(map()->constructor());
+String* Map::constructor_name() {
+  if (constructor()->IsJSFunction()) {
+    JSFunction* constructor = JSFunction::cast(this->constructor());
     String* name = String::cast(constructor->shared()->name());
     if (name->length() > 0) return name;
     String* inferred_name = constructor->shared()->inferred_name();
     if (inferred_name->length() > 0) return inferred_name;
-    Object* proto = GetPrototype();
+    Object* proto = prototype();
     if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name();
   }
   // TODO(rossberg): what about proxies?
@@ -1799,6 +1847,11 @@ String* JSReceiver::constructor_name() {
 }
 
 
+String* JSReceiver::constructor_name() {
+  return map()->constructor_name();
+}
+
+
 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map,
                                                Name* name,
                                                Object* value,
@@ -2626,12 +2679,6 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
   if (old_representation.IsNone() &&
       !new_representation.IsNone() &&
       !new_representation.IsDouble()) {
-    if (FLAG_trace_generalization) {
-      PrintF("initializing representation %i: %p -> %s\n",
-             modify_index,
-             static_cast<void*>(this),
-             new_representation.Mnemonic());
-    }
     old_descriptors->SetRepresentation(modify_index, new_representation);
     return old_map;
   }
@@ -2661,11 +2708,9 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
       if (FLAG_trace_generalization &&
           !(modify_index == 0 && new_representation.IsNone())) {
         PropertyDetails old_details = old_descriptors->GetDetails(modify_index);
-        PrintF("migrating to existing map %p(%s) -> %p(%s)\n",
-               static_cast<void*>(this),
-               old_details.representation().Mnemonic(),
-               static_cast<void*>(updated),
-               updated_representation.Mnemonic());
+        PrintGeneralization(stdout, modify_index, descriptors, descriptors,
+                            old_details.representation(),
+                            updated_representation);
       }
       return updated;
     }
@@ -2698,13 +2743,8 @@ MaybeObject* Map::GeneralizeRepresentation(int modify_index,
 
   if (FLAG_trace_generalization &&
       !(modify_index == 0 && new_representation.IsNone())) {
-    PrintF("migrating to new map %i: %p(%s) -> %p(%s) (%i steps)\n",
-           modify_index,
-           static_cast<void*>(this),
-           old_representation.Mnemonic(),
-           static_cast<void*>(new_descriptors),
-           updated_representation.Mnemonic(),
-           descriptors - descriptor);
+    PrintGeneralization(stdout, modify_index, descriptor, descriptors,
+                        old_representation, updated_representation);
   }
 
   Map* new_map = split_map;
@@ -3726,11 +3766,6 @@ void JSObject::AllocateStorageForMap(Handle<JSObject> object, Handle<Map> map) {
 
 
 void JSObject::MigrateInstance(Handle<JSObject> object) {
-  if (FLAG_trace_migration) {
-    PrintF("migrating instance %p (%p)\n",
-           static_cast<void*>(*object),
-           static_cast<void*>(object->map()));
-  }
   CALL_HEAP_FUNCTION_VOID(
       object->GetIsolate(),
       object->MigrateInstance());
@@ -3738,11 +3773,6 @@ void JSObject::MigrateInstance(Handle<JSObject> object) {
 
 
 Handle<Object> JSObject::TryMigrateInstance(Handle<JSObject> object) {
-  if (FLAG_trace_migration) {
-    PrintF("migrating instance (no new maps) %p (%p)\n",
-           static_cast<void*>(*object),
-           static_cast<void*>(object->map()));
-  }
   CALL_HEAP_FUNCTION(
       object->GetIsolate(),
       object->MigrateInstance(),
index f800c5d..96b4011 100644 (file)
@@ -2672,6 +2672,8 @@ class JSObject: public JSReceiver {
       FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements,
       ElementsKind to_kind, FixedArrayBase* to_elements);
 
+  void PrintInstanceMigration(FILE* file, Map* original_map, Map* new_map);
+
 #ifdef DEBUG
   // Structure for collecting spill information about JSObjects.
   class SpillInformation {
@@ -5623,6 +5625,17 @@ class Map: public HeapObject {
       Representation representation);
   MUST_USE_RESULT MaybeObject* CopyGeneralizeAllRepresentations();
 
+  void PrintGeneralization(FILE* file,
+                           int modify_index,
+                           int split,
+                           int descriptors,
+                           Representation old_representation,
+                           Representation new_representation);
+
+  // Returns the constructor name (the name (possibly, inferred name) of the
+  // function that was used to instantiate the object).
+  String* constructor_name();
+
   // Tells whether the map is attached to SharedFunctionInfo
   // (for inobject slack tracking).
   inline void set_attached_to_shared_function_info(bool value);