Revision: 14625
Author:   [email protected]
Date:     Fri May 10 10:17:50 2013
Log:      Track heap objects.

[email protected]

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

Modified:
 /branches/bleeding_edge/src/arm/lithium-arm.cc
 /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc
 /branches/bleeding_edge/src/arm/stub-cache-arm.cc
 /branches/bleeding_edge/src/flag-definitions.h
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc
 /branches/bleeding_edge/src/ia32/lithium-ia32.cc
 /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc
 /branches/bleeding_edge/src/objects-inl.h
 /branches/bleeding_edge/src/objects.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/property-details.h
 /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc
 /branches/bleeding_edge/src/x64/lithium-x64.cc
 /branches/bleeding_edge/src/x64/stub-cache-x64.cc
 /branches/bleeding_edge/test/mjsunit/elements-transition-hoisting.js

=======================================
--- /branches/bleeding_edge/src/arm/lithium-arm.cc      Fri May 10 05:45:14 2013
+++ /branches/bleeding_edge/src/arm/lithium-arm.cc      Fri May 10 10:17:50 2013
@@ -2334,7 +2334,9 @@
   LOperand* temp = needs_write_barrier_for_map ? TempRegister() : NULL;

   LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp);
-  if (FLAG_track_fields && instr->field_representation().IsSmi()) {
+  if ((FLAG_track_fields && instr->field_representation().IsSmi()) ||
+      (FLAG_track_heap_object_fields &&
+       instr->field_representation().IsHeapObject())) {
     return AssignEnvironment(result);
   }
   return result;
=======================================
--- /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri May 10 02:52:08 2013 +++ /branches/bleeding_edge/src/arm/lithium-codegen-arm.cc Fri May 10 10:17:50 2013
@@ -4229,6 +4229,12 @@
     if (!instr->hydrogen()->value()->range()->IsInSmiRange()) {
       DeoptimizeIf(vs, instr->environment());
     }
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+    Register value = ToRegister(instr->value());
+    if (!instr->hydrogen()->value()->type().IsHeapObject()) {
+      __ tst(value, Operand(kSmiTagMask));
+      DeoptimizeIf(eq, instr->environment());
+    }
   } else if (FLAG_track_double_fields && representation.IsDouble()) {
     ASSERT(transition.is_null());
     ASSERT(instr->is_in_object());
=======================================
--- /branches/bleeding_edge/src/arm/stub-cache-arm.cc Wed May 8 08:02:08 2013 +++ /branches/bleeding_edge/src/arm/stub-cache-arm.cc Fri May 10 10:17:50 2013
@@ -516,6 +516,8 @@

   if (FLAG_track_fields && representation.IsSmi()) {
     __ JumpIfNotSmi(value_reg, miss_restore_name);
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+    __ JumpIfSmi(value_reg, miss_restore_name);
   } else if (FLAG_track_double_fields && representation.IsDouble()) {
     Label do_store, heap_number;
     __ LoadRoot(scratch3, Heap::kHeapNumberMapRootIndex);
@@ -685,6 +687,8 @@
   ASSERT(!representation.IsNone());
   if (FLAG_track_fields && representation.IsSmi()) {
     __ JumpIfNotSmi(value_reg, miss_label);
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+    __ JumpIfSmi(value_reg, miss_label);
   } else if (FLAG_track_double_fields && representation.IsDouble()) {
     // Load the double storage.
     if (index < 0) {
=======================================
--- /branches/bleeding_edge/src/flag-definitions.h      Fri May 10 02:12:52 2013
+++ /branches/bleeding_edge/src/flag-definitions.h      Fri May 10 10:17:50 2013
@@ -195,7 +195,9 @@
 DEFINE_bool(pretenure_literals, true, "allocate literals in old space")
 DEFINE_bool(track_fields, true, "track fields with only smi values")
 DEFINE_bool(track_double_fields, true, "track fields with double values")
+DEFINE_bool(track_heap_object_fields, true, "track fields with heap values")
 DEFINE_implication(track_double_fields, track_fields)
+DEFINE_implication(track_heap_object_fields, track_fields)

 // Flags for data representation optimizations
DEFINE_bool(unbox_double_arrays, true, "automatically unbox arrays of doubles")
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Fri May 10 02:52:08 2013 +++ /branches/bleeding_edge/src/hydrogen-instructions.h Fri May 10 10:17:50 2013
@@ -5218,6 +5218,10 @@
       set_representation(Representation::Tagged());
} else if (FLAG_track_double_fields && field_representation.IsDouble()) {
       set_representation(field_representation);
+    } else if (FLAG_track_heap_object_fields &&
+               field_representation.IsHeapObject()) {
+      set_type(HType::NonPrimitive());
+      set_representation(Representation::Tagged());
     } else {
       set_representation(Representation::Tagged());
     }
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri May 10 02:52:08 2013 +++ /branches/bleeding_edge/src/ia32/lithium-codegen-ia32.cc Fri May 10 10:17:50 2013
@@ -4239,6 +4239,19 @@
         DeoptimizeIf(overflow, instr->environment());
       }
     }
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+    if (instr->value()->IsConstantOperand()) {
+ LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
+      if (IsInteger32(operand_value)) {
+        DeoptimizeIf(no_condition, instr->environment());
+      }
+    } else {
+      if (!instr->hydrogen()->value()->type().IsHeapObject()) {
+        Register value = ToRegister(instr->value());
+        __ test(value, Immediate(kSmiTagMask));
+        DeoptimizeIf(zero, instr->environment());
+      }
+    }
   } else if (FLAG_track_double_fields && representation.IsDouble()) {
     ASSERT(transition.is_null());
     ASSERT(instr->is_in_object());
=======================================
--- /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri May 10 05:45:14 2013 +++ /branches/bleeding_edge/src/ia32/lithium-ia32.cc Fri May 10 10:17:50 2013
@@ -2458,7 +2458,9 @@

   LStoreNamedField* result =
       new(zone()) LStoreNamedField(obj, val, temp, temp_map);
-  if (FLAG_track_fields && instr->field_representation().IsSmi()) {
+  if ((FLAG_track_fields && instr->field_representation().IsSmi()) ||
+      (FLAG_track_heap_object_fields &&
+       instr->field_representation().IsHeapObject())) {
     return AssignEnvironment(result);
   }
   return result;
=======================================
--- /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Wed May 8 08:02:08 2013 +++ /branches/bleeding_edge/src/ia32/stub-cache-ia32.cc Fri May 10 10:17:50 2013
@@ -826,6 +826,8 @@

   if (FLAG_track_fields && representation.IsSmi()) {
     __ JumpIfNotSmi(value_reg, miss_restore_name);
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+    __ JumpIfSmi(value_reg, miss_restore_name);
   } else if (FLAG_track_double_fields && representation.IsDouble()) {
     Label do_store, heap_number;
     __ AllocateHeapNumber(storage_reg, scratch1, scratch2, slow);
@@ -996,6 +998,8 @@
   ASSERT(!representation.IsNone());
   if (FLAG_track_fields && representation.IsSmi()) {
     __ JumpIfNotSmi(value_reg, miss_label);
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+    __ JumpIfSmi(value_reg, miss_label);
   } else if (FLAG_track_double_fields && representation.IsDouble()) {
     // Load the double storage.
     if (index < 0) {
=======================================
--- /branches/bleeding_edge/src/objects-inl.h   Wed May  8 08:02:08 2013
+++ /branches/bleeding_edge/src/objects-inl.h   Fri May 10 10:17:50 2013
@@ -3608,6 +3608,10 @@
     if (FLAG_track_double_fields && details.representation().IsDouble()) {
       return true;
     }
+    if (FLAG_track_heap_object_fields &&
+        details.representation().IsHeapObject()) {
+      return true;
+    }
   }
   return false;
 }
=======================================
--- /branches/bleeding_edge/src/objects.cc      Wed May  8 08:02:08 2013
+++ /branches/bleeding_edge/src/objects.cc      Fri May 10 10:17:50 2013
@@ -2137,6 +2137,7 @@
     case kSmi: return "s";
     case kDouble: return "d";
     case kInteger32: return "i";
+    case kHeapObject: return "h";
     case kExternal: return "x";
     default:
       UNREACHABLE();
@@ -2499,10 +2500,10 @@
Representation new_representation) {
   Map* old_map = this;
   DescriptorArray* old_descriptors = old_map->instance_descriptors();
-  Representation old_reprepresentation =
+  Representation old_representation =
       old_descriptors->GetDetails(modify_index).representation();

-  if (old_reprepresentation.IsNone()) {
+  if (old_representation.IsNone()) {
     UNREACHABLE();
     old_descriptors->SetRepresentation(modify_index, new_representation);
     return this;
@@ -2528,9 +2529,14 @@
     Representation updated_representation =
         updated_descriptors->GetDetails(modify_index).representation();
     if (new_representation.fits_into(updated_representation)) {
-      if (FLAG_trace_generalization) {
-        PrintF("migrating to existing map %p -> %p\n",
-               static_cast<void*>(this), static_cast<void*>(updated));
+      if (FLAG_trace_generalization &&
+          !(modify_index == 0 && new_representation.IsSmi())) {
+ 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());
       }
       return updated;
     }
@@ -2541,10 +2547,13 @@
       verbatim, valid, descriptors, old_descriptors);
   if (!maybe_descriptors->To(&new_descriptors)) return maybe_descriptors;

-  old_reprepresentation =
+  old_representation =
       new_descriptors->GetDetails(modify_index).representation();
- new_representation = new_representation.generalize(old_reprepresentation);
-  new_descriptors->SetRepresentation(modify_index, new_representation);
+  Representation updated_representation =
+      new_representation.generalize(old_representation);
+  if (!updated_representation.Equals(old_representation)) {
+ new_descriptors->SetRepresentation(modify_index, updated_representation);
+  }

   Map* split_map = root_map->FindLastMatchMap(
       verbatim, descriptors, new_descriptors);
@@ -2558,10 +2567,14 @@
   split_map->DeprecateTarget(
       old_descriptors->GetKey(descriptor), new_descriptors);

-  if (FLAG_trace_generalization) {
-    PrintF("migrating to new map %p -> %p (%i steps)\n",
+  if (FLAG_trace_generalization &&
+      !(modify_index == 0 && new_representation.IsSmi())) {
+    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);
   }

=======================================
--- /branches/bleeding_edge/src/objects.h       Wed May  8 08:02:08 2013
+++ /branches/bleeding_edge/src/objects.h       Fri May 10 10:17:50 2013
@@ -1066,6 +1066,13 @@
       return Representation::Smi();
     } else if (FLAG_track_double_fields && IsHeapNumber()) {
       return Representation::Double();
+    } else if (FLAG_track_heap_object_fields && !IsUndefined()) {
+ // Don't track undefined as heapobject because it's also used as temporary + // value for computed fields that may turn out to be Smi. That combination
+      // will go tagged, so go tagged immediately.
+      // TODO(verwaest): Change once we track computed boilerplate fields.
+      ASSERT(IsHeapObject());
+      return Representation::HeapObject();
     } else {
       return Representation::Tagged();
     }
@@ -1076,6 +1083,8 @@
       return IsSmi();
     } else if (FLAG_track_double_fields && representation.IsDouble()) {
       return IsNumber();
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+      return IsHeapObject();
     }
     return true;
   }
=======================================
--- /branches/bleeding_edge/src/property-details.h      Wed May  8 07:18:30 2013
+++ /branches/bleeding_edge/src/property-details.h      Fri May 10 10:17:50 2013
@@ -83,6 +83,7 @@
     kSmi,
     kInteger32,
     kDouble,
+    kHeapObject,
     kTagged,
     kExternal,
     kNumRepresentations
@@ -95,6 +96,7 @@
   static Representation Smi() { return Representation(kSmi); }
   static Representation Integer32() { return Representation(kInteger32); }
   static Representation Double() { return Representation(kDouble); }
+ static Representation HeapObject() { return Representation(kHeapObject); }
   static Representation External() { return Representation(kExternal); }

static Representation FromKind(Kind kind) { return Representation(kind); }
@@ -111,6 +113,7 @@
   bool is_more_general_than(const Representation& other) const {
     ASSERT(kind_ != kExternal);
     ASSERT(other.kind_ != kExternal);
+    if (IsHeapObject()) return other.IsDouble();
     return kind_ > other.kind_;
   }

@@ -119,11 +122,9 @@
   }

   Representation generalize(Representation other) {
-    if (is_more_general_than(other)) {
-      return *this;
-    } else {
-      return other;
-    }
+    if (other.fits_into(*this)) return *this;
+    if (other.is_more_general_than(*this)) return other;
+    return Representation::Tagged();
   }

   Kind kind() const { return static_cast<Kind>(kind_); }
@@ -132,6 +133,7 @@
   bool IsSmi() const { return kind_ == kSmi; }
   bool IsInteger32() const { return kind_ == kInteger32; }
   bool IsDouble() const { return kind_ == kDouble; }
+  bool IsHeapObject() const { return kind_ == kHeapObject; }
   bool IsExternal() const { return kind_ == kExternal; }
   bool IsSpecialization() const {
     return kind_ == kInteger32 || kind_ == kDouble;
=======================================
--- /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri May 10 02:52:08 2013 +++ /branches/bleeding_edge/src/x64/lithium-codegen-x64.cc Fri May 10 10:17:50 2013
@@ -3921,6 +3921,19 @@
       Register value = ToRegister(instr->value());
       __ Integer32ToSmi(value, value);
     }
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+    if (instr->value()->IsConstantOperand()) {
+ LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
+      if (IsInteger32Constant(operand_value)) {
+        DeoptimizeIf(no_condition, instr->environment());
+      }
+    } else {
+      if (!instr->hydrogen()->value()->type().IsHeapObject()) {
+        Register value = ToRegister(instr->value());
+        Condition cc = masm()->CheckSmi(value);
+        DeoptimizeIf(cc, instr->environment());
+      }
+    }
   } else if (FLAG_track_double_fields && representation.IsDouble()) {
     ASSERT(transition.is_null());
     ASSERT(instr->is_in_object());
=======================================
--- /branches/bleeding_edge/src/x64/lithium-x64.cc      Fri May 10 05:45:14 2013
+++ /branches/bleeding_edge/src/x64/lithium-x64.cc      Fri May 10 10:17:50 2013
@@ -2273,7 +2273,9 @@
       needs_write_barrier_for_map) ? TempRegister() : NULL;

   LStoreNamedField* result = new(zone()) LStoreNamedField(obj, val, temp);
