Bug 588522 - Remove JSOP_ENDINIT. r=jorendorff.
authorNicholas Nethercote <nnethercote@mozilla.com>
Mon, 27 Oct 2014 15:37:48 -0700
changeset 212587 ba4beabcb40bfeee0af98de08552a78c570524a8
parent 212586 98d0bbc3081747a830296780a30439dd47f855ee
child 212588 9b2a722cfd1555615e0f82ba7ed5a359a01624a9
push id27721
push usercbook@mozilla.com
push dateTue, 28 Oct 2014 14:55:05 +0000
treeherdermozilla-central@c0ddb1b098ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs588522
milestone36.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 588522 - Remove JSOP_ENDINIT. r=jorendorff.
js/src/frontend/BytecodeEmitter.cpp
js/src/jit/BaselineCompiler.cpp
js/src/jit/BaselineCompiler.h
js/src/jit/IonBuilder.cpp
js/src/jsopcode.h
js/src/vm/Interpreter-inl.h
js/src/vm/Interpreter.cpp
js/src/vm/Opcodes.h
js/src/vm/Xdr.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -2221,18 +2221,16 @@ EmitFinishIteratorResult(ExclusiveContex
         return UINT_MAX;
 
     if (!EmitIndex32(cx, JSOP_INITPROP, value_id, bce))
         return false;
     if (Emit1(cx, bce, done ? JSOP_TRUE : JSOP_FALSE) < 0)
         return false;
     if (!EmitIndex32(cx, JSOP_INITPROP, done_id, bce))
         return false;
-    if (Emit1(cx, bce, JSOP_ENDINIT) < 0)
-        return false;
     return true;
 }
 
 static bool
 EmitNameOp(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn, bool callContext)
 {
     if (!BindNameToSlot(cx, bce, pn))
         return false;
@@ -3383,18 +3381,16 @@ EmitDestructuringOpsArrayHelper(Exclusiv
             SET_UINT24(pc, 0);
 
             if (!EmitNumberOp(cx, 0, bce))                             // ... OBJ? ITER ARRAY INDEX
                 return false;
             if (!EmitSpread(cx, bce))                                  // ... OBJ? ARRAY INDEX
                 return false;
             if (Emit1(cx, bce, JSOP_POP) < 0)                          // ... OBJ? ARRAY
                 return false;
-            if (Emit1(cx, bce, JSOP_ENDINIT) < 0)
-                return false;
             needToPopIterator = false;
         } else {
             if (Emit1(cx, bce, JSOP_DUP) < 0)                          // ... OBJ? ITER ITER
                 return false;
             if (!EmitIteratorNext(cx, bce, pattern))                   // ... OBJ? ITER RESULT
                 return false;
             if (Emit1(cx, bce, JSOP_DUP) < 0)                          // ... OBJ? ITER RESULT RESULT
                 return false;
@@ -6417,19 +6413,16 @@ EmitObject(ExclusiveContext *cx, Bytecod
                     obj = nullptr;
             }
 
             if (!EmitIndex32(cx, op, index, bce))
                 return false;
         }
     }
 
