Get rid of HStringLength.
authorbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 1 Aug 2013 08:42:47 +0000 (08:42 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Thu, 1 Aug 2013 08:42:47 +0000 (08:42 +0000)
Use HLoadNamedField to load the string length field instead.

Depends on: https://codereview.chromium.org/21488002

R=svenpanne@chromium.org

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

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

16 files changed:
src/arm/lithium-arm.cc
src/arm/lithium-arm.h
src/arm/lithium-codegen-arm.cc
src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen.cc
src/hydrogen.h
src/ia32/lithium-codegen-ia32.cc
src/ia32/lithium-ia32.cc
src/ia32/lithium-ia32.h
src/mips/lithium-codegen-mips.cc
src/mips/lithium-mips.cc
src/mips/lithium-mips.h
src/x64/lithium-codegen-x64.cc
src/x64/lithium-x64.cc
src/x64/lithium-x64.h

index 04e26bb..1857b4a 100644 (file)
@@ -2393,12 +2393,6 @@ LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
 }
 
 
-LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
-  LOperand* string = UseRegisterAtStart(instr->value());
-  return DefineAsRegister(new(zone()) LStringLength(string));
-}
-
-
 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
   info()->MarkAsDeferredCalling();
   LOperand* size = instr->size()->IsConstant()
index 42bec14..c568ad6 100644 (file)
@@ -175,7 +175,6 @@ class LCodeGen;
   V(StringCharCodeAt)                           \
   V(StringCharFromCode)                         \
   V(StringCompareAndBranch)                     \
-  V(StringLength)                               \
   V(SubI)                                       \
   V(RSubI)                                      \
   V(TaggedToI)                                  \
@@ -2314,19 +2313,6 @@ class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> {
 };
 
 
-class LStringLength: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LStringLength(LOperand* string) {
-    inputs_[0] = string;
-  }
-
-  LOperand* string() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
-  DECLARE_HYDROGEN_ACCESSOR(StringLength)
-};
-
-
 class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
  public:
   explicit LCheckFunction(LOperand* value) {
index a92604e..cf1e7c7 100644 (file)
@@ -4645,13 +4645,6 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
 }
 
 
-void LCodeGen::DoStringLength(LStringLength* instr) {
-  Register string = ToRegister(instr->string());
-  Register result = ToRegister(instr->result());
-  __ ldr(result, FieldMemOperand(string, String::kLengthOffset));
-}
-
-
 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
   LOperand* input = instr->value();
   ASSERT(input->IsRegister() || input->IsStackSlot());
index 5f08f67..3eb4aa6 100644 (file)
@@ -3050,6 +3050,14 @@ Range* HShl::InferRange(Zone* zone) {
 }
 
 
