diff options
Diffstat (limited to 'js/src/jit')
-rw-r--r-- | js/src/jit/BaselineCompiler.cpp | 30 | ||||
-rw-r--r-- | js/src/jit/BaselineCompiler.h | 1 | ||||
-rw-r--r-- | js/src/jit/IonBuilder.cpp | 5 | ||||
-rw-r--r-- | js/src/jit/MIRGraph.cpp | 13 | ||||
-rw-r--r-- | js/src/jit/MIRGraph.h | 3 |
5 files changed, 51 insertions, 1 deletions
diff --git a/js/src/jit/BaselineCompiler.cpp b/js/src/jit/BaselineCompiler.cpp index 4dcc10b61..2f0d41707 100644 --- a/js/src/jit/BaselineCompiler.cpp +++ b/js/src/jit/BaselineCompiler.cpp @@ -1147,7 +1147,7 @@ BaselineCompiler::emit_JSOP_PICK() // after : A B D E C // First, move value at -(amount + 1) into R0. - int depth = -(GET_INT8(pc) + 1); + int32_t depth = -(GET_INT8(pc) + 1); masm.loadValue(frame.addressOfStackValue(frame.peek(depth)), R0); // Move the other values down. @@ -1166,6 +1166,34 @@ BaselineCompiler::emit_JSOP_PICK() } bool +BaselineCompiler::emit_JSOP_UNPICK() +{ + frame.syncStack(0); + + // Pick takes the top of the stack value and moves it under the nth value. + // For instance, unpick 2: + // before: A B C D E + // after : A B E C D + + // First, move value at -1 into R0. + masm.loadValue(frame.addressOfStackValue(frame.peek(-1)), R0); + + // Move the other values up. + int32_t depth = -(GET_INT8(pc) + 1); + for (int32_t i = -1; i > depth; i--) { + Address source = frame.addressOfStackValue(frame.peek(i - 1)); + Address dest = frame.addressOfStackValue(frame.peek(i)); + masm.loadValue(source, R1); + masm.storeValue(R1, dest); + } + + // Store R0 under the nth value. + Address dest = frame.addressOfStackValue(frame.peek(depth)); + masm.storeValue(R0, dest); + return true; +} + +bool BaselineCompiler::emit_JSOP_GOTO() { frame.syncStack(0); diff --git a/js/src/jit/BaselineCompiler.h b/js/src/jit/BaselineCompiler.h index 77f4dd005..60dac0966 100644 --- a/js/src/jit/BaselineCompiler.h +++ b/js/src/jit/BaselineCompiler.h @@ -42,6 +42,7 @@ namespace jit { _(JSOP_DUP2) \ _(JSOP_SWAP) \ _(JSOP_PICK) \ + _(JSOP_UNPICK) \ _(JSOP_GOTO) \ _(JSOP_IFEQ) \ _(JSOP_IFNE) \ diff --git a/js/src/jit/IonBuilder.cpp b/js/src/jit/IonBuilder.cpp index 2e7784ff4..c4df415a4 100644 --- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -1563,6 +1563,7 @@ IonBuilder::traverseBytecode() case JSOP_DUP: case JSOP_DUP2: case JSOP_PICK: + case JSOP_UNPICK: case JSOP_SWAP: case JSOP_SETARG: case JSOP_SETLOCAL: @@ -2017,6 +2018,10 @@ IonBuilder::inspectOpcode(JSOp op) current->pick(-GET_INT8(pc)); return true; + case JSOP_UNPICK: + current->unpick(-GET_INT8(pc)); + return true; + case JSOP_GETALIASEDVAR: return jsop_getaliasedvar(EnvironmentCoordinate(pc)); diff --git a/js/src/jit/MIRGraph.cpp b/js/src/jit/MIRGraph.cpp index 3a363a5bf..d6e0fa8ff 100644 --- a/js/src/jit/MIRGraph.cpp +++ b/js/src/jit/MIRGraph.cpp @@ -790,6 +790,19 @@ MBasicBlock::pick(int32_t depth) } void +MBasicBlock::unpick(int32_t depth) +{ + // unpick take the top of the stack element and move it under the depth-th + // element; + // unpick(-2): + // A B C D E + // A B C E D [ swapAt(-1) ] + // A B E C D [ swapAt(-2) ] + for (int32_t n = -1; n >= depth; n--) + swapAt(n); +} + +void MBasicBlock::swapAt(int32_t depth) { uint32_t lhsDepth = stackPosition_ + depth - 1; diff --git a/js/src/jit/MIRGraph.h b/js/src/jit/MIRGraph.h index b986218f4..705d70fa1 100644 --- a/js/src/jit/MIRGraph.h +++ b/js/src/jit/MIRGraph.h @@ -142,6 +142,9 @@ class MBasicBlock : public TempObject, public InlineListNode<MBasicBlock> // Move the definition to the top of the stack. void pick(int32_t depth); + // Move the top of the stack definition under the depth-th stack value. + void unpick(int32_t depth); + // Exchange 2 stack slots at the defined depth void swapAt(int32_t depth); |