Bug 1509537 - Simplify JSOP_INITHOMEOBJECT, emit JSOP_DUPAT to put the home object on top of the stack. r=arai
authorJan de Mooij <jdemooij@mozilla.com>
Mon, 26 Nov 2018 04:44:31 +0000
changeset 504395 6b3e2ddccf10962e9fdabec9c2dd0d8a9bcffab2
parent 504394 367cea0a5b9f4b31c5ff497f36cfba484c52ebbd
child 504396 2ba86b9e4cc85efd75c3b22e4728135012930e39
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersarai
bugs1509537
milestone65.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 1509537 - Simplify JSOP_INITHOMEOBJECT, emit JSOP_DUPAT to put the home object on top of the stack. r=arai Differential Revision: https://phabricator.services.mozilla.com/D12777
js/src/frontend/BytecodeEmitter.cpp
js/src/jit/BaselineCompiler.cpp
js/src/vm/BytecodeUtil.cpp
js/src/vm/Interpreter.cpp
js/src/vm/Opcodes.h
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -5846,17 +5846,18 @@ BytecodeEmitter::emitAsyncWrapper(unsign
     //   dup          // unwrapped unwrapped
     //   toasync      // unwrapped wrapped
     //
     // Emitted code is surrounded by the following code.
     //
     //                    // classObj classCtor classProto
     //   (emitted code)   // classObj classCtor classProto unwrapped wrapped
     //   swap             // classObj classCtor classProto wrapped unwrapped
-    //   inithomeobject 1 // classObj classCtor classProto wrapped unwrapped
+    //   dupat 2          // classObj classCtor classProto wrapped unwrapped classProto
+    //   inithomeobject   // classObj classCtor classProto wrapped unwrapped
     //                    //   initialize the home object of unwrapped
     //                    //   with classProto here
     //   pop              // classObj classCtor classProto wrapped
     //   inithiddenprop   // classObj classCtor classProto wrapped
     //                    //   initialize the property of the classProto
     //                    //   with wrapped function here
     //   pop              // classObj classCtor classProto
     //
@@ -7897,17 +7898,20 @@ BytecodeEmitter::emitPropertyList(ListNo
             FunctionBox* funbox = propVal->as<CodeNode>().funbox();
             MOZ_ASSERT(funbox->function()->allowSuperProperty());
             bool isAsync = funbox->isAsync();
             if (isAsync) {
                 if (!emit1(JSOP_SWAP)) {
                     return false;
                 }
             }
-            if (!emit2(JSOP_INITHOMEOBJECT, isIndex + isAsync)) {
+            if (!emitDupAt(1 + isIndex + isAsync)) {
+                return false;
+            }
+            if (!emit1(JSOP_INITHOMEOBJECT)) {
                 return false;
             }
             if (isAsync) {
                 if (!emit1(JSOP_POP)) {
                     return false;
                 }
             }
         }
@@ -8801,17 +8805,21 @@ BytecodeEmitter::emitClass(ClassNode* cl
     // is not used, an implicit value of %FunctionPrototype% is implied.
 
     if (constructor) {
         if (!emitFunction(constructor, !!heritageExpression)) {
             //                [stack] ... HOMEOBJ CONSTRUCTOR
             return false;
         }
         if (constructor->funbox()->needsHomeObject()) {
-            if (!emit2(JSOP_INITHOMEOBJECT, 0)) {
+            if (!emitDupAt(1)) {
+                //            [stack] ... HOMEOBJ CONSTRUCTOR HOMEOBJ
+                return false;
+            }
+            if (!emit1(JSOP_INITHOMEOBJECT)) {
                 //            [stack] ... HOMEOBJ CONSTRUCTOR
                 return false;
             }
         }
     } else {
         // In the case of default class constructors, emit the start and end
         // offsets in the source buffer as source notes so that when we
         // actually make the constructor during execution, we can give it the
--- a/js/src/jit/BaselineCompiler.cpp
+++ b/js/src/jit/BaselineCompiler.cpp
@@ -5323,22 +5323,18 @@ BaselineCompiler::emit_JSOP_CHECKCLASSHE
     prepareVMCall();
     pushArg(R0);
     return callVM(CheckClassHeritageOperationInfo);
 }
 
 bool
 BaselineCompiler::emit_JSOP_INITHOMEOBJECT()
 {
-    frame.syncStack(0);
-
-    // Load HomeObject off stack
-    unsigned skipOver = GET_UINT8(pc);
-    MOZ_ASSERT(frame.stackDepth() >= skipOver + 2);
-    masm.loadValue(frame.addressOfStackValue(frame.peek(-2 - skipOver)), R0);
+    // Load HomeObject in R0.
+    frame.popRegsAndSync(1);
 
     // Load function off stack
     Register func = R2.scratchReg();
     masm.unboxObject(frame.addressOfStackValue(frame.peek(-1)), func);
 
     // Set HOMEOBJECT_SLOT
     Address addr(func, FunctionExtended::offsetOfMethodHomeObjectSlot());
     masm.guardedCallPreBarrier(addr, MIRType::Value);
--- a/js/src/vm/BytecodeUtil.cpp
+++ b/js/src/vm/BytecodeUtil.cpp
@@ -702,19 +702,19 @@ BytecodeParser::simulateOp(JSOp op, uint
       case JSOP_INITIALYIELD:
       case JSOP_ITERNEXT:
         // Keep the top value.
         MOZ_ASSERT(nuses == 1);
         MOZ_ASSERT(ndefs == 1);
         break;
 
       case JSOP_INITHOMEOBJECT:
-        // Keep the top 2 values.
+        // Pop the top value, keep the other value.
         MOZ_ASSERT(nuses == 2);
-        MOZ_ASSERT(ndefs == 2);
+        MOZ_ASSERT(ndefs == 1);
         break;
 
       case JSOP_SETGNAME:
       case JSOP_SETNAME:
       case JSOP_SETPROP:
       case JSOP_STRICTSETGNAME:
       case JSOP_STRICTSETNAME:
       case JSOP_STRICTSETPROP:
--- a/js/src/vm/Interpreter.cpp
+++ b/js/src/vm/Interpreter.cpp
@@ -4719,29 +4719,28 @@ CASE(JSOP_OBJWITHPROTO)
     }
 
     REGS.sp[-1].setObject(*obj);
 }
 END_CASE(JSOP_OBJWITHPROTO)
 
 CASE(JSOP_INITHOMEOBJECT)
 {
-    unsigned skipOver = GET_UINT8(REGS.pc);
-    MOZ_ASSERT(REGS.stackDepth() >= skipOver + 2);
+    MOZ_ASSERT(REGS.stackDepth() >= 2);
 
     /* Load the function to be initialized */
-    ReservedRooted<JSFunction*> func(&rootFunction0, &REGS.sp[-1].toObject().as<JSFunction>());
+    ReservedRooted<JSFunction*> func(&rootFunction0, &REGS.sp[-2].toObject().as<JSFunction>());
     MOZ_ASSERT(func->allowSuperProperty());
 
     /* Load the home object */
-    ReservedRooted<JSObject*> obj(&rootObject0);
-    obj = &REGS.sp[int(-2 - skipOver)].toObject();
+    ReservedRooted<JSObject*> obj(&rootObject0, &REGS.sp[-1].toObject());
     MOZ_ASSERT(obj->is<PlainObject>() || obj->is<UnboxedPlainObject>() || obj->is<JSFunction>());
 
     func->setExtendedSlot(FunctionExtended::METHOD_HOMEOBJECT_SLOT, ObjectValue(*obj));
+    REGS.sp--;
 }
 END_CASE(JSOP_INITHOMEOBJECT)
 
 CASE(JSOP_SUPERBASE)
 {
     JSFunction& superEnvFunc = GetSuperEnvFunction(cx, REGS);
     MOZ_ASSERT(superEnvFunc.allowSuperProperty());
     MOZ_ASSERT(superEnvFunc.nonLazyScript()->needsHomeObject());
--- a/js/src/vm/Opcodes.h
+++ b/js/src/vm/Opcodes.h
@@ -915,24 +915,24 @@
      *   Operands: uint32_t baseobjIndex
      *   Stack: => obj
      */ \
     MACRO(JSOP_NEWOBJECT, 91, "newobject", NULL, 5, 0, 1, JOF_OBJECT|JOF_IC) \
     /*
      * Initialize the home object for functions with super bindings.
      *
      * This opcode takes the function and the object to be the home object,
-     * does the set, and leaves both on the stack.
+     * does the set, and leaves the function on the stack.
      *
      *   Category: Literals
      *   Type: Object
-     *   Operands: uint8_t n
-     *   Stack: homeObject, [...n], fun => homeObject, [...n], fun
+     *   Operands:
+     *   Stack: fun, homeObject => fun
      */ \
-    MACRO(JSOP_INITHOMEOBJECT, 92, "inithomeobject", NULL, 2, 2, 2, JOF_UINT8) \
+    MACRO(JSOP_INITHOMEOBJECT, 92, "inithomeobject", NULL, 1, 2, 1, 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