Reviewers: Benedikt Meurer,

Description:
Handle string + number in hydrogen.

BUG=

Please review this at https://codereview.chromium.org/27011002/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files (+26, -19 lines):
  M src/code-stubs-hydrogen.cc
  M src/code-stubs.cc
  M src/hydrogen.h
  M src/hydrogen.cc


Index: src/code-stubs-hydrogen.cc
diff --git a/src/code-stubs-hydrogen.cc b/src/code-stubs-hydrogen.cc
index dcf9e5b67e50565c3ac4599975914544c4c977b7..e64ba3cd7925142ab87ad9e55e8290c815ab2acc 100644
--- a/src/code-stubs-hydrogen.cc
+++ b/src/code-stubs-hydrogen.cc
@@ -351,7 +351,7 @@ template <>
 HValue* CodeStubGraphBuilder<NumberToStringStub>::BuildCodeStub() {
   info()->MarkAsSavesCallerDoubles();
   HValue* number = GetParameter(NumberToStringStub::kNumber);
-  return BuildNumberToString(number);
+  return BuildNumberToString(number, ALLOW_SIDE_EFFECTS);
 }


Index: src/code-stubs.cc
diff --git a/src/code-stubs.cc b/src/code-stubs.cc
index 2283f847bab674029ae9e6d1f881e431589a60fc..6ea154bb0fbb264cc975f1785a7d51f98eeb10de 100644
--- a/src/code-stubs.cc
+++ b/src/code-stubs.cc
@@ -569,14 +569,8 @@ void BinaryOpStub::UpdateStatus(Handle<Object> left,

   State max_input = Max(left_state_, right_state_);

- // TODO(olivf) Instead of doing this normalization we should have a Hydrogen - // version of the LookupNumberStringCache to avoid a converting StringAddStub.
-  if (left_state_ == STRING && right_state_ < STRING) {
-    right_state_ = GENERIC;
-  } else if (right_state_ == STRING && left_state_ < STRING) {
-    left_state_ = GENERIC;
-  } else if (!has_int_result() && op_ != Token::SHR &&
-             max_input <= NUMBER && max_input > result_state_) {
+  if (!has_int_result() && op_ != Token::SHR &&
+      max_input <= NUMBER && max_input > result_state_) {
     result_state_ = max_input;
   }

Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index 45fbbc09821824998595b84291389a3bf214bfd0..4bfb91c1108245716adbbb6f19c1f32b49ead887 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1283,8 +1283,7 @@ void HGraphBuilder::BuildTransitionElementsKind(HValue* object,


 HValue* HGraphBuilder::BuildLookupNumberStringCache(
-    HValue* object,
-    HIfContinuation* continuation) {
+    HValue* object, ToStringMode mode, HIfContinuation* continuation) {
   // Create a joinable continuation.
   HIfContinuation found(graph()->CreateBasicBlock(),
                         graph()->CreateBasicBlock());
@@ -1366,6 +1365,10 @@ HValue* HGraphBuilder::BuildLookupNumberStringCache(
         }
         if_keyeqobject.JoinContinuation(&found);
       }
+      if (mode == CHECK_NUMBER) {
+        if_objectisnumber.Else();
+        if_objectisnumber.Deopt("Expected Argument to be Numeric");
+      }
       if_keyisnumber.JoinContinuation(&found);
     }
     if_objectisnumber.JoinContinuation(&found);
@@ -1391,12 +1394,12 @@ HValue* HGraphBuilder::BuildLookupNumberStringCache(
 }


-HValue* HGraphBuilder::BuildNumberToString(HValue* number) {
+HValue* HGraphBuilder::BuildNumberToString(HValue* number, ToStringMode mode) {
   NoObservableSideEffectsScope scope(this);

   // Lookup the number in the number string cache.
   HIfContinuation continuation;
-  HValue* value = BuildLookupNumberStringCache(number, &continuation);
+ HValue* value = BuildLookupNumberStringCache(number, mode, &continuation);
   IfBuilder if_found(this, &continuation);
   if_found.Then();

@@ -7909,17 +7912,25 @@ HInstruction* HGraphBuilder::BuildBinaryOperation(
     switch (op) {
       case Token::ADD:
         if (is_string_add) {
-          StringAddFlags flags = STRING_ADD_CHECK_BOTH;
+          StringAddFlags flags = STRING_ADD_CHECK_NONE;
           if (left_type->Is(Type::String())) {
             BuildCheckHeapObject(left);
             AddInstruction(HCheckInstanceType::NewIsString(left, zone()));
-            flags = STRING_ADD_CHECK_RIGHT;
+            if (right_type->Is(Type::Number())) {
+              right = BuildNumberToString(right, CHECK_NUMBER);
+            } else {
+              flags = STRING_ADD_CHECK_RIGHT;
+            }
           }
           if (right_type->Is(Type::String())) {
+            if (left_type->Is(Type::Number())) {
+              left = BuildNumberToString(left, CHECK_NUMBER);
+            } else {
+              flags = (flags == STRING_ADD_CHECK_RIGHT)
+                  ? STRING_ADD_CHECK_NONE : STRING_ADD_CHECK_LEFT;
+            }
             BuildCheckHeapObject(right);
             AddInstruction(HCheckInstanceType::NewIsString(right, zone()));
-            flags = (flags == STRING_ADD_CHECK_BOTH)
-                ? STRING_ADD_CHECK_LEFT : STRING_ADD_CHECK_NONE;
           }
           instr = NewUncasted<HStringAdd>(left, right, flags);
         } else {
@@ -9124,7 +9135,7 @@ void HOptimizedGraphBuilder::GenerateNumberToString(CallRuntime* call) {
   ASSERT_EQ(1, call->arguments()->length());
   CHECK_ALIVE(VisitForValue(call->arguments()->at(0)));
   HValue* number = Pop();
-  HValue* result = BuildNumberToString(number);
+  HValue* result = BuildNumberToString(number, ALLOW_SIDE_EFFECTS);
   return ast_context()->ReturnValue(result);
 }

Index: src/hydrogen.h
diff --git a/src/hydrogen.h b/src/hydrogen.h
index 271835b8fdad97f74aac6d7a5c700bd5ec6184f2..12b57c793f49ed6eceba61ce8701f855437f0be1 100644
--- a/src/hydrogen.h
+++ b/src/hydrogen.h
@@ -1239,9 +1239,11 @@ class HGraphBuilder {
   // otherwise the true branch is taken and the returned value contains
   // the cache value for the object. The returned value must NOT be used
   // on the false branch.
+  enum ToStringMode { ALLOW_SIDE_EFFECTS, CHECK_NUMBER };
   HValue* BuildLookupNumberStringCache(HValue* object,
+                                       ToStringMode mode,
                                        HIfContinuation* continuation);
-  HValue* BuildNumberToString(HValue* number);
+  HValue* BuildNumberToString(HValue* number, ToStringMode mode);

   HInstruction* BuildUncheckedMonomorphicElementAccess(
       HValue* checked_object,


--
--
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