Reviewers: Jakob,

Message:
PTAL.

Description:
Elements load depends on the type of the receiver.

[email protected]


Please review this at https://chromiumcodereview.appspot.com/10918005/

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

Affected files:
  M src/hydrogen-instructions.h
  M src/hydrogen.cc
  A + test/mjsunit/regress/regress-load-elements.js


Index: src/hydrogen-instructions.h
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h
index b5741c633bf8eaaf1f7e7f0670524b2c7aba6930..1cc0628900764d7f76d518e6e3e3967b6080429a 100644
--- a/src/hydrogen-instructions.h
+++ b/src/hydrogen-instructions.h
@@ -2068,14 +2068,18 @@ class HUnaryMathOperation: public HTemplateInstruction<2> {
 };


-class HLoadElements: public HUnaryOperation {
+class HLoadElements: public HTemplateInstruction<2> {
  public:
-  explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
+  HLoadElements(HValue* value, HValue* typecheck) {
+    SetOperandAt(0, value);
+    SetOperandAt(1, typecheck);
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
     SetGVNFlag(kDependsOnElementsPointer);
   }

+  HValue* value() { return OperandAt(0); }
+
   virtual Representation RequiredInputRepresentation(int index) {
     return Representation::Tagged();
   }
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index d2aba123922e05452c7bd2b65e8048137110b382..9f5a631ec8b73d78e00ca3cd864157b45d7e1bce 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -5218,7 +5218,9 @@ void HGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
     HValue* value = Pop();
     if (!Smi::IsValid(i)) return Bailout("Non-smi key in array literal");

-    elements = new(zone()) HLoadElements(literal);
+    // Pass in literal as dummy depedency, since  the receiver always has
+    // elements.
+    elements = new(zone()) HLoadElements(literal, literal);
     AddInstruction(elements);

     HValue* key = AddInstruction(
@@ -6186,7 +6188,8 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
   }
   bool fast_smi_only_elements = map->has_fast_smi_elements();
   bool fast_elements = map->has_fast_object_elements();
- HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
+  HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object,
+ mapcheck));
   if (is_store && (fast_elements || fast_smi_only_elements)) {
     HCheckMaps* check_cow_map = new(zone()) HCheckMaps(
         elements, isolate()->factory()->fixed_array_map(), zone());
@@ -6366,13 +6369,15 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object,
     return is_store ? NULL : instr;
   }

-  AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone()));
+  HInstruction* checkspec =
+      AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone()));
   HBasicBlock* join = graph()->CreateBasicBlock();

   HInstruction* elements_kind_instr =
       AddInstruction(new(zone()) HElementsKind(object));
   HCompareConstantEqAndBranch* elements_kind_branch = NULL;
- HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object));
+  HInstruction* elements = AddInstruction(new(zone()) HLoadElements(object,
+ checkspec));
   HLoadExternalArrayPointer* external_elements = NULL;
   HInstruction* checked_key = NULL;

Index: test/mjsunit/regress/regress-load-elements.js
diff --git a/test/mjsunit/pixel-array-rounding.js b/test/mjsunit/regress/regress-load-elements.js
old mode 100755
new mode 100644
similarity index 80%
copy from test/mjsunit/pixel-array-rounding.js
copy to test/mjsunit/regress/regress-load-elements.js
index 0c307e62e55297faefe3e2ae253e7a344f4ee6c6..02670f395b0266eff47a8ff65b48703febb9e210
--- a/test/mjsunit/pixel-array-rounding.js
+++ b/test/mjsunit/regress/regress-load-elements.js
@@ -27,18 +27,23 @@

 // Flags: --allow-natives-syntax

-var pixels = new Uint8ClampedArray(8);
-
-function f() {
-  for (var i = 0; i < 8; i++) {
-    pixels[i] = (i * 1.1);
+function bad_func(o,a) {
+  for (var i = 0; i < 1; ++i) {
+    o.prop = 0;
+    var x = a[0];
   }
-  return pixels[1] + pixels[6];
 }

-f();
-f();
-assertEquals(6, pixels[5]);
-%OptimizeFunctionOnNextCall(f);
-f();
-assertEquals(6, pixels[5]);
+o = new Object();
+a = {};
+a[0] = 1;
+bad_func(o, a);
+
+o = new Object();
+bad_func(o, a);
+
+// Optimize, before the fix, the element load and subsequent tagged-to-i were +// hoisted above the map check, which can't be hoisted due to the map-changing
+// store.
+%OptimizeFunctionOnNextCall(bad_func);
+bad_func(o, "");


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to