Bug 1304643 - IonMonkey: Only mark as not aliasing if object owns property, r=jandem
authorHannes Verschore <hv1989@gmail.com>
Wed, 19 Oct 2016 11:50:01 +0200
changeset 318533 2faa2e745b8e4093ce5e0dfc80441fad3d876f19
parent 318532 e2da3bb6654f97a7139b53ef3e77e4603a5310f5
child 318534 671e1920ff9997ea4fa2e777d439cf9afbde5878
push id82956
push userhv1989@gmail.com
push dateWed, 19 Oct 2016 09:51:05 +0000
treeherdermozilla-inbound@a9ee75a0ae5a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1304643
milestone52.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1304643 - IonMonkey: Only mark as not aliasing if object owns property, r=jandem
js/src/jit-test/tests/ion/bug1304643.js
js/src/jit/AliasAnalysisShared.cpp
js/src/jit/MIR.cpp
js/src/jit/MIR.h
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug1304643.js
@@ -0,0 +1,7 @@
+
+var x = Object.create(this);
+var y = '1';
+for (var i = 0; i < 3; ++i) {
+        y += x.y;
+}
+assertEq(y, "11111111");
--- a/js/src/jit/AliasAnalysisShared.cpp
+++ b/js/src/jit/AliasAnalysisShared.cpp
@@ -65,23 +65,20 @@ MaybeUnwrap(const MDefinition* object)
 // Get the object of any load/store. Returns nullptr if not tied to
 // an object.
 static inline const MDefinition*
 GetObject(const MDefinition* ins)
 {
     if (!ins->getAliasSet().isStore() && !ins->getAliasSet().isLoad())
         return nullptr;
 
+    // Note: only return the object if that objects owns that property.
+    // I.e. the poperty isn't on the prototype chain.
     const MDefinition* object = nullptr;
     switch (ins->op()) {
-      case MDefinition::Op_GetPropertyCache:
-        if (!ins->toGetPropertyCache()->idempotent())
-            return nullptr;
-        object = ins->getOperand(0);
-        break;
       case MDefinition::Op_InitializedLength:
       case MDefinition::Op_LoadElement:
       case MDefinition::Op_LoadUnboxedScalar:
       case MDefinition::Op_LoadUnboxedObjectOrNull:
       case MDefinition::Op_LoadUnboxedString:
       case MDefinition::Op_StoreElement:
       case MDefinition::Op_StoreUnboxedObjectOrNull:
       case MDefinition::Op_StoreUnboxedString:
@@ -123,16 +120,17 @@ GetObject(const MDefinition* ins)
       case MDefinition::Op_LoadSlot:
       case MDefinition::Op_StoreSlot:
       case MDefinition::Op_InArray:
       case MDefinition::Op_LoadElementHole:
       case MDefinition::Op_TypedArrayElements:
       case MDefinition::Op_TypedObjectElements:
         object = ins->getOperand(0);
         break;
+      case MDefinition::Op_GetPropertyCache:
       case MDefinition::Op_LoadTypedArrayElementStatic:
       case MDefinition::Op_StoreTypedArrayElementStatic:
       case MDefinition::Op_GetDOMProperty:
       case MDefinition::Op_GetDOMMember:
       case MDefinition::Op_Call:
       case MDefinition::Op_Compare:
       case MDefinition::Op_GetArgumentsObjectArg:
       case MDefinition::Op_SetArgumentsObjectArg:
--- a/js/src/jit/MIR.cpp
+++ b/js/src/jit/MIR.cpp
@@ -5073,16 +5073,33 @@ MDefinition*
 MLoadSlot::foldsTo(TempAllocator& alloc)
 {
     if (MDefinition* def = foldsToStore(alloc))
         return def;
 
     return this;
 }
 
+void
+MLoadSlot::printOpcode(GenericPrinter& out) const
+{
+    MDefinition::printOpcode(out);
+    out.printf(" %d", slot());
+}
+
+void
+MStoreSlot::printOpcode(GenericPrinter& out) const
+{
+    PrintOpcodeName(out, op());
+    out.printf(" ", slot());
+    getOperand(0)->printName(out);
+    out.printf(" %d ", slot());
+    getOperand(1)->printName(out);
+}
+
 MDefinition*
 MFunctionEnvironment::foldsTo(TempAllocator& alloc)
 {
     if (!input()->isLambda())
         return this;
 
     return input()->toLambda()->environmentChain();
 }
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -11457,16 +11457,18 @@ class MLoadSlot
     MDefinition* foldsTo(TempAllocator& alloc) override;
 
     AliasSet getAliasSet() const override {
         MOZ_ASSERT(slots()->type() == MIRType::Slots);
         return AliasSet::Load(AliasSet::DynamicSlot);
     }
     AliasType mightAlias(const MDefinition* store) const override;
 
+    void printOpcode(GenericPrinter& out) const override;
+
     ALLOW_CLONE(MLoadSlot)
 };
 
 // Inline call to access a function's environment (scope chain).
 class MFunctionEnvironment
   : public MUnaryInstruction,
     public SingleObjectPolicy::Data
 {
@@ -11537,16 +11539,17 @@ class MStoreSlot
         return needsBarrier_;
     }
     void setNeedsBarrier() {
         needsBarrier_ = true;
     }
     AliasSet getAliasSet() const override {
         return AliasSet::Store(AliasSet::DynamicSlot);
     }
+    void printOpcode(GenericPrinter& out) const override;
 
     ALLOW_CLONE(MStoreSlot)
 };
 
 class MGetNameCache
   : public MUnaryInstruction,
     public SingleObjectPolicy::Data
 {