Move representation into HObjectAccess and remove from HLoadNamedField and HStoreName...
authortitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 25 Jul 2013 09:37:52 +0000 (09:37 +0000)
committertitzer@chromium.org <titzer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 25 Jul 2013 09:37:52 +0000 (09:37 +0000)
BUG=
R=danno@chromium.org

Review URL: https://codereview.chromium.org/18503006

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

src/code-stubs-hydrogen.cc
src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen.cc
src/hydrogen.h

index 7d9a00c..651ce0a 100644 (file)
@@ -521,11 +521,11 @@ Handle<Code> KeyedLoadFastElementStub::GenerateCode() {
 
 template<>
 HValue* CodeStubGraphBuilder<LoadFieldStub>::BuildCodeStub() {
+  Representation rep = casted_stub()->representation();
   HObjectAccess access = casted_stub()->is_inobject() ?
-      HObjectAccess::ForJSObjectOffset(casted_stub()->offset()) :
-      HObjectAccess::ForBackingStoreOffset(casted_stub()->offset());
-  return AddInstruction(BuildLoadNamedField(GetParameter(0), access,
-      casted_stub()->representation()));
+      HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
+      HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
+  return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
 }
 
 
@@ -536,11 +536,11 @@ Handle<Code> LoadFieldStub::GenerateCode() {
 
 template<>
 HValue* CodeStubGraphBuilder<KeyedLoadFieldStub>::BuildCodeStub() {
+  Representation rep = casted_stub()->representation();
   HObjectAccess access = casted_stub()->is_inobject() ?
-      HObjectAccess::ForJSObjectOffset(casted_stub()->offset()) :
-      HObjectAccess::ForBackingStoreOffset(casted_stub()->offset());
-  return AddInstruction(BuildLoadNamedField(GetParameter(0), access,
-      casted_stub()->representation()));
+      HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
+      HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
+  return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
 }
 
 
index a4d7d16..707e818 100644 (file)
@@ -4358,7 +4358,8 @@ HObjectAccess HObjectAccess::ForFixedArrayHeader(int offset) {
 }
 
 
-HObjectAccess HObjectAccess::ForJSObjectOffset(int offset) {
+HObjectAccess HObjectAccess::ForJSObjectOffset(int offset,
+    Representation representation) {
   ASSERT(offset >= 0);
   Portion portion = kInobject;
 
@@ -4367,7 +4368,7 @@ HObjectAccess HObjectAccess::ForJSObjectOffset(int offset) {
   } else if (offset == JSObject::kMapOffset) {
     portion = kMaps;
   }
-  return HObjectAccess(portion, offset, Handle<String>::null());
+  return HObjectAccess(portion, offset, representation);
 }
 
 
@@ -4382,13 +4383,14 @@ HObjectAccess HObjectAccess::ForJSArrayOffset(int offset) {
   } else if (offset == JSObject::kMapOffset) {
     portion = kMaps;
   }
-  return HObjectAccess(portion, offset, Handle<String>::null());
+  return HObjectAccess(portion, offset);
 }
 
 
-HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset) {
+HObjectAccess HObjectAccess::ForBackingStoreOffset(int offset,
+    Representation representation) {
   ASSERT(offset >= 0);
-  return HObjectAccess(kBackingStore, offset, Handle<String>::null());
+  return HObjectAccess(kBackingStore, offset, representation);
 }
 
 
@@ -4396,30 +4398,35 @@ HObjectAccess HObjectAccess::ForField(Handle<Map> map,
     LookupResult *lookup, Handle<String> name) {
   ASSERT(lookup->IsField() || lookup->IsTransitionToField(*map));
   int index;
+  Representation representation;
   if (lookup->IsField()) {
     index = lookup->GetLocalFieldIndexFromMap(*map);
+    representation = lookup->representation();
   } else {
     Map* transition = lookup->GetTransitionMapFromMap(*map);
     int descriptor = transition->LastAdded();
     index = transition->instance_descriptors()->GetFieldIndex(descriptor) -
         map->inobject_properties();
+    PropertyDetails details =
+        transition->instance_descriptors()->GetDetails(descriptor);
+    representation = details.representation();
   }
   if (index < 0) {
     // Negative property indices are in-object properties, indexed
     // from the end of the fixed part of the object.
     int offset = (index * kPointerSize) + map->instance_size();
-    return HObjectAccess(kInobject, offset);
+    return HObjectAccess(kInobject, offset, representation);
   } else {
     // Non-negative property indices are in the properties array.
     int offset = (index * kPointerSize) + FixedArray::kHeaderSize;
-    return HObjectAccess(kBackingStore, offset, name);
+    return HObjectAccess(kBackingStore, offset, representation, name);
   }
 }
 
 
 HObjectAccess HObjectAccess::ForCellPayload(Isolate* isolate) {
   return HObjectAccess(
-      kInobject, Cell::kValueOffset,
+      kInobject, Cell::kValueOffset, Representation::Tagged(),
       Handle<String>(isolate->heap()->cell_value_string()));
 }
 
index 117bcb2..b43efc8 100644 (file)
@@ -5486,20 +5486,32 @@ class HObjectAccess {
     return OffsetField::decode(value_);
   }
 
+  inline Representation representation() const {
+    return Representation::FromKind(RepresentationField::decode(value_));
+  }
+
   inline Handle<String> name() const {
     return name_;
   }
 
+  inline HObjectAccess WithRepresentation(Representation representation) {
+    return HObjectAccess(portion(), offset(), representation, name());
+  }
+
   static HObjectAccess ForHeapNumberValue() {
-    return HObjectAccess(kDouble, HeapNumber::kValueOffset);
+    return HObjectAccess(
+        kDouble, HeapNumber::kValueOffset, Representation::Double());
   }
 
   static HObjectAccess ForElementsPointer() {
     return HObjectAccess(kElementsPointer, JSObject::kElementsOffset);
   }
 
-  static HObjectAccess ForArrayLength() {
-    return HObjectAccess(kArrayLengths, JSArray::kLengthOffset);
+  static HObjectAccess ForArrayLength(ElementsKind elements_kind) {
+    return HObjectAccess(
+        kArrayLengths, JSArray::kLengthOffset,
+        IsFastElementsKind(elements_kind) && FLAG_track_fields ?
+        Representation::Smi() : Representation::Tagged());
   }
 
   static HObjectAccess ForAllocationSiteTransitionInfo() {
@@ -5511,7 +5523,10 @@ class HObjectAccess {
   }
 
   static HObjectAccess ForFixedArrayLength() {
-    return HObjectAccess(kArrayLengths, FixedArray::kLengthOffset);
+    return HObjectAccess(
+        kArrayLengths, FixedArray::kLengthOffset,
+        FLAG_track_fields ?
+        Representation::Smi() : Representation::Tagged());
   }
 
   static HObjectAccess ForPropertiesPointer() {
@@ -5542,13 +5557,15 @@ class HObjectAccess {
   static HObjectAccess ForFixedArrayHeader(int offset);
 
   // Create an access to an in-object property in a JSObject.
-  static HObjectAccess ForJSObjectOffset(int offset);
+  static HObjectAccess ForJSObjectOffset(int offset,
+      Representation representation = Representation::Tagged());
 
   // Create an access to an in-object property in a JSArray.
   static HObjectAccess ForJSArrayOffset(int offset);
 
   // Create an access to the backing store of an object.
-  static HObjectAccess ForBackingStoreOffset(int offset);
+  static HObjectAccess ForBackingStoreOffset(int offset,
+      Representation representation = Representation::Tagged());
 
   // Create an access to a resolved field (in-object or backing store).
   static HObjectAccess ForField(Handle<Map> map,
@@ -5578,17 +5595,23 @@ class HObjectAccess {
   };
 
   HObjectAccess(Portion portion, int offset,
-      Handle<String> name = Handle<String>::null())
-    : value_(PortionField::encode(portion) | OffsetField::encode(offset)),
+                Representation representation = Representation::Tagged(),
+                Handle<String> name = Handle<String>::null())
+    : value_(PortionField::encode(portion) |
+             RepresentationField::encode(representation.kind()) |
+             OffsetField::encode(offset)),
       name_(name) {
-    ASSERT(this->offset() == offset);    // offset should decode correctly
-    ASSERT(this->portion() == portion);  // portion should decode correctly
+    // assert that the fields decode correctly
+    ASSERT(this->offset() == offset);
+    ASSERT(this->portion() == portion);
+    ASSERT(RepresentationField::decode(value_) == representation.kind());
   }
 
   class PortionField : public BitField<Portion, 0, 3> {};
-  class OffsetField : public BitField<int, 3, 29> {};
+  class RepresentationField : public BitField<Representation::Kind, 3, 3> {};
+  class OffsetField : public BitField<int, 6, 26> {};
 
-  uint32_t value_;  // encodes both portion and offset
+  uint32_t value_;  // encodes portion, representation, and offset
   Handle<String> name_;
 
   friend class HLoadNamedField;
@@ -5636,22 +5659,20 @@ class HLoadNamedField: public HTemplateInstruction<2> {
  public:
   HLoadNamedField(HValue* object,
                   HObjectAccess access,
-                  HValue* typecheck = NULL,
-                  Representation field_representation
-                      = Representation::Tagged())
-      : access_(access),
-        field_representation_(field_representation) {
+                  HValue* typecheck = NULL)
+      : access_(access) {
     ASSERT(object != NULL);
     SetOperandAt(0, object);
     SetOperandAt(1, typecheck != NULL ? typecheck : object);
 
-    if (FLAG_track_fields && field_representation.IsSmi()) {
+    Representation representation = access.representation();
+    if (representation.IsSmi()) {
       set_type(HType::Smi());
-      set_representation(field_representation);
-    } else if (FLAG_track_double_fields && field_representation.IsDouble()) {
-      set_representation(field_representation);
+      set_representation(representation);
+    } else if (representation.IsDouble()) {
+      set_representation(representation);
     } else if (FLAG_track_heap_object_fields &&
-               field_representation.IsHeapObject()) {
+               representation.IsHeapObject()) {
       set_type(HType::NonPrimitive());
       set_representation(Representation::Tagged());
     } else {
@@ -5668,7 +5689,9 @@ class HLoadNamedField: public HTemplateInstruction<2> {
 
   bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
   HObjectAccess access() const { return access_; }
-  Representation field_representation() const { return representation_; }
+  Representation field_representation() const {
+      return access_.representation();
+  }
 
   virtual bool HasEscapingOperandAt(int index) { return false; }
   virtual Representation RequiredInputRepresentation(int index) {
@@ -5688,7 +5711,6 @@ class HLoadNamedField: public HTemplateInstruction<2> {
   virtual bool IsDeletable() const { return true; }
 
   HObjectAccess access_;
-  Representation field_representation_;
 };
 
 
@@ -5988,11 +6010,8 @@ class HStoreNamedField: public HTemplateInstruction<2> {
  public:
   HStoreNamedField(HValue* obj,
                    HObjectAccess access,
-                   HValue* val,
-                   Representation field_representation
-                       = Representation::Tagged())
+                   HValue* val)
       : access_(access),
-        field_representation_(field_representation),
         transition_(),
         transition_unique_id_(),
         new_space_dominator_(NULL),
@@ -6006,12 +6025,10 @@ class HStoreNamedField: public HTemplateInstruction<2> {
 
   virtual bool HasEscapingOperandAt(int index) { return index == 1; }
   virtual Representation RequiredInputRepresentation(int index) {
-    if (FLAG_track_double_fields &&
-        index == 1 && field_representation_.IsDouble()) {
-      return field_representation_;
-    } else if (FLAG_track_fields &&
-               index == 1 && field_representation_.IsSmi()) {
-      return field_representation_;
+    if (index == 1 && field_representation().IsDouble()) {
+      return field_representation();
+    } else if (index == 1 && field_representation().IsSmi()) {
+      return field_representation();
     }
     return Representation::Tagged();
   }
@@ -6043,13 +6060,12 @@ class HStoreNamedField: public HTemplateInstruction<2> {
   HValue* new_space_dominator() const { return new_space_dominator_; }
 
   bool NeedsWriteBarrier() {
-    ASSERT(!(FLAG_track_double_fields && field_representation_.IsDouble()) ||
+    ASSERT(!(FLAG_track_double_fields && field_representation().IsDouble()) ||
            transition_.is_null());
     if (IsSkipWriteBarrier()) return false;
-    return (!FLAG_track_fields || !field_representation_.IsSmi()) &&
-        // If there is a transition, a new storage object needs to be allocated.
-        !(FLAG_track_double_fields && field_representation_.IsDouble()) &&
-        StoringValueNeedsWriteBarrier(value()) &&
+    if (field_representation().IsDouble()) return false;
+    if (field_representation().IsSmi()) return false;
+    return StoringValueNeedsWriteBarrier(value()) &&
         ReceiverObjectNeedsWriteBarrier(object(), new_space_dominator());
   }
 
@@ -6063,12 +6079,11 @@ class HStoreNamedField: public HTemplateInstruction<2> {
   }
 
   Representation field_representation() const {
-    return field_representation_;
+    return access_.representation();
   }
 
  private:
   HObjectAccess access_;
-  Representation field_representation_;
   Handle<Map> transition_;
   UniqueValueId transition_unique_id_;
   HValue* new_space_dominator_;
index 7a761a3..0aae861 100644 (file)
@@ -1095,10 +1095,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object,
         HAdd::New(zone, context, key, graph_->GetConstant1()));
     new_length->ClearFlag(HValue::kCanOverflow);
 
-    Representation representation = IsFastElementsKind(kind)
-        ? Representation::Smi() : Representation::Tagged();
-    AddStore(object, HObjectAccess::ForArrayLength(), new_length,
-        representation);
+    AddStore(object, HObjectAccess::ForArrayLength(kind), new_length);
   }
 
   length_checker.Else();
@@ -1166,10 +1163,8 @@ void HGraphBuilder::BuildTransitionElementsKind(HValue* object,
     HInstruction* elements_length = AddLoadFixedArrayLength(elements);
 
     HInstruction* array_length = is_jsarray
-        ? AddLoad(object, HObjectAccess::ForArrayLength(),
-                  NULL, Representation::Smi())
+        ? AddLoad(object, HObjectAccess::ForArrayLength(from_kind), NULL)
         : elements_length;
-    array_length->set_type(HType::Smi());
 
     BuildGrowElementsCapacity(object, elements, from_kind, to_kind,
                               array_length, elements_length);
@@ -1217,8 +1212,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
   }
   HInstruction* length = NULL;
   if (is_js_array) {
-    length = AddLoad(object, HObjectAccess::ForArrayLength(), mapcheck,
-        Representation::Smi());
+    length = AddLoad(object, HObjectAccess::ForArrayLength(elements_kind),
+        mapcheck);
   } else {
     length = AddLoadFixedArrayLength(elements);
   }
@@ -1334,10 +1329,7 @@ void HGraphBuilder::BuildInitializeElementsHeader(HValue* elements,
       : factory->fixed_array_map();
 
   AddStoreMapConstant(elements, map);
-  Representation representation = IsFastElementsKind(kind)
-      ? Representation::Smi() : Representation::Tagged();
-  AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity,
-      representation);
+  AddStore(elements, HObjectAccess::ForFixedArrayLength(), capacity);
 }
 
 
@@ -1354,6 +1346,7 @@ HValue* HGraphBuilder::BuildAllocateElementsAndInitializeElementsHeader(
 HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
     HValue* array_map,
     AllocationSiteMode mode,
+    ElementsKind elements_kind,
     HValue* allocation_site_payload,
     HValue* length_field) {
 
@@ -1364,7 +1357,7 @@ HInnerAllocatedObject* HGraphBuilder::BuildJSArrayHeader(HValue* array,
 
   HObjectAccess access = HObjectAccess::ForPropertiesPointer();
   AddStore(array, access, empty_fixed_array);
-  AddStore(array, HObjectAccess::ForArrayLength(), length_field);
+  AddStore(array, HObjectAccess::ForArrayLength(elements_kind), length_field);
 
   if (mode == TRACK_ALLOCATION_SITE) {
     BuildCreateAllocationMemento(array,
@@ -1471,10 +1464,7 @@ HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
 
 
 HLoadNamedField* HGraphBuilder::AddLoadFixedArrayLength(HValue* object) {
-  HLoadNamedField* instr = AddLoad(object, HObjectAccess::ForFixedArrayLength(),
-                                   NULL, Representation::Smi());
-  instr->set_type(HType::Smi());
-  return instr;
+  return AddLoad(object, HObjectAccess::ForFixedArrayLength());
 }
 
 
@@ -1845,11 +1835,8 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitMapCode(HValue* context) {
     // No need for a context lookup if the kind_ matches the initial
     // map, because we can just load the map in that case.
     HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
-    HInstruction* load =
-        builder()->BuildLoadNamedField(constructor_function_,
-                                       access,
-                                       Representation::Tagged());
-    return builder()->AddInstruction(load);
+    return builder()->AddInstruction(
+        builder()->BuildLoadNamedField(constructor_function_, access));
   }
 
   HInstruction* native_context = builder()->BuildGetNativeContext(context);
@@ -1870,9 +1857,7 @@ HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() {
   // Find the map near the constructor function
   HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
   return builder()->AddInstruction(
-      builder()->BuildLoadNamedField(constructor_function_,
-                                     access,
-                                     Representation::Tagged()));
+      builder()->BuildLoadNamedField(constructor_function_, access));
 }
 
 
@@ -1960,6 +1945,7 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
   elements_location_ = builder()->BuildJSArrayHeader(new_object,
                                                      map,
                                                      mode_,
+                                                     kind_,
                                                      allocation_site_payload_,
                                                      length_field);
 
@@ -1977,17 +1963,15 @@ HValue* HGraphBuilder::JSArrayBuilder::AllocateArray(HValue* size_in_bytes,
 
 HStoreNamedField* HGraphBuilder::AddStore(HValue *object,
                                           HObjectAccess access,
-                                          HValue *val,
-                                          Representation representation) {
-  return Add<HStoreNamedField>(object, access, val, representation);
+                                          HValue *val) {
+  return Add<HStoreNamedField>(object, access, val);
 }
 
 
 HLoadNamedField* HGraphBuilder::AddLoad(HValue *object,
                                         HObjectAccess access,
-                                        HValue *typecheck,
-                                        Representation representation) {
-  return Add<HLoadNamedField>(object, access, typecheck, representation);
+                                        HValue *typecheck) {
+  return Add<HLoadNamedField>(object, access, typecheck);
 }
 
 
@@ -4532,20 +4516,6 @@ static bool ComputeLoadStoreField(Handle<Map> type,
 }
 
 
-static Representation ComputeLoadStoreRepresentation(Handle<Map> type,
-                                                     LookupResult* lookup) {
-  if (lookup->IsField()) {
-    return lookup->representation();
-  } else {
-    Map* transition = lookup->GetTransitionMapFromMap(*type);
-    int descriptor = transition->LastAdded();
-    PropertyDetails details =
-        transition->instance_descriptors()->GetDetails(descriptor);
-    return details.representation();
-  }
-}
-
-
 void HOptimizedGraphBuilder::AddCheckMap(HValue* object, Handle<Map> map) {
   BuildCheckHeapObject(object);
   AddInstruction(HCheckMaps::New(object, map, zone(), top_info()));
@@ -4597,33 +4567,33 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
   }
 
   HObjectAccess field_access = HObjectAccess::ForField(map, lookup, name);
-  Representation representation = ComputeLoadStoreRepresentation(map, lookup);
   bool transition_to_field = lookup->IsTransitionToField(*map);
 
   HStoreNamedField *instr;
-  if (FLAG_track_double_fields && representation.IsDouble()) {
+  if (FLAG_track_double_fields && field_access.representation().IsDouble()) {
+    HObjectAccess heap_number_access =
+        field_access.WithRepresentation(Representation::Tagged());
     if (transition_to_field) {
       // The store requires a mutable HeapNumber to be allocated.
       NoObservableSideEffectsScope no_side_effects(this);
       HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize);
-      HInstruction* double_box = Add<HAllocate>(
+      HInstruction* heap_number = Add<HAllocate>(
           environment()->LookupContext(), heap_number_size,
           HType::HeapNumber(), HAllocate::CAN_ALLOCATE_IN_NEW_SPACE);
-      AddStoreMapConstant(double_box, isolate()->factory()->heap_number_map());
-      AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
-          value, Representation::Double());
-      instr = new(zone()) HStoreNamedField(object, field_access, double_box);
+      AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map());
+      AddStore(heap_number, HObjectAccess::ForHeapNumberValue(), value);
+      instr = new(zone()) HStoreNamedField(
+          object, heap_number_access, heap_number);
     } else {
       // Already holds a HeapNumber; load the box and write its value field.
-      HInstruction* double_box = AddLoad(object, field_access);
-      double_box->set_type(HType::HeapNumber());
-      instr = new(zone()) HStoreNamedField(double_box,
-          HObjectAccess::ForHeapNumberValue(), value, Representation::Double());
+      HInstruction* heap_number = AddLoad(object, heap_number_access);
+      heap_number->set_type(HType::HeapNumber());
+      instr = new(zone()) HStoreNamedField(heap_number,
+          HObjectAccess::ForHeapNumberValue(), value);
     }
   } else {
-    // This is a non-double store.
-    instr = new(zone()) HStoreNamedField(
-        object, field_access, value, representation);
+    // This is a normal store.
+    instr = new(zone()) HStoreNamedField(object, field_access, value);
   }
 
   if (transition_to_field) {
@@ -4690,20 +4660,18 @@ HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
 
   LookupResult lookup(isolate());
   int count;
-  Representation representation = Representation::None();
   HObjectAccess access = HObjectAccess::ForMap();  // initial value unused.
   for (count = 0; count < types->length(); ++count) {
     Handle<Map> map = types->at(count);
     if (!ComputeLoadStoreField(map, name, &lookup, false)) break;
 
     HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
-    Representation new_representation =
-        ComputeLoadStoreRepresentation(map, &lookup);
 
     if (count == 0) {
       // First time through the loop; set access and representation.
       access = new_access;
-    } else if (!representation.IsCompatibleForLoad(new_representation)) {
+    } else if (!access.representation().IsCompatibleForLoad(
+        new_access.representation())) {
       // Representations did not match.
       break;
     } else if (access.offset() != new_access.offset()) {
@@ -4713,14 +4681,15 @@ HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
       // In-objectness did not match.
       break;
     }
-    representation = representation.generalize(new_representation);
+    access = access.WithRepresentation(
+        access.representation().generalize(new_access.representation()));
   }
 
   if (count == types->length()) {
     // Everything matched; can use monomorphic load.
     BuildCheckHeapObject(object);
     AddInstruction(HCheckMaps::New(object, types, zone()));
-    return BuildLoadNamedField(object, access, representation);
+    return BuildLoadNamedField(object, access);
   }
 
   if (count != 0) return NULL;
@@ -4742,14 +4711,14 @@ HInstruction* HOptimizedGraphBuilder::TryLoadPolymorphicAsMonomorphic(
 
   BuildCheckHeapObject(object);
   AddInstruction(HCheckMaps::New(object, types, zone()));
+
   Handle<JSObject> holder(lookup.holder());
   Handle<Map> holder_map(holder->map());
   AddInstruction(new(zone()) HCheckPrototypeMaps(
       Handle<JSObject>::cast(prototype), holder, zone(), top_info()));
   HValue* holder_value = AddInstruction(new(zone()) HConstant(holder));
   return BuildLoadNamedField(holder_value,
-      HObjectAccess::ForField(holder_map, &lookup, name),
-      ComputeLoadStoreRepresentation(map, &lookup));
+      HObjectAccess::ForField(holder_map, &lookup, name));
 }
 
 
@@ -4798,8 +4767,7 @@ bool HOptimizedGraphBuilder::TryStorePolymorphicAsMonomorphic(
     ASSERT(!map->is_observed());
 
     HObjectAccess new_access = HObjectAccess::ForField(map, &lookup, name);
-    Representation new_representation =
-        ComputeLoadStoreRepresentation(map, &lookup);
+    Representation new_representation = new_access.representation();
 
     if (count == 0) {
       // First time through the loop; set access and representation.
@@ -5392,24 +5360,18 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
 }
 
 
-HLoadNamedField* HGraphBuilder::BuildLoadNamedField(
-    HValue* object,
-    HObjectAccess access,
-    Representation representation) {
-  bool load_double = false;
-  if (representation.IsDouble()) {
-    representation = Representation::Tagged();
-    load_double = FLAG_track_double_fields;
-  }
-  HLoadNamedField* field =
-      new(zone()) HLoadNamedField(object, access, NULL, representation);
-  if (load_double) {
-    AddInstruction(field);
-    field->set_type(HType::HeapNumber());
-    return new(zone()) HLoadNamedField(field,
-        HObjectAccess::ForHeapNumberValue(), NULL, Representation::Double());
+HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
+    HObjectAccess access) {
+  if (FLAG_track_double_fields && access.representation().IsDouble()) {
+    // load the heap number
+    HLoadNamedField* heap_number =
+        AddLoad(object, access.WithRepresentation(Representation::Tagged()));
+    heap_number->set_type(HType::HeapNumber());
+    // load the double value from it
+    return new(zone()) HLoadNamedField(heap_number,
+        HObjectAccess::ForHeapNumberValue(), NULL);
   }
-  return field;
+  return new(zone()) HLoadNamedField(object, access, NULL);
 }
 
 
@@ -5449,7 +5411,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
     if (map->instance_type() == JS_ARRAY_TYPE) {
       AddCheckMapsWithTransitions(object, map);
       return new(zone()) HLoadNamedField(object,
-          HObjectAccess::ForArrayLength());
+          HObjectAccess::ForArrayLength(map->elements_kind()));
     }
   }
 
@@ -5458,8 +5420,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
   if (lookup.IsField()) {
     AddCheckMap(object, map);
     return BuildLoadNamedField(object,
-        HObjectAccess::ForField(map, &lookup, name),
-        ComputeLoadStoreRepresentation(map, &lookup));
+        HObjectAccess::ForField(map, &lookup, name));
   }
 
   // Handle a load of a constant known function.
@@ -5479,8 +5440,7 @@ HInstruction* HOptimizedGraphBuilder::BuildLoadNamedMonomorphic(
     Add<HCheckPrototypeMaps>(prototype, holder, zone(), top_info());
     HValue* holder_value = Add<HConstant>(holder);
     return BuildLoadNamedField(holder_value,
-        HObjectAccess::ForField(holder_map, &lookup, name),
-        ComputeLoadStoreRepresentation(map, &lookup));
+        HObjectAccess::ForField(holder_map, &lookup, name));
   }
 
   // Handle a load of a constant function somewhere in the prototype chain.
@@ -5702,9 +5662,8 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
             zone(), top_info(), mapcompare));
       }
       if (map->IsJSArray()) {
-        HInstruction* length = AddLoad(object, HObjectAccess::ForArrayLength(),
-                                       mapcompare, Representation::Smi());
-        length->set_type(HType::Smi());
+        HInstruction* length = AddLoad(
+            object, HObjectAccess::ForArrayLength(elements_kind), mapcompare);
         checked_key = Add<HBoundsCheck>(key, length);
       } else {
         HInstruction* length = AddLoadFixedArrayLength(elements);
@@ -8501,11 +8460,8 @@ HValue* HOptimizedGraphBuilder::BuildEmitObjectHeader(
     HInstruction* length = Add<HConstant>(length_field);
 
     ASSERT(boilerplate_array->length()->IsSmi());
-    Representation representation =
-        IsFastElementsKind(boilerplate_array->GetElementsKind())
-        ? Representation::Smi() : Representation::Tagged();
-    AddStore(object_header, HObjectAccess::ForArrayLength(),
-        length, representation);
+    AddStore(object_header, HObjectAccess::ForArrayLength(
+        boilerplate_array->GetElementsKind()), length);
   }
 
   return result;
@@ -8571,7 +8527,7 @@ void HOptimizedGraphBuilder::BuildEmitInObjectProperties(
         AddStoreMapConstant(double_box,
             isolate()->factory()->heap_number_map());
         AddStore(double_box, HObjectAccess::ForHeapNumberValue(),
-            value_instruction, Representation::Double());
+            value_instruction);
         value_instruction = double_box;
       }
 
index e64947d..46d23da 100644 (file)
@@ -1094,8 +1094,7 @@ class HGraphBuilder {
   HLoadNamedField* AddLoad(
       HValue *object,
       HObjectAccess access,
-      HValue *typecheck = NULL,
-      Representation representation = Representation::Tagged());
+      HValue *typecheck = NULL);
 
   HLoadNamedField* BuildLoadNamedField(
       HValue* object,
@@ -1120,16 +1119,10 @@ class HGraphBuilder {
       LoadKeyedHoleMode load_mode,
       KeyedAccessStoreMode store_mode);
 
-  HStoreNamedField* AddStore(
-      HValue *object,
-      HObjectAccess access,
-      HValue *val,
-      Representation representation = Representation::Tagged());
-
+  HLoadNamedField* BuildLoadNamedField(HValue* object, HObjectAccess access);
+  HStoreNamedField* AddStore(HValue *object, HObjectAccess access, HValue *val);
   HStoreNamedField* AddStoreMapConstant(HValue *object, Handle<Map>);
-
   HLoadNamedField* AddLoadElements(HValue *object, HValue *typecheck = NULL);
-
   HLoadNamedField* AddLoadFixedArrayLength(HValue *object);
 
   HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin, HValue* context);
@@ -1389,6 +1382,7 @@ class HGraphBuilder {
   HInnerAllocatedObject* BuildJSArrayHeader(HValue* array,
                                             HValue* array_map,
                                             AllocationSiteMode mode,
+                                            ElementsKind elements_kind,
                                             HValue* allocation_site_payload,
                                             HValue* length_field);