Bug 722121 - Remove JSOP_DEFFUN_FC, because it can never be generated. r=jorendorff
authorJeff Walden <jwalden@mit.edu>
Sat, 28 Jan 2012 22:46:08 -0800
changeset 89427 fa99b3a04938c4e359ff066394fcf4156b7802a9
parent 89426 bb8e2ee240719b413df888e28a3b371832931e63
child 89428 6d1c5d3a29ff276e819f4067bd65c8cb6daefabb
push id783
push userlsblakk@mozilla.com
push dateTue, 24 Apr 2012 17:33:42 +0000
treeherdermozilla-beta@11faed19f136 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs722121
milestone13.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 722121 - Remove JSOP_DEFFUN_FC, because it can never be generated. r=jorendorff
js/src/frontend/BytecodeEmitter.cpp
js/src/frontend/SemanticAnalysis.cpp
js/src/jsinfer.cpp
js/src/jsinterp.cpp
js/src/jsopcode.cpp
js/src/jsopcode.tbl
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -5133,18 +5133,19 @@ EmitFunc(JSContext *cx, BytecodeEmitter 
      * definitions can be scheduled before generating the rest of code.
      */
     if (!bce->inFunction()) {
         JS_ASSERT(!bce->topStmt);
         if (!BindGlobal(cx, bce, pn, fun->atom))
             return false;
         if (pn->pn_cookie.isFree()) {
             bce->switchToProlog();
-            JSOp op = fun->isFlatClosure() ? JSOP_DEFFUN_FC : JSOP_DEFFUN;
-            if (!EmitFunctionOp(cx, op, index, bce))
+            MOZ_ASSERT(!fun->isFlatClosure(),
+                       "global functions can't have upvars, so they are never flat");
+            if (!EmitFunctionOp(cx, JSOP_DEFFUN, index, bce))
                 return false;
             bce->switchToMain();
         }
 
         /* Emit NOP for the decompiler. */
         if (!EmitFunctionDefNop(cx, bce, index))
             return false;
     } else {
--- a/js/src/frontend/SemanticAnalysis.cpp
+++ b/js/src/frontend/SemanticAnalysis.cpp
@@ -565,25 +565,30 @@ SetFunctionKinds(FunctionBox *funbox, ui
                              */
                             canFlatten = false;
                             break;
                         }
                     }
                 }
             }
 
