Don't generate useless string checks for string adds.
authorbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 20 Nov 2013 11:53:09 +0000 (11:53 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 20 Nov 2013 11:53:09 +0000 (11:53 +0000)
If we know that one side of a string add is definitely a string
(i.e. if it's a string constant), then we don't need to emit a
string check for the argument.

This adds a new BuildCheckString() method to the graph builder,
which does "the right thing".

TEST=mjsunit/string-add
R=mvstanton@chromium.org

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

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

src/hydrogen.cc
src/hydrogen.h

index 22da947..b47bb95 100644 (file)
@@ -1273,6 +1273,20 @@ HValue* HGraphBuilder::BuildCheckMap(HValue* obj, Handle<Map> map) {
 }
 
 
+HValue* HGraphBuilder::BuildCheckString(
+    HValue* object, const char* failure_reason) {
+  if (!object->type().IsString()) {
+    ASSERT(!object->IsConstant() ||
+           !HConstant::cast(object)->HasStringValue());
+    IfBuilder if_isstring(this);
+    if_isstring.If<HIsStringAndBranch>(object);
+    if_isstring.Then();
+    if_isstring.ElseDeopt(failure_reason);
+  }
+  return object;
+}
+
+
 HValue* HGraphBuilder::BuildWrapReceiver(HValue* object, HValue* function) {
   if (object->type().IsJSObject()) return object;
   return Add<HWrapReceiver>(object, function);
@@ -8631,18 +8645,14 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(
       (left_type->Is(Type::String()) || right_type->Is(Type::String()))) {
     // Validate type feedback for left argument.
     if (left_type->Is(Type::String())) {
-      IfBuilder if_isstring(this);
-      if_isstring.If<HIsStringAndBranch>(left);
-      if_isstring.Then();
-      if_isstring.ElseDeopt("Expected string for LHS of binary operation");
+      left = BuildCheckString(
+          left, "Expected string for LHS of binary operation");
     }
 
     // Validate type feedback for right argument.
     if (right_type->Is(Type::String())) {
-      IfBuilder if_isstring(this);
-      if_isstring.If<HIsStringAndBranch>(right);
-      if_isstring.Then();
-      if_isstring.ElseDeopt("Expected string for RHS of binary operation");
+      right = BuildCheckString(
+          right, "Expected string for RHS of binary operation");
     }
 
     // Convert left argument as necessary.
index 9aa9489..723bb44 100644 (file)
@@ -1256,6 +1256,7 @@ class HGraphBuilder {
 
   HValue* BuildCheckHeapObject(HValue* object);
   HValue* BuildCheckMap(HValue* obj, Handle<Map> map);
+  HValue* BuildCheckString(HValue* object, const char* failure_reason);
   HValue* BuildWrapReceiver(HValue* object, HValue* function);
 
   // Building common constructs