-    if (Emit1(cx, bce, JSOP_ENDINIT) < 0)
-        return false;
-
     if (obj) {
         /*
          * The object survived and has a predictable shape: update the original
          * bytecode.
          */
         ObjectBox *objbox = bce->parser->newObjectBox(obj);
         if (!objbox)
             return false;
@@ -6462,18 +6455,17 @@ EmitArrayComp(ExclusiveContext *cx, Byte
      */
     MOZ_ASSERT(bce->stackDepth > 0);
     uint32_t saveDepth = bce->arrayCompDepth;
     bce->arrayCompDepth = (uint32_t) (bce->stackDepth - 1);
     if (!EmitTree(cx, bce, pn->pn_head))
         return false;
     bce->arrayCompDepth = saveDepth;
 
-    /* Emit the usual op needed for decompilation. */
-    return Emit1(cx, bce, JSOP_ENDINIT) >= 0;
+    return true;
 }
 
 /**
  * EmitSpread expects the current index (I) of the array, the array itself and the iterator to be
  * on the stack in that order (iterator on the bottom).
  * It will pop the iterator and I, then iterate over the iterator by calling |.next()|
  * and put the results into the I-th element of array with incrementing I, then
  * push the result I (it will be original I + iteration count).
@@ -6551,19 +6543,17 @@ EmitArray(ExclusiveContext *cx, Bytecode
             SET_UINT24(bce->code(off), atomIndex);
         }
     }
     MOZ_ASSERT(atomIndex == count);
     if (afterSpread) {
         if (Emit1(cx, bce, JSOP_POP) < 0)                                // ARRAY
             return false;
     }
-
-    /* Emit an op to finish the array and aid in decompilation. */
-    return Emit1(cx, bce, JSOP_ENDINIT) >= 0;
+    return true;
 }
 
 static bool
 EmitUnary(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
 {
     if (!UpdateSourceCoordNotes(cx, bce, pn->pn_pos.begin))
         return false;
     /* Unary op, including unary +/-. */
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -1849,22 +1849,16 @@ BaselineCompiler::emit_JSOP_INITPROP()
     frame.push(R0);
     frame.syncStack(0);
 
     // Call IC.
     ICSetProp_Fallback::Compiler compiler(cx);
     return emitOpIC(compiler.getStub(&stubSpace_));
 }
 
-bool
-BaselineCompiler::emit_JSOP_ENDINIT()
-{
-    return true;
-}
-
 typedef bool (*NewbornArrayPushFn)(JSContext *, HandleObject, const Value &);
 static const VMFunction NewbornArrayPushInfo = FunctionInfo<NewbornArrayPushFn>(NewbornArrayPush);
 
 bool
 BaselineCompiler::emit_JSOP_ARRAYPUSH()
 {
     // Keep value in R0, object in R1.
     frame.popRegsAndSync(2);
--- a/js/src/jit/BaselineCompiler.h
+++ b/js/src/jit/BaselineCompiler.h
@@ -99,17 +99,16 @@ namespace jit {
     _(JSOP_INITELEM)           \
     _(JSOP_INITELEM_GETTER)    \
     _(JSOP_INITELEM_SETTER)    \
     _(JSOP_INITELEM_INC)       \
     _(JSOP_MUTATEPROTO)        \
     _(JSOP_INITPROP)           \
     _(JSOP_INITPROP_GETTER)    \
     _(JSOP_INITPROP_SETTER)    \
-    _(JSOP_ENDINIT)            \
     _(JSOP_ARRAYPUSH)          \
     _(JSOP_GETELEM)            \
     _(JSOP_SETELEM)            \
     _(JSOP_CALLELEM)           \
     _(JSOP_DELELEM)            \
     _(JSOP_IN)                 \
     _(JSOP_GETGNAME)           \
     _(JSOP_BINDGNAME)          \
--- a/js/src/jit/IonBuilder.cpp
+++ b/js/src/jit/IonBuilder.cpp
@@ -1634,19 +1634,16 @@ IonBuilder::inspectOpcode(JSOp op)
         PropertyName *name = info().getAtom(pc)->asPropertyName();
         return jsop_initprop_getter_setter(name);
       }
 
       case JSOP_INITELEM_GETTER:
       case JSOP_INITELEM_SETTER:
         return jsop_initelem_getter_setter();
 
-      case JSOP_ENDINIT:
-        return true;
-
       case JSOP_FUNCALL:
         return jsop_funcall(GET_ARGC(pc));
 
       case JSOP_FUNAPPLY:
         return jsop_funapply(GET_ARGC(pc));
 
       case JSOP_CALL:
       case JSOP_NEW:
--- a/js/src/jsopcode.h
+++ b/js/src/jsopcode.h
@@ -21,27 +21,17 @@
 /*
  * JS operation bytecodes.
  */
 typedef enum JSOp {
 #define ENUMERATE_OPCODE(op, val, ...) op = val,
 FOR_EACH_OPCODE(ENUMERATE_OPCODE)
 #undef ENUMERATE_OPCODE
 
-    JSOP_LIMIT,
-
-    /*
-     * These pseudo-ops help js_DecompileValueGenerator decompile JSOP_SETPROP,
-     * JSOP_SETELEM, and comprehension-tails, respectively.  They are never
-     * stored in bytecode, so they don't preempt valid opcodes.
-     */
-    JSOP_GETPROP2 = JSOP_LIMIT,
-    JSOP_GETELEM2 = JSOP_LIMIT + 1,
-    JSOP_FORLOCAL = JSOP_LIMIT + 2,
-    JSOP_FAKE_LIMIT = JSOP_FORLOCAL
+    JSOP_LIMIT
 } JSOp;
 
 /*
  * JS bytecode formats.
  */
 #define JOF_BYTE          0       /* single bytecode, no immediates */
 #define JOF_JUMP          1       /* signed 16-bit jump offset immediate */
 #define JOF_ATOM          2       /* unsigned 16-bit constant index */
--- a/js/src/vm/Interpreter-inl.h
+++ b/js/src/vm/Interpreter-inl.h
@@ -565,29 +565,29 @@ static MOZ_ALWAYS_INLINE bool
 InitArrayElemOperation(JSContext *cx, jsbytecode *pc, HandleObject obj, uint32_t index, HandleValue val)
 {
     JSOp op = JSOp(*pc);
     MOZ_ASSERT(op == JSOP_INITELEM_ARRAY || op == JSOP_INITELEM_INC);
 
     MOZ_ASSERT(obj->is<ArrayObject>());
 
     /*
-     * If val is a hole, do not call JSObject::defineElement. In this case,
-     * if the current op is the last element initialiser, set the array length
-     * to one greater than id.
+     * If val is a hole, do not call JSObject::defineElement.
      *
-     * If val is a hole and current op is JSOP_INITELEM_INC, always call
+     * Furthermore, if the current op is JSOP_INITELEM_INC, always call
      * SetLengthProperty even if it is not the last element initialiser,
      * because it may be followed by JSOP_SPREAD, which will not set the array
-     * length if nothing is spreaded.
+     * length if nothing is spread.
+     *
+     * Alternatively, if the current op is JSOP_INITELEM_ARRAY, the length will
+     * have already been set by the earlier JSOP_NEWARRAY; JSOP_INITELEM_ARRAY
+     * cannot follow JSOP_SPREAD.
      */
     if (val.isMagic(JS_ELEMENTS_HOLE)) {
-        JSOp next = JSOp(*GetNextPc(pc));
-
-        if ((op == JSOP_INITELEM_ARRAY && next == JSOP_ENDINIT) || op == JSOP_INITELEM_INC) {
+        if (op == JSOP_INITELEM_INC) {
             if (!SetLengthProperty(cx, obj, index + 1))
                 return false;
         }
     } else {
         if (!JSObject::defineElement(cx, obj, index, val, nullptr, nullptr, JSPROP_ENUMERATE))
             return false;
     }
 
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -1606,16 +1606,17 @@ CASE(JSOP_UNUSED46)
 CASE(JSOP_UNUSED47)
 CASE(JSOP_UNUSED48)
 CASE(JSOP_UNUSED49)
 CASE(JSOP_UNUSED50)
 CASE(JSOP_UNUSED51)
 CASE(JSOP_UNUSED52)
 CASE(JSOP_UNUSED57)
 CASE(JSOP_UNUSED83)
+CASE(JSOP_UNUSED92)
 CASE(JSOP_UNUSED103)
 CASE(JSOP_UNUSED104)
 CASE(JSOP_UNUSED105)
 CASE(JSOP_UNUSED107)
 CASE(JSOP_UNUSED124)
 CASE(JSOP_UNUSED125)
 CASE(JSOP_UNUSED126)
 CASE(JSOP_UNUSED146)
@@ -3115,24 +3116,16 @@ CASE(JSOP_NEWOBJECT)
     obj = CopyInitializerObject(cx, baseobj, newKind);
     if (!obj || !SetInitializerObjectType(cx, script, REGS.pc, obj, newKind))
         goto error;
 
     PUSH_OBJECT(*obj);
 }
 END_CASE(JSOP_NEWOBJECT)
 
-CASE(JSOP_ENDINIT)
-{
-    /* FIXME remove JSOP_ENDINIT bug 588522 */
-    MOZ_ASSERT(REGS.stackDepth() >= 1);
-    MOZ_ASSERT(REGS.sp[-1].isObject() || REGS.sp[-1].isUndefined());
-}
-END_CASE(JSOP_ENDINIT)
-
 CASE(JSOP_MUTATEPROTO)
 {
     MOZ_ASSERT(REGS.stackDepth() >= 2);
 
     if (REGS.sp[-1].isObjectOrNull()) {
         RootedObject &newProto = rootObject1;
         rootObject1 = REGS.sp[-1].toObjectOrNull();
 
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -765,27 +765,19 @@ 1234567890123456789012345678901234567890
      * This opcode takes an object with the final shape, which can be set at
      * the start and slots then filled in directly.
      *   Category: Literals
      *   Type: Object
      *   Operands: uint32_t baseobjIndex
      *   Stack: => obj
      */ \
     macro(JSOP_NEWOBJECT, 91, "newobject",  NULL,         5,  0,  1, JOF_OBJECT) \
-    /*
-     * A no-operation bytecode.
-     *
-     * Indicates the end of object/array initialization, and used for
-     * Type-Inference, decompile, etc.
-     *   Category: Literals
-     *   Type: Object
-     *   Operands:
-     *   Stack: =>
-     */ \
-    macro(JSOP_ENDINIT,   92, "endinit",    NULL,         1,  0,  0, JOF_BYTE) \
+    \
+    macro(JSOP_UNUSED92,  92, "unused92",   NULL,         1,  0,  0, JOF_BYTE) \
+    \
     /*
      * Initialize a named property in an object literal, like '{a: x}'.
      *
      * Pops the top two values on the stack as 'val' and 'obj', defines
      * 'nameIndex' property of 'obj' as 'val', pushes 'obj' onto the stack.
      *   Category: Literals
      *   Type: Object
      *   Operands: uint32_t nameIndex
--- a/js/src/vm/Xdr.h
+++ b/js/src/vm/Xdr.h
@@ -23,17 +23,17 @@ namespace js {
  * versions.  If deserialization fails, the data should be invalidated if
  * possible.
  *
  * When you change this, run make_opcode_doc.py and copy the new output into
  * this wiki page:
  *
  *  https://developer.mozilla.org/en-US/docs/SpiderMonkey/Internals/Bytecode
  */
-static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 186);
+static const uint32_t XDR_BYTECODE_VERSION = uint32_t(0xb973c0de - 187);
 
 class XDRBuffer {
   public:
     explicit XDRBuffer(JSContext *cx)
       : context(cx), base(nullptr), cursor(nullptr), limit(nullptr) { }
 
     JSContext *cx() const {
         return context;