Use persistent type sets for initializer opcodes, bug 714600. r=dvander
authorBrian Hackett <bhackett1024@gmail.com>
Thu, 05 Jan 2012 06:50:46 -0800
changeset 86327 1a8a06e6c634608db279ebf9a4719add45549f75
parent 86326 26d7324c8d37eac60d1abea7e4f645a55084ca68
child 86328 d9011e124a959f0acc35bff27fdf3239bc53a8ff
push idunknown
push userunknown
push dateunknown
reviewersdvander
bugs714600
milestone12.0a1
Use persistent type sets for initializer opcodes, bug 714600. r=dvander
js/src/frontend/BytecodeEmitter.cpp
js/src/jsinfer.cpp
js/src/jsopcode.tbl
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -4760,16 +4760,17 @@ EmitFunctionDefNop(JSContext *cx, Byteco
            Emit1(cx, bce, JSOP_NOP) >= 0;
 }
 
 static bool
 EmitNewInit(JSContext *cx, BytecodeEmitter *bce, JSProtoKey key, ParseNode *pn, int sharpnum)
 {
     if (Emit3(cx, bce, JSOP_NEWINIT, (jsbytecode) key, 0) < 0)
         return false;
+    CheckTypeSet(cx, bce, JSOP_NEWINIT);
 #if JS_HAS_SHARP_VARS
     if (bce->hasSharps()) {
         if (pn->pn_count != 0)
             EMIT_UINT16_IMM_OP(JSOP_SHARPINIT, bce->sharpSlotBase);
         if (sharpnum >= 0)
             EMIT_UINT16PAIR_IMM_OP(JSOP_DEFSHARP, bce->sharpSlotBase, sharpnum);
     } else {
         JS_ASSERT(sharpnum < 0);
@@ -6972,16 +6973,17 @@ EmitArray(JSContext *cx, BytecodeEmitter
     /* Use the slower NEWINIT for arrays in scripts containing sharps. */
     if (bce->hasSharps()) {
         if (!EmitNewInit(cx, bce, JSProto_Array, pn, sharpnum))
             return false;
     } else {
         ptrdiff_t off = EmitN(cx, bce, JSOP_NEWARRAY, 3);
         if (off < 0)
             return false;
+        CheckTypeSet(cx, bce, JSOP_NEWARRAY);
         jsbytecode *pc = bce->code(off);
         SET_UINT24(pc, pn->pn_count);
     }
 
     ParseNode *pn2 = pn->pn_head;
     jsatomid atomIndex;
     for (atomIndex = 0; pn2; atomIndex++, pn2 = pn2->pn_next) {
         if (!EmitNumberOp(cx, atomIndex, bce))
--- a/js/src/jsinfer.cpp
+++ b/js/src/jsinfer.cpp
@@ -3891,24 +3891,26 @@ ScriptAnalysis::analyzeTypesBytecode(JSC
         poppedTypes(pc, argCount + 1)->addCall(cx, callsite);
         break;
       }
 
       case JSOP_NEWINIT:
       case JSOP_NEWARRAY:
       case JSOP_NEWOBJECT: {
         TypeObject *initializer = GetInitializerType(cx, script, pc);
+        TypeSet *types = script->analysis()->bytecodeTypes(pc);
         if (script->hasGlobal()) {
             if (!initializer)
                 return false;
-            pushed[0].addType(cx, Type::ObjectType(initializer));
+            types->addType(cx, Type::ObjectType(initializer));
         } else {
             JS_ASSERT(!initializer);
-            pushed[0].addType(cx, Type::UnknownType());
+            types->addType(cx, Type::UnknownType());
         }
+        types->addSubset(cx, &pushed[0]);
         break;
       }
 
       case JSOP_ENDINIT:
         break;
 
       case JSOP_INITELEM: {
         const SSAValue &objv = poppedValue(pc, 2);
--- a/js/src/jsopcode.tbl
+++ b/js/src/jsopcode.tbl
@@ -246,19 +246,19 @@ OPDEF(JSOP_UINT16,    88, "uint16",     
 /*
  * Object and array literal support.  NEWINIT takes the kind of initializer
  * (JSProto_Array or JSProto_Object).  NEWARRAY is an array initializer
  * taking the final length, which can be filled in at the start and initialized
  * directly.  NEWOBJECT is an object initializer taking an object with the final
  * shape, which can be set at the start and slots then filled in directly.
  * NEWINIT has an extra byte so it can be exchanged with NEWOBJECT during emit.
  */
-OPDEF(JSOP_NEWINIT,   89, "newinit",    NULL,         3,  0,  1, 19,  JOF_UINT8)
-OPDEF(JSOP_NEWARRAY,  90, "newarray",   NULL,         4,  0,  1, 19,  JOF_UINT24)
-OPDEF(JSOP_NEWOBJECT, 91, "newobject",  NULL,         3,  0,  1, 19,  JOF_OBJECT)
+OPDEF(JSOP_NEWINIT,   89, "newinit",    NULL,         3,  0,  1, 19,  JOF_UINT8|JOF_TYPESET)
+OPDEF(JSOP_NEWARRAY,  90, "newarray",   NULL,         4,  0,  1, 19,  JOF_UINT24|JOF_TYPESET)
+OPDEF(JSOP_NEWOBJECT, 91, "newobject",  NULL,         3,  0,  1, 19,  JOF_OBJECT|JOF_TYPESET)
 OPDEF(JSOP_ENDINIT,   92, "endinit",    NULL,         1,  0,  0, 19,  JOF_BYTE)
 OPDEF(JSOP_INITPROP,  93, "initprop",   NULL,         3,  2,  1,  3,  JOF_ATOM|JOF_PROP|JOF_SET|JOF_DETECTING)
 OPDEF(JSOP_INITELEM,  94, "initelem",   NULL,         1,  3,  1,  3,  JOF_BYTE|JOF_ELEM|JOF_SET|JOF_DETECTING)
 OPDEF(JSOP_DEFSHARP,  95, "defsharp",   NULL,         5,  0,  0,  0,  JOF_UINT16PAIR|JOF_SHARPSLOT)
 OPDEF(JSOP_USESHARP,  96, "usesharp",   NULL,         5,  0,  1,  0,  JOF_UINT16PAIR|JOF_SHARPSLOT)
 
 /* Fast inc/dec ops for args and locals. */
 OPDEF(JSOP_INCARG,    97, "incarg",     NULL,         3,  0,  1, 15,  JOF_QARG |JOF_NAME|JOF_INC|JOF_TMPSLOT3)