Bug 1138693 - Check if Loads can be optimized by Scalar Replcement. r=jandem
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Fri, 20 Mar 2015 19:16:47 +0100
changeset 263627 0942dd86e375e3bd1c86f259a534172237a5d3f0
parent 263626 fd0834bbfd3c76ab39675e4998bcff5a230570a2
child 263628 1534390c5c6ebdeb12274ec13c447843f66874db
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs1138693
milestone39.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 1138693 - Check if Loads can be optimized by Scalar Replcement. r=jandem
js/src/jit/MIR.h
js/src/jit/ScalarReplacement.cpp
--- a/js/src/jit/MIR.h
+++ b/js/src/jit/MIR.h
@@ -3354,25 +3354,31 @@ class MObjectState
 
     MDefinition *getSlot(uint32_t slot) const {
         return getOperand(slot + 1);
     }
     void setSlot(uint32_t slot, MDefinition *def) {
         replaceOperand(slot + 1, def);
     }
 
+    bool hasFixedSlot(uint32_t slot) const {
+        return slot < numSlots() && slot < numFixedSlots();
+    }
     MDefinition *getFixedSlot(uint32_t slot) const {
         MOZ_ASSERT(slot < numFixedSlots());
         return getSlot(slot);
     }
     void setFixedSlot(uint32_t slot, MDefinition *def) {
         MOZ_ASSERT(slot < numFixedSlots());
         setSlot(slot, def);
     }
 
+    bool hasDynamicSlot(uint32_t slot) const {
+        return numFixedSlots() < numSlots() && slot < numSlots() - numFixedSlots();
+    }
     MDefinition *getDynamicSlot(uint32_t slot) const {
         return getSlot(slot + numFixedSlots());
     }
     void setDynamicSlot(uint32_t slot, MDefinition *def) {
         setSlot(slot + numFixedSlots(), def);
     }
 
     bool writeRecoverData(CompactBufferWriter &writer) const MOZ_OVERRIDE;
--- a/js/src/jit/ScalarReplacement.cpp
+++ b/js/src/jit/ScalarReplacement.cpp
@@ -431,33 +431,44 @@ ObjectMemoryView::visitObjectState(MObje
 void
 ObjectMemoryView::visitStoreFixedSlot(MStoreFixedSlot *ins)
 {
     // Skip stores made on other objects.
     if (ins->object() != obj_)
         return;
 
     // Clone the state and update the slot value.
-    state_ = BlockState::Copy(alloc_, state_);
-    state_->setFixedSlot(ins->slot(), ins->value());
-    ins->block()->insertBefore(ins->toInstruction(), state_);
+    if (state_->hasFixedSlot(ins->slot())) {
+        state_ = BlockState::Copy(alloc_, state_);
+        state_->setFixedSlot(ins->slot(), ins->value());
+        ins->block()->insertBefore(ins->toInstruction(), state_);
+    } else {
+        MBail *bailout = MBail::New(alloc_, Bailout_Inevitable);
+        ins->block()->insertBefore(ins, bailout);
+    }
 
     // Remove original instruction.
     ins->block()->discard(ins);
 }
 
 void
 ObjectMemoryView::visitLoadFixedSlot(MLoadFixedSlot *ins)
 {
     // Skip loads made on other objects.
     if (ins->object() != obj_)
         return;
 
     // Replace load by the slot value.
-    ins->replaceAllUsesWith(state_->getFixedSlot(ins->slot()));
+    if (state_->hasFixedSlot(ins->slot())) {
+        ins->replaceAllUsesWith(state_->getFixedSlot(ins->slot()));
+    } else {
+        MBail *bailout = MBail::New(alloc_, Bailout_Inevitable);
+        ins->block()->insertBefore(ins, bailout);
+        ins->replaceAllUsesWith(undefinedVal_);
+    }
 
     // Remove original instruction.
     ins->block()->discard(ins);
 }
 
 void
 ObjectMemoryView::visitPostWriteBarrier(MPostWriteBarrier *ins)
 {
@@ -476,19 +487,24 @@ ObjectMemoryView::visitStoreSlot(MStoreS
     MSlots *slots = ins->slots()->toSlots();
     if (slots->object() != obj_) {
         // Guard objects are replaced when they are visited.
         MOZ_ASSERT(!slots->object()->isGuardShape() || slots->object()->toGuardShape()->obj() != obj_);
         return;
     }
 
     // Clone the state and update the slot value.
-    state_ = BlockState::Copy(alloc_, state_);
-    state_->setDynamicSlot(ins->slot(), ins->value());
-    ins->block()->insertBefore(ins->toInstruction(), state_);
+    if (state_->hasDynamicSlot(ins->slot())) {
+        state_ = BlockState::Copy(alloc_, state_);
+        state_->setDynamicSlot(ins->slot(), ins->value());
+        ins->block()->insertBefore(ins->toInstruction(), state_);
+    } else {
+        MBail *bailout = MBail::New(alloc_, Bailout_Inevitable);
+        ins->block()->insertBefore(ins, bailout);
+    }
 
     // Remove original instruction.
     ins->block()->discard(ins);
 }
 
 void
 ObjectMemoryView::visitLoadSlot(MLoadSlot *ins)
 {
@@ -496,17 +512,23 @@ ObjectMemoryView::visitLoadSlot(MLoadSlo
     MSlots *slots = ins->slots()->toSlots();
     if (slots->object() != obj_) {
         // Guard objects are replaced when they are visited.
         MOZ_ASSERT(!slots->object()->isGuardShape() || slots->object()->toGuardShape()->obj() != obj_);
         return;
     }
 
     // Replace load by the slot value.
-    ins->replaceAllUsesWith(state_->getDynamicSlot(ins->slot()));
+    if (state_->hasDynamicSlot(ins->slot())) {
+        ins->replaceAllUsesWith(state_->getDynamicSlot(ins->slot()));
+    } else {
+        MBail *bailout = MBail::New(alloc_, Bailout_Inevitable);
+        ins->block()->insertBefore(ins, bailout);
+        ins->replaceAllUsesWith(undefinedVal_);
+    }
 
     // Remove original instruction.
     ins->block()->discard(ins);
 }
 
 void
 ObjectMemoryView::visitGuardShape(MGuardShape *ins)
 {