Bug 922028 - Only intern iterator result object shapes in compileAndGo mode. r=jorendorff
authorAndy Wingo <wingo@igalia.com>
Mon, 30 Sep 2013 12:53:20 +0200
changeset 149453 6682ed134766597270c1a33fb563c8970ed4499c
parent 149452 133d0dee12eefccbccf8a4cbe1ed47253182cf55
child 149454 09cca9f3210390ef5c6ef51ff78202309a65188b
push id25389
push userryanvm@gmail.com
push dateTue, 01 Oct 2013 20:35:30 +0000
treeherdermozilla-central@4364824a4cab [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjorendorff
bugs922028
milestone27.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 922028 - Only intern iterator result object shapes in compileAndGo mode. r=jorendorff
js/src/frontend/BytecodeEmitter.cpp
--- a/js/src/frontend/BytecodeEmitter.cpp
+++ b/js/src/frontend/BytecodeEmitter.cpp
@@ -1794,18 +1794,39 @@ BytecodeEmitter::reportStrictModeError(P
     va_start(args, errorNumber);
     bool result = tokenStream()->reportStrictModeErrorNumberVA(pos.begin, sc->strict,
                                                                errorNumber, args);
     va_end(args);
     return result;
 }
 
 static bool
+EmitNewInit(ExclusiveContext *cx, BytecodeEmitter *bce, JSProtoKey key)
+{
+    const size_t len = 1 + UINT32_INDEX_LEN;
+    ptrdiff_t offset = EmitCheck(cx, bce, len);
+    if (offset < 0)
+        return false;
+
+    jsbytecode *code = bce->code(offset);
+    code[0] = JSOP_NEWINIT;
+    code[1] = jsbytecode(key);
+    code[2] = 0;
+    code[3] = 0;
+    code[4] = 0;
+    UpdateDepth(cx, bce, offset);
+    CheckTypeSet(cx, bce, JSOP_NEWINIT);
+    return true;
+}
+
+static bool
 IteratorResultShape(ExclusiveContext *cx, BytecodeEmitter *bce, unsigned *shape)
 {
+    JS_ASSERT(bce->script->compileAndGo);
+
     RootedObject obj(cx);
     gc::AllocKind kind = GuessObjectGCKind(2);
     obj = NewBuiltinClassInstance(cx, &JSObject::class_, kind);
     if (!obj)
         return false;
 
     Rooted<jsid> value_id(cx, AtomToId(cx->names().value));
     Rooted<jsid> done_id(cx, AtomToId(cx->names().done));
@@ -1824,20 +1845,24 @@ IteratorResultShape(ExclusiveContext *cx
     *shape = bce->objectList.add(objbox);
 
     return true;
 }
 
 static bool
 EmitPrepareIteratorResult(ExclusiveContext *cx, BytecodeEmitter *bce)
 {
-    unsigned shape;
-    if (!IteratorResultShape(cx, bce, &shape))
-        return false;
-    return EmitIndex32(cx, JSOP_NEWOBJECT, shape, bce);
+    if (bce->script->compileAndGo) {
+        unsigned shape;
+        if (!IteratorResultShape(cx, bce, &shape))
+            return false;
+        return EmitIndex32(cx, JSOP_NEWOBJECT, shape, bce);
+    }
+
+    return EmitNewInit(cx, bce, JSProto_Object);
 }
 
 static bool
 EmitFinishIteratorResult(ExclusiveContext *cx, BytecodeEmitter *bce, bool done)
 {
     jsatomid value_id;
     if (!bce->makeAtomIndex(cx->names().value, &value_id))
         return UINT_MAX;
@@ -3555,35 +3580,16 @@ EmitAssignment(ExclusiveContext *cx, Byt
         break;
 #endif
       default:
         JS_ASSERT(0);
     }
     return true;
 }
 
-static bool
-EmitNewInit(ExclusiveContext *cx, BytecodeEmitter *bce, JSProtoKey key, ParseNode *pn)
-{
-    const size_t len = 1 + UINT32_INDEX_LEN;
-    ptrdiff_t offset = EmitCheck(cx, bce, len);
-    if (offset < 0)
-        return false;
-
-    jsbytecode *code = bce->code(offset);
-    code[0] = JSOP_NEWINIT;
-    code[1] = jsbytecode(key);
-    code[2] = 0;
-    code[3] = 0;
-    code[4] = 0;
-    UpdateDepth(cx, bce, offset);
-    CheckTypeSet(cx, bce, JSOP_NEWINIT);
-    return true;
-}
-
 bool
 ParseNode::getConstantValue(ExclusiveContext *cx, bool strictChecks, MutableHandleValue vp)
 {
     switch (getKind()) {
       case PNK_NUMBER:
         vp.setNumber(pn_dval);
         return true;
       case PNK_STRING:
@@ -5630,17 +5636,17 @@ EmitObject(ExclusiveContext *cx, Bytecod
      * Emit code for {p:a, '%q':b, 2:c} that is equivalent to constructing
      * a new object and in source order evaluating each property value and
      * adding the property to the object, without invoking latent setters.
      * We use the JSOP_NEWINIT and JSOP_INITELEM/JSOP_INITPROP bytecodes to
      * ignore setters and to avoid dup'ing and popping the object as each
      * property is added, as JSOP_SETELEM/JSOP_SETPROP would do.
      */
     ptrdiff_t offset = bce->offset();
-    if (!EmitNewInit(cx, bce, JSProto_Object, pn))
+    if (!EmitNewInit(cx, bce, JSProto_Object))
         return false;
 
     /*
      * Try to construct the shape of the object as we go, so we can emit a
      * JSOP_NEWOBJECT with the final shape instead.
      */
     RootedObject obj(cx);
     if (bce->script->compileAndGo) {
@@ -5729,17 +5735,17 @@ EmitObject(ExclusiveContext *cx, Bytecod
     }
 
     return true;
 }
 
 static bool
 EmitArrayComp(ExclusiveContext *cx, BytecodeEmitter *bce, ParseNode *pn)
 {
-    if (!EmitNewInit(cx, bce, JSProto_Array, pn))
+    if (!EmitNewInit(cx, bce, JSProto_Array))
         return false;
 
     /*
      * Pass the new array's stack index to the PNK_ARRAYPUSH case via
      * bce->arrayCompDepth, then simply traverse the PNK_FOR node and
      * its kids under pn2 to generate this comprehension.
      */
     JS_ASSERT(bce->stackDepth > 0);