Bug 1147371 - Implement JSOP_PICK and JSOP_UNPICK in the expression decompiler. (r=arai)
☠☠ backed out by 6584da54c13d ☠ ☠
authorShu-yu Guo <shu@rfrn.org>
Thu, 12 Jan 2017 23:51:35 -0800
changeset 374306 408a37107c7f2fa27ddc0ed40ff5b86694760178
parent 374305 d9eef2331ae6a7896da0c6caca605317499db73b
child 374307 a14cade8b9627585d42abc2f6e72deaf4c335a25
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1147371
milestone53.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 1147371 - Implement JSOP_PICK and JSOP_UNPICK in the expression decompiler. (r=arai)
js/src/jsopcode.cpp
js/src/jsopcode.h
js/src/jsopcodeinlines.h
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -455,16 +455,44 @@ BytecodeParser::simulateOp(JSOp op, uint
       case JSOP_SWAP:
         MOZ_ASSERT(ndefs == 2);
         if (offsetStack) {
             uint32_t tmp = offsetStack[stackDepth + 1];
             offsetStack[stackDepth + 1] = offsetStack[stackDepth];
             offsetStack[stackDepth] = tmp;
         }
         break;
+
+      case JSOP_PICK: {
+        jsbytecode* pc = script_->offsetToPC(offset);
+        unsigned n = GET_UINT8(pc);
+        MOZ_ASSERT(ndefs == n + 1);
+        if (offsetStack) {
+            uint32_t top = stackDepth + n;
+            uint32_t tmp = offsetStack[stackDepth];
+            for (uint32_t i = stackDepth; i < top; i++)
+                offsetStack[i] = offsetStack[i + 1];
+            offsetStack[top] = tmp;
+        }
+        break;
+      }
+
+      case JSOP_UNPICK: {
+        jsbytecode* pc = script_->offsetToPC(offset);
+        unsigned n = GET_UINT8(pc);
+        MOZ_ASSERT(ndefs == n + 1);
+        if (offsetStack) {
+            uint32_t top = stackDepth + n;
+            uint32_t tmp = offsetStack[top];
+            for (uint32_t i = top; i > stackDepth; i--)
+                offsetStack[i] = offsetStack[i - 1];
+            offsetStack[stackDepth] = tmp;
+        }
+        break;
+      }
     }
     stackDepth += ndefs;
     return stackDepth;
 }
 
 bool
 BytecodeParser::recordBytecode(uint32_t offset, const uint32_t* offsetStack,
                                uint32_t stackDepth)
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -418,16 +418,17 @@ BytecodeFallsThrough(JSOp op)
 {
     switch (op) {
       case JSOP_GOTO:
       case JSOP_DEFAULT:
       case JSOP_RETURN:
       case JSOP_RETRVAL:
       case JSOP_FINALYIELDRVAL:
       case JSOP_THROW:
+      case JSOP_THROWMSG:
       case JSOP_TABLESWITCH:
         return false;
       case JSOP_GOSUB:
         /* These fall through indirectly, after executing a 'finally'. */
         return true;
       default:
         return true;
     }
--- a/js/src/jsopcodeinlines.h
+++ b/js/src/jsopcodeinlines.h
@@ -22,16 +22,17 @@ GetDefCount(JSScript* script, unsigned o
      * Add an extra pushed value for OR/AND opcodes, so that they are included
      * in the pushed array of stack values for type inference.
      */
     switch (JSOp(*pc)) {
       case JSOP_OR:
       case JSOP_AND:
         return 1;
       case JSOP_PICK:
+      case JSOP_UNPICK:
         /*
          * Pick pops and pushes how deep it looks in the stack + 1
          * items. i.e. if the stack were |a b[2] c[1] d[0]|, pick 2
          * would pop b, c, and d to rearrange the stack to |a c[0]
          * d[1] b[2]|.
          */
         return pc[1] + 1;
       default:
@@ -39,17 +40,17 @@ GetDefCount(JSScript* script, unsigned o
     }
 }
 
 static inline unsigned
 GetUseCount(JSScript* script, unsigned offset)
 {
     jsbytecode* pc = script->offsetToPC(offset);
 
-    if (JSOp(*pc) == JSOP_PICK)
+    if (JSOp(*pc) == JSOP_PICK || JSOp(*pc) == JSOP_UNPICK)
         return pc[1] + 1;
     if (CodeSpec[*pc].nuses == -1)
         return StackUses(script, pc);
     return CodeSpec[*pc].nuses;
 }
 
 static inline JSOp
 ReverseCompareOp(JSOp op)