+            /*
+             * Top-level functions, and (extension) functions not at top level
+             * which are also not directly within other functions, aren't
+             * flattened.
+             */
+            if (fn->isOp(JSOP_DEFFUN))
+                canFlatten = false;
+
             if (!hasUpvars) {
                 /* No lexical dependencies => null closure, for best performance. */
                 fun->setKind(JSFUN_NULL_CLOSURE);
             } else if (canFlatten) {
                 fun->setKind(JSFUN_FLAT_CLOSURE);
                 switch (fn->getOp()) {
-                  case JSOP_DEFFUN:
-                    fn->setOp(JSOP_DEFFUN_FC);
-                    break;
                   case JSOP_DEFLOCALFUN:
                     fn->setOp(JSOP_DEFLOCALFUN_FC);
                     break;
                   case JSOP_LAMBDA:
                     fn->setOp(JSOP_LAMBDA_FC);
                     break;
                   default:
                     /* js::frontend::EmitTree's PNK_FUNCTION case sets op. */
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -3817,17 +3817,16 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
       case JSOP_NEG:
       case JSOP_POS:
         poppedTypes(pc, 0)->addArith(cx, &pushed[0]);
         break;
 
       case JSOP_LAMBDA:
       case JSOP_LAMBDA_FC:
       case JSOP_DEFFUN:
-      case JSOP_DEFFUN_FC:
       case JSOP_DEFLOCALFUN:
       case JSOP_DEFLOCALFUN_FC: {
         unsigned off = (op == JSOP_DEFLOCALFUN || op == JSOP_DEFLOCALFUN_FC) ? SLOTNO_LEN : 0;
         JSObject *obj = script->getObject(GET_UINT32_INDEX(pc + off));
 
         TypeSet *res = NULL;
         if (op == JSOP_LAMBDA || op == JSOP_LAMBDA_FC) {
             res = &pushed[0];
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1739,16 +1739,17 @@ ADD_EMPTY_CASE(JSOP_UNUSED8)
 ADD_EMPTY_CASE(JSOP_UNUSED9)
 ADD_EMPTY_CASE(JSOP_UNUSED10)
 ADD_EMPTY_CASE(JSOP_UNUSED11)
 ADD_EMPTY_CASE(JSOP_UNUSED12)
 ADD_EMPTY_CASE(JSOP_UNUSED13)
 ADD_EMPTY_CASE(JSOP_UNUSED14)
 ADD_EMPTY_CASE(JSOP_UNUSED15)
 ADD_EMPTY_CASE(JSOP_UNUSED16)
+ADD_EMPTY_CASE(JSOP_UNUSED17)
 ADD_EMPTY_CASE(JSOP_CONDSWITCH)
 ADD_EMPTY_CASE(JSOP_TRY)
 #if JS_HAS_XML_SUPPORT
 ADD_EMPTY_CASE(JSOP_STARTXML)
 ADD_EMPTY_CASE(JSOP_STARTXMLEXPR)
 #endif
 ADD_EMPTY_CASE(JSOP_LOOPHEAD)
 ADD_EMPTY_CASE(JSOP_LOOPENTRY)
@@ -3263,45 +3264,16 @@ BEGIN_CASE(JSOP_DEFFUN)
 
         /* Step 5f. */
         if (!parent->setProperty(cx, name, &rval, script->strictModeCode))
             goto error;
     } while (false);
 }
 END_CASE(JSOP_DEFFUN)
 
-BEGIN_CASE(JSOP_DEFFUN_FC)
-{
-    JSFunction *fun = script->getFunction(GET_UINT32_INDEX(regs.pc));
-
-    JSObject *obj = js_NewFlatClosure(cx, fun);
-    if (!obj)
-        goto error;
-
-    Value rval = ObjectValue(*obj);
-
-    uintN attrs = regs.fp()->isEvalFrame()
-                  ? JSPROP_ENUMERATE
-                  : JSPROP_ENUMERATE | JSPROP_PERMANENT;
-
-    JSObject &parent = regs.fp()->varObj();
-
-    PropertyName *name = fun->atom->asPropertyName();
-    if (!CheckRedeclaration(cx, &parent, name, attrs))
-        goto error;
-
-    if ((attrs == JSPROP_ENUMERATE)
-        ? !parent.setProperty(cx, name, &rval, script->strictModeCode)
-        : !parent.defineProperty(cx, name, rval, JS_PropertyStub, JS_StrictPropertyStub, attrs))
-    {
-        goto error;
-    }
-}
-END_CASE(JSOP_DEFFUN_FC)
-
 BEGIN_CASE(JSOP_DEFLOCALFUN)
 {
     /*
      * Define a local function (i.e., one nested at the top level of another
      * function), parented by the current scope chain, stored in a local
      * variable slot that the compiler allocated.  This is an optimization over
      * JSOP_DEFFUN that avoids requiring a call object for the outer function's
      * activation.
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -5128,21 +5128,19 @@ Decompile(SprintStack *ss, jsbytecode *p
                 js_printf(jp, "\tcase ");
                 SprintOpcodePermanent(jp, lval, lvalpc);
                 js_printf(jp, ":\n");
                 todo = -2;
                 break;
               }
 
               case JSOP_DEFFUN:
-              case JSOP_DEFFUN_FC:
                 fun = jp->script->getFunction(GET_UINT32_INDEX(pc));
                 todo = -2;
                 goto do_function;
-                break;
 
               case JSOP_HOLE:
                 todo = SprintPut(&ss->sprinter, "", 0);
                 break;
 
               case JSOP_NEWINIT:
               {
                 i = GET_UINT8(pc);
--- a/js/src/jsopcode.tbl
+++ b/js/src/jsopcode.tbl
@@ -547,20 +547,21 @@ OPDEF(JSOP_LENGTH,        217, "length",
 
 /*
  * Push a JSVAL_HOLE value onto the stack, representing an omitted property in
  * an array literal (e.g. property 0 in the array [, 1]).  This opcode is used
  * with the JSOP_NEWARRAY opcode.
  */
 OPDEF(JSOP_HOLE,          218, "hole",         NULL,  1,  0,  1,  0,  JOF_BYTE)
 
+OPDEF(JSOP_UNUSED17,      219,"unused17",      NULL,  1,  0,  0,  0,  JOF_BYTE)
+
 /*
- * Variants of JSOP_{DEF{,LOCAL}FUN,LAMBDA} optimized for the flat closure case.
+ * Variants of JSOP_{DEFLOCALFUN,LAMBDA} optimized for the flat closure case.
  */
-OPDEF(JSOP_DEFFUN_FC,     219,"deffun_fc",     NULL,  5,  0,  0,  0,  JOF_OBJECT|JOF_DECLARING)
 OPDEF(JSOP_DEFLOCALFUN_FC,220,"deflocalfun_fc",NULL,  7,  0,  0,  0,  JOF_SLOTOBJECT|JOF_DECLARING|JOF_TMPSLOT)
 OPDEF(JSOP_LAMBDA_FC,     221,"lambda_fc",     NULL,  5,  0,  1, 19,  JOF_OBJECT)
 
 /*
  * Joined function object as method optimization support.
  */
 OPDEF(JSOP_SETMETHOD,     222,"setmethod",     NULL,  3,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
 OPDEF(JSOP_INITMETHOD,    223,"initmethod",    NULL,  3,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)