+Range* HLoadNamedField::InferRange(Zone* zone) {
+  if (access().IsStringLength()) {
+    return new(zone) Range(0, String::kMaxLength);
+  }
+  return HValue::InferRange(zone);
+}
+
+
 Range* HLoadKeyed::InferRange(Zone* zone) {
   switch (elements_kind()) {
     case EXTERNAL_PIXEL_ELEMENTS:
@@ -3937,17 +3945,6 @@ HInstruction* HStringCharFromCode::New(
 }
 
 
-HInstruction* HStringLength::New(Zone* zone, HValue* context, HValue* string) {
-  if (FLAG_fold_constants && string->IsConstant()) {
-    HConstant* c_string = HConstant::cast(string);
-    if (c_string->HasStringValue()) {
-      return HConstant::New(zone, context, c_string->StringValue()->length());
-    }
-  }
-  return new(zone) HStringLength(string);
-}
-
-
 HInstruction* HUnaryMathOperation::New(
     Zone* zone, HValue* context, HValue* value, BuiltinFunctionId op) {
   do {
@@ -4425,6 +4422,10 @@ void HObjectAccess::SetGVNFlags(HValue *instr, bool is_store) {
       instr->SetGVNFlag(is_store
           ? kChangesArrayLengths : kDependsOnArrayLengths);
       break;
+    case kStringLengths:
+      instr->SetGVNFlag(is_store
+          ? kChangesStringLengths : kDependsOnStringLengths);
+      break;
     case kInobject:
       instr->SetGVNFlag(is_store
           ? kChangesInobjectFields : kDependsOnInobjectFields);
@@ -4458,6 +4459,7 @@ void HObjectAccess::PrintTo(StringStream* stream) {
 
   switch (portion()) {
     case kArrayLengths:
+    case kStringLengths:
       stream->Add("%length");
       break;
     case kElementsPointer:
index 5565e25..eac5173 100644 (file)
@@ -178,7 +178,6 @@ class LChunkBuilder;
   V(StringCharCodeAt)                          \
   V(StringCharFromCode)                        \
   V(StringCompareAndBranch)                    \
-  V(StringLength)                              \
   V(Sub)                                       \
   V(ThisFunction)                              \
   V(Throw)                                     \
@@ -200,6 +199,7 @@ class LChunkBuilder;
 #define GVN_UNTRACKED_FLAG_LIST(V)             \
   V(ArrayElements)                             \
   V(ArrayLengths)                              \
+  V(StringLengths)                             \
   V(BackingStoreFields)                        \
   V(Calls)                                     \
   V(ContextSlots)                              \
@@ -5840,6 +5840,10 @@ class HObjectAccess {
     return portion() == kExternalMemory;
   }
 
+  inline bool IsStringLength() const {
+    return portion() == kStringLengths;
+  }
+
   inline int offset() const {
     return OffsetField::decode(value_);
   }
@@ -5893,6 +5897,14 @@ class HObjectAccess {
         FLAG_track_fields ? Representation::Smi() : Representation::Tagged());
   }
 
+  static HObjectAccess ForStringLength() {
+    STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
+    return HObjectAccess(
+        kStringLengths,
+        String::kLengthOffset,
+        FLAG_track_fields ? Representation::Smi() : Representation::Tagged());
+  }
+
   static HObjectAccess ForPropertiesPointer() {
     return HObjectAccess(kInobject, JSObject::kPropertiesOffset);
   }
@@ -5956,6 +5968,7 @@ class HObjectAccess {
   enum Portion {
     kMaps,             // map of an object
     kArrayLengths,     // the length of an array
+    kStringLengths,    // the length of a string
     kElementsPointer,  // elements pointer
     kBackingStore,     // some field in the backing store
     kDouble,           // some double field
@@ -6018,6 +6031,7 @@ class HLoadNamedField: public HTemplateInstruction<2> {
     }
     return Representation::Tagged();
   }
+  virtual Range* InferRange(Zone* zone);
   virtual void PrintDataTo(StringStream* stream);
 
   DECLARE_CONCRETE_INSTRUCTION(LoadNamedField)
@@ -6853,36 +6867,6 @@ class HStringCharFromCode: public HTemplateInstruction<2> {
 };
 
 
-class HStringLength: public HUnaryOperation {
- public:
-  static HInstruction* New(Zone* zone, HValue* context, HValue* string);
-
-  virtual Representation RequiredInputRepresentation(int index) {
-    return Representation::Tagged();
-  }
-
-  DECLARE_CONCRETE_INSTRUCTION(StringLength)
-
- protected:
-  virtual bool DataEquals(HValue* other) { return true; }
-
-  virtual Range* InferRange(Zone* zone) {
-    return new(zone) Range(0, String::kMaxLength);
-  }
-
- private:
-  explicit HStringLength(HValue* string)
-      : HUnaryOperation(string, HType::Smi()) {
-    STATIC_ASSERT(String::kMaxLength <= Smi::kMaxValue);
-    set_representation(Representation::Tagged());
-    SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnMaps);
-  }
-
-  virtual bool IsDeletable() const { return true; }
-};
-
-
 template <int V>
 class HMaterializedLiteral: public HTemplateInstruction<V> {
  public:
index 9997f13..34ecfa3 100644 (file)
@@ -5314,7 +5314,8 @@ void HOptimizedGraphBuilder::VisitThrow(Throw* expr) {
 
 
 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
-                                                    HObjectAccess access) {
+                                                    HObjectAccess access,
+                                                    HValue* typecheck) {
   if (FLAG_track_double_fields && access.representation().IsDouble()) {
     // load the heap number
     HLoadNamedField* heap_number = Add<HLoadNamedField>(
@@ -5322,9 +5323,23 @@ HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
     heap_number->set_type(HType::HeapNumber());
     // load the double value from it
     return New<HLoadNamedField>(heap_number,
-                                HObjectAccess::ForHeapNumberValue());
+                                HObjectAccess::ForHeapNumberValue(),
+                                typecheck);
   }
-  return New<HLoadNamedField>(object, access);
+  return New<HLoadNamedField>(object, access, typecheck);
+}
+
+
+HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object,
+                                                   HValue* typecheck) {
+  if (FLAG_fold_constants && object->IsConstant()) {
+    HConstant* constant = HConstant::cast(object);
+    if (constant->HasStringValue()) {
+      return New<HConstant>(constant->StringValue()->length());
+    }
+  }
+  return BuildLoadNamedField(
+      object, HObjectAccess::ForStringLength(), typecheck);
 }
 
 
@@ -5808,8 +5823,9 @@ void HOptimizedGraphBuilder::VisitProperty(Property* expr) {
   if (expr->IsStringLength()) {
     HValue* string = Pop();
     BuildCheckHeapObject(string);
-    AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
-    instr = NewUncasted<HStringLength>(string);
+    HInstruction* checkstring =
+        AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
+    instr = BuildLoadStringLength(string, checkstring);
   } else if (expr->IsStringAccess()) {
     CHECK_ALIVE(VisitForValue(expr->key()));
     HValue* index = Pop();
@@ -7587,8 +7603,10 @@ HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt(
     }
   }
   BuildCheckHeapObject(string);
-  AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
-  HInstruction* length = Add<HStringLength>(string);
+  HValue* checkstring =
+      AddInstruction(HCheckInstanceType::NewIsString(string, zone()));
+  HInstruction* length = BuildLoadStringLength(string, checkstring);
+  AddInstruction(length);
   HInstruction* checked_index = Add<HBoundsCheck>(index, length);
   return New<HStringCharCodeAt>(string, checked_index);
 }
index daca61d..2668d19 100644 (file)
@@ -1237,10 +1237,6 @@ class HGraphBuilder {
       LoadKeyedHoleMode load_mode,
       KeyedAccessStoreMode store_mode);
 
-  HLoadNamedField* BuildLoadNamedField(
-      HValue* object,
-      HObjectAccess access);
-
   HInstruction* AddExternalArrayElementAccess(
       HValue* external_elements,
       HValue* checked_key,
@@ -1259,6 +1255,11 @@ class HGraphBuilder {
       LoadKeyedHoleMode load_mode,
       KeyedAccessStoreMode store_mode);
 
+  HLoadNamedField* BuildLoadNamedField(
+      HValue* object,
+      HObjectAccess access,
+      HValue* typecheck = NULL);
+  HInstruction* BuildLoadStringLength(HValue* object, HValue* typecheck = NULL);
   HStoreNamedField* AddStoreMapConstant(HValue *object, Handle<Map>);
   HLoadNamedField* AddLoadElements(HValue *object, HValue *typecheck = NULL);
   HLoadNamedField* AddLoadFixedArrayLength(HValue *object);
index 013a921..41441f5 100644 (file)
@@ -4862,13 +4862,6 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
 }
 
 
-void LCodeGen::DoStringLength(LStringLength* instr) {
-  Register string = ToRegister(instr->string());
-  Register result = ToRegister(instr->result());
-  __ mov(result, FieldOperand(string, String::kLengthOffset));
-}
-
-
 void LCodeGen::DoStringAdd(LStringAdd* instr) {
   EmitPushTaggedOperand(instr->left());
   EmitPushTaggedOperand(instr->right());
index 7edf2d9..2fa038b 100644 (file)
@@ -2514,12 +2514,6 @@ LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
 }
 
 
-LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
-  LOperand* string = UseRegisterAtStart(instr->value());
-  return DefineAsRegister(new(zone()) LStringLength(string));
-}
-
-
 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
   info()->MarkAsDeferredCalling();
   LOperand* context = UseAny(instr->context());
index e81cc27..6b0f9d0 100644 (file)
@@ -174,7 +174,6 @@ class LCodeGen;
   V(StringCharCodeAt)                           \
   V(StringCharFromCode)                         \
   V(StringCompareAndBranch)                     \
-  V(StringLength)                               \
   V(SubI)                                       \
   V(TaggedToI)                                  \
   V(TaggedToINoSSE2)                            \
@@ -2411,19 +2410,6 @@ class LStringCharFromCode: public LTemplateInstruction<1, 2, 0> {
 };
 
 
-class LStringLength: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LStringLength(LOperand* string) {
-    inputs_[0] = string;
-  }
-
-  LOperand* string() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
-  DECLARE_HYDROGEN_ACCESSOR(StringLength)
-};
-
-
 class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
  public:
   explicit LCheckFunction(LOperand* value) {
index d7d1241..be5809d 100644 (file)
@@ -4596,13 +4596,6 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
 }
 
 
-void LCodeGen::DoStringLength(LStringLength* instr) {
-  Register string = ToRegister(instr->string());
-  Register result = ToRegister(instr->result());
-  __ lw(result, FieldMemOperand(string, String::kLengthOffset));
-}
-
-
 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
   LOperand* input = instr->value();
   ASSERT(input->IsRegister() || input->IsStackSlot());
index b75a43f..a5371f7 100644 (file)
@@ -2316,12 +2316,6 @@ LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
 }
 
 
-LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
-  LOperand* string = UseRegisterAtStart(instr->value());
-  return DefineAsRegister(new(zone()) LStringLength(string));
-}
-
-
 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
   info()->MarkAsDeferredCalling();
   LOperand* size = instr->size()->IsConstant()
index d4735ce..44c909e 100644 (file)
@@ -174,7 +174,6 @@ class LCodeGen;
   V(StringCharCodeAt)                           \
   V(StringCharFromCode)                         \
   V(StringCompareAndBranch)                     \
-  V(StringLength)                               \
   V(SubI)                                       \
   V(TaggedToI)                                  \
   V(ThisFunction)                               \
@@ -2286,19 +2285,6 @@ class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> {
 };
 
 
-class LStringLength: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LStringLength(LOperand* string) {
-    inputs_[0] = string;
-  }
-
-  LOperand* string() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
-  DECLARE_HYDROGEN_ACCESSOR(StringLength)
-};
-
-
 class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
  public:
   explicit LCheckFunction(LOperand* value) {
index a8a691e..5a75f95 100644 (file)
@@ -4445,13 +4445,6 @@ void LCodeGen::DoDeferredStringCharFromCode(LStringCharFromCode* instr) {
 }
 
 
-void LCodeGen::DoStringLength(LStringLength* instr) {
-  Register string = ToRegister(instr->string());
-  Register result = ToRegister(instr->result());
-  __ movq(result, FieldOperand(string, String::kLengthOffset));
-}
-
-
 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
   LOperand* input = instr->value();
   ASSERT(input->IsRegister() || input->IsStackSlot());
index 4ecb733..e403165 100644 (file)
@@ -2320,12 +2320,6 @@ LInstruction* LChunkBuilder::DoStringCharFromCode(HStringCharFromCode* instr) {
 }
 
 
-LInstruction* LChunkBuilder::DoStringLength(HStringLength* instr) {
-  LOperand* string = UseRegisterAtStart(instr->value());
-  return DefineAsRegister(new(zone()) LStringLength(string));
-}
-
-
 LInstruction* LChunkBuilder::DoAllocate(HAllocate* instr) {
   info()->MarkAsDeferredCalling();
   LOperand* size = instr->size()->IsConstant()
index b5d01c8..31e5437 100644 (file)
@@ -173,7 +173,6 @@ class LCodeGen;
   V(StringCharCodeAt)                           \
   V(StringCharFromCode)                         \
   V(StringCompareAndBranch)                     \
-  V(StringLength)                               \
   V(SubI)                                       \
   V(TaggedToI)                                  \
   V(ThisFunction)                               \
@@ -2224,19 +2223,6 @@ class LStringCharFromCode: public LTemplateInstruction<1, 1, 0> {
 };
 
 
-class LStringLength: public LTemplateInstruction<1, 1, 0> {
- public:
-  explicit LStringLength(LOperand* string) {
-    inputs_[0] = string;
-  }
-
-  LOperand* string() { return inputs_[0]; }
-
-  DECLARE_CONCRETE_INSTRUCTION(StringLength, "string-length")
-  DECLARE_HYDROGEN_ACCESSOR(StringLength)
-};
-
-
 class LCheckFunction: public LTemplateInstruction<0, 1, 0> {
  public:
   explicit LCheckFunction(LOperand* value) {