-  if (FLAG_track_fields && instr->field_representation().IsSmi()) {
+  if ((FLAG_track_fields && instr->field_representation().IsSmi()) ||
+      (FLAG_track_heap_object_fields &&
+       instr->field_representation().IsHeapObject())) {
     return AssignEnvironment(result);
   }
   return result;
=======================================
--- /branches/bleeding_edge/src/x64/stub-cache-x64.cc Wed May 8 08:02:08 2013 +++ /branches/bleeding_edge/src/x64/stub-cache-x64.cc Fri May 10 10:17:50 2013
@@ -807,6 +807,8 @@

   if (FLAG_track_fields && representation.IsSmi()) {
     __ JumpIfNotSmi(value_reg, miss_restore_name);
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+    __ JumpIfSmi(value_reg, miss_restore_name);
   } else if (FLAG_track_double_fields && representation.IsDouble()) {
     Label do_store, heap_number;
     __ AllocateHeapNumber(storage_reg, scratch1, slow);
@@ -953,6 +955,8 @@
   ASSERT(!representation.IsNone());
   if (FLAG_track_fields && representation.IsSmi()) {
     __ JumpIfNotSmi(value_reg, miss_label);
+ } else if (FLAG_track_heap_object_fields && representation.IsHeapObject()) {
+    __ JumpIfSmi(value_reg, miss_label);
   } else if (FLAG_track_double_fields && representation.IsDouble()) {
     // Load the double storage.
     if (index < 0) {
=======================================
--- /branches/bleeding_edge/test/mjsunit/elements-transition-hoisting.js Fri Apr 26 08:30:41 2013 +++ /branches/bleeding_edge/test/mjsunit/elements-transition-hoisting.js Fri May 10 10:17:50 2013
@@ -129,7 +129,7 @@
   // upon can hoisted, too.
   function testExactMapHoisting3(a) {
     var object = new Object();
-    a.foo = 0;
+    a.foo = null;
     a[0] = 0;
     a[1] = 1;
     var count = 3;

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to