Reviewers: Jakob,

Message:
PTAL

Description:
Fix Crankshafted CompareNil of constant values

[email protected]

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

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

Affected files:
  M src/hydrogen.cc
  A + test/mjsunit/constant-compare-nil-value.js


Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index ba1de7aa2258a308927c90f937d5d1e6beccd841..f32e0cd2120812eb837594e8132bc5eab1adce02 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -1748,32 +1748,48 @@ void HGraphBuilder::BuildCompareNil(
     HIfContinuation* continuation) {
   IfBuilder if_nil(this, position);
   bool needs_or = false;
-  if (type->Maybe(Type::Null())) {
-    if (needs_or) if_nil.Or();
- if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull());
-    needs_or = true;
-  }
-  if (type->Maybe(Type::Undefined())) {
-    if (needs_or) if_nil.Or();
-    if_nil.If<HCompareObjectEqAndBranch>(value,
-                                         graph()->GetConstantUndefined());
-    needs_or = true;
-  }
-  if (type->Maybe(Type::Undetectable())) {
-    if (needs_or) if_nil.Or();
-    if_nil.If<HIsUndetectableAndBranch>(value);
+  if (value->IsConstant()) {
+    bool is_null = false;
+    HConstant* constant_value = HConstant::cast(value);
+    if (!constant_value->HasNumberValue()) {
+      Object* constant_object = *(constant_value->handle());
+      is_null = constant_object->IsNull() ||
+          constant_object->IsUndefined() ||
+          constant_object->IsUndetectableObject();
+    }
+    constant_value = is_null
+        ? graph()->GetConstantTrue()
+        : graph()->GetConstantFalse();
+    if_nil.If<HCompareObjectEqAndBranch>(constant_value,
+                                         graph()->GetConstantTrue());
   } else {
-    if_nil.Then();
-    if_nil.Else();
-    if (type->NumClasses() == 1) {
-      BuildCheckHeapObject(value);
- // For ICs, the map checked below is a sentinel map that gets replaced by - // the monomorphic map when the code is used as a template to generate a
-      // new IC. For optimized functions, there is no sentinel map, the map
-      // emitted below is the actual monomorphic map.
-      BuildCheckMap(value, type->Classes().Current());
+    if (type->Maybe(Type::Null())) {
+      if (needs_or) if_nil.Or();
+ if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull());
+      needs_or = true;
+    }
+    if (type->Maybe(Type::Undefined())) {
+      if (needs_or) if_nil.Or();
+      if_nil.If<HCompareObjectEqAndBranch>(value,
+ graph()->GetConstantUndefined());
+      needs_or = true;
+    }
+    if (type->Maybe(Type::Undetectable())) {
+      if (needs_or) if_nil.Or();
+      if_nil.If<HIsUndetectableAndBranch>(value);
     } else {
-      if_nil.Deopt("Too many undetectable types");
+      if_nil.Then();
+      if_nil.Else();
+      if (type->NumClasses() == 1) {
+        BuildCheckHeapObject(value);
+ // For ICs, the map checked below is a sentinel map that gets replaced
+        // by the monomorphic map when the code is used as a template to
+ // generate a new IC. For optimized functions, there is no sentinel map,
+        // the map emitted below is the actual monomorphic map.
+        BuildCheckMap(value, type->Classes().Current());
+      } else {
+        if_nil.Deopt("Too many undetectable types");
+      }
     }
   }

Index: test/mjsunit/constant-compare-nil-value.js
diff --git a/test/mjsunit/regress/regress-2499.js b/test/mjsunit/constant-compare-nil-value.js
similarity index 88%
copy from test/mjsunit/regress/regress-2499.js
copy to test/mjsunit/constant-compare-nil-value.js
index 52aad874db6fcdc89f5ee1ae4db45304e64b0e77..9f5b2adb063abc0c7920d8dee30edb7ee6eb1ff9 100644
--- a/test/mjsunit/regress/regress-2499.js
+++ b/test/mjsunit/constant-compare-nil-value.js
@@ -27,14 +27,16 @@

 // Flags: --allow-natives-syntax

-function foo(word, nBits) {
-  return (word[1] >>> nBits) | (word[0] << (32 - nBits));
+function inlined() {
+    return 1;
 }

-word = [0x1001, 0];
+function foo() {
+    if ((inlined() + 0.5) == null) return "null";
+    return "non-null";
+}

-var expected = foo(word, 1);
-foo(word, 1);
+assertEquals("non-null", foo());
+assertEquals("non-null", foo());
 %OptimizeFunctionOnNextCall(foo);
-var optimized = foo(word, 1);
-assertEquals(expected, optimized)
+assertEquals("non-null", foo());


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