Bug 876454 - Implement JSOP_LEAVEBLOCKEXPR and JSOP_LEAVEFORLETIN in the baseline compiler. r=evilpie
authorJan de Mooij <jdemooij@mozilla.com>
Sat, 01 Jun 2013 11:54:11 +0200
changeset 140816 fc0a521fad4314d8f31f6c47f55aaf39ad5b9ed5
parent 140815 9bcaba8046eeab95bd4552a2f68767b4f524a22e
child 140817 c5a4248bf250d495b345a1bd0ddf3898269fef2d
push id3911
push userakeybl@mozilla.com
push dateMon, 24 Jun 2013 20:17:26 +0000
treeherdermozilla-aurora@7e26ca8db92b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersevilpie
bugs876454
milestone24.0a1
Bug 876454 - Implement JSOP_LEAVEBLOCKEXPR and JSOP_LEAVEFORLETIN in the baseline compiler. r=evilpie
js/src/ion/BaselineCompiler.cpp
js/src/ion/BaselineCompiler.h
--- a/js/src/ion/BaselineCompiler.cpp
+++ b/js/src/ion/BaselineCompiler.cpp
@@ -2345,30 +2345,59 @@ BaselineCompiler::emit_JSOP_ENTERLET1()
 {
     return emitEnterBlock();
 }
 
 typedef bool (*LeaveBlockFn)(JSContext *, BaselineFrame *);
 static const VMFunction LeaveBlockInfo = FunctionInfo<LeaveBlockFn>(ion::LeaveBlock);
 
 bool
-BaselineCompiler::emit_JSOP_LEAVEBLOCK()
+BaselineCompiler::emitLeaveBlock()
 {
     // Call a stub to pop the block from the block chain.
     prepareVMCall();
 
     masm.loadBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
     pushArg(R0.scratchReg());
 
-    if (!callVM(LeaveBlockInfo))
+    return callVM(LeaveBlockInfo);
+}
+
+bool
+BaselineCompiler::emit_JSOP_LEAVEBLOCK()
+{
+    if (!emitLeaveBlock())
         return false;
 
-    // Pop slots pushed by ENTERBLOCK.
-    size_t n = StackUses(script, pc);
-    frame.popn(n);
+    // Pop slots pushed by JSOP_ENTERBLOCK.
+    frame.popn(GET_UINT16(pc));
+    return true;
+}
+
+bool
+BaselineCompiler::emit_JSOP_LEAVEBLOCKEXPR()
+{
+    if (!emitLeaveBlock())
+        return false;
+
+    // Pop slots pushed by JSOP_ENTERBLOCK, but leave the topmost value
+    // on the stack.
+    frame.popRegsAndSync(1);
+    frame.popn(GET_UINT16(pc));
+    frame.push(R0);
+    return true;
+}
+
+bool
+BaselineCompiler::emit_JSOP_LEAVEFORLETIN()
+{
+    if (!emitLeaveBlock())
+        return false;
+
+    // Another op will pop the slots (after the enditer).
     return true;
 }
 
 typedef bool (*GetAndClearExceptionFn)(JSContext *, MutableHandleValue);
 static const VMFunction GetAndClearExceptionInfo =
     FunctionInfo<GetAndClearExceptionFn>(GetAndClearException);
 
 bool
--- a/js/src/ion/BaselineCompiler.h
+++ b/js/src/ion/BaselineCompiler.h
@@ -150,16 +150,18 @@ namespace ion {
     _(JSOP_TYPEOFEXPR)         \
     _(JSOP_SETCALL)            \
     _(JSOP_THROW)              \
     _(JSOP_TRY)                \
     _(JSOP_ENTERBLOCK)         \
     _(JSOP_ENTERLET0)          \
     _(JSOP_ENTERLET1)          \
     _(JSOP_LEAVEBLOCK)         \
+    _(JSOP_LEAVEBLOCKEXPR)     \
+    _(JSOP_LEAVEFORLETIN)      \
     _(JSOP_EXCEPTION)          \
     _(JSOP_DEBUGGER)           \
     _(JSOP_ARGUMENTS)          \
     _(JSOP_RUNONCE)            \
     _(JSOP_REST)               \
     _(JSOP_TOID)               \
     _(JSOP_TABLESWITCH)        \
     _(JSOP_ITER)               \
@@ -245,16 +247,17 @@ class BaselineCompiler : public Baseline
     bool emitCall();
 
     bool emitInitPropGetterSetter();
     bool emitInitElemGetterSetter();
 
     bool emitFormalArgAccess(uint32_t arg, bool get);
 
     bool emitEnterBlock();
+    bool emitLeaveBlock();
 
     bool addPCMappingEntry(bool addIndexEntry);
 
     void getScopeCoordinateObject(Register reg);
     Address getScopeCoordinateAddressFromObject(Register objReg, Register reg);
     Address getScopeCoordinateAddress(Register reg);
 };