Bug 669786: JSCodeGenerator::upvarMap should be a js::Vector. (r=njn)
authorChris Leary <cdleary@mozilla.com>
Wed, 06 Jul 2011 18:00:17 -0700
changeset 72839 2bdcc80c8324ec330507c9a7dab619369299e128
parent 72838 4fc08ab607dba39c3dc07db634627c845ceeb0b7
child 72840 3cd0a17b27bf7176c3d7d720c84feaab3b17bfe7
push id20776
push usereakhgari@mozilla.com
push dateFri, 15 Jul 2011 12:13:35 +0000
treeherdermozilla-central@9349ae9094f6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnjn
bugs669786
milestone8.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 669786: JSCodeGenerator::upvarMap should be a js::Vector. (r=njn)
js/src/jsemit.cpp
js/src/jsemit.h
js/src/jsprvtd.h
js/src/jsscript.cpp
--- a/js/src/jsemit.cpp
+++ b/js/src/jsemit.cpp
@@ -116,29 +116,29 @@ JSCodeGenerator::JSCodeGenerator(Parser 
     ntrynotes(0), lastTryNode(NULL),
     spanDeps(NULL), jumpTargets(NULL), jtFreeList(NULL),
     numSpanDeps(0), numJumpTargets(0), spanDepTodo(0),
     arrayCompDepth(0),
     emitLevel(0),
     constMap(parser->context),
     constList(parser->context),
     upvarIndices(parser->context),
+    upvarMap(parser->context),
     globalUses(parser->context),
     globalMap(parser->context),
     closedArgs(parser->context),
     closedVars(parser->context),
     traceIndex(0)
 {
     flags = TCF_COMPILING;
     memset(&prolog, 0, sizeof prolog);
     memset(&main, 0, sizeof main);
     current = &main;
     firstLine = prolog.currentLine = main.currentLine = lineno;
     prolog.noteMask = main.noteMask = SRCNOTE_CHUNK - 1;
-    memset(&upvarMap, 0, sizeof upvarMap);
 }
 
 bool
 JSCodeGenerator::init(JSContext *cx, JSTreeContext::InitBehavior ib)
 {
     roLexdeps.init();
     return JSTreeContext::init(cx, ib) && constMap.init() && atomIndices.ensureMap(cx);
 }
@@ -148,19 +148,16 @@ JSCodeGenerator::~JSCodeGenerator()
     JS_ARENA_RELEASE(codePool, codeMark);
     JS_ARENA_RELEASE(notePool, noteMark);
 
     JSContext *cx = parser->context;
 
     /* NB: non-null only after OOM. */
     if (spanDeps)
         cx->free_(spanDeps);
-
-    if (upvarMap.vector)
-        cx->free_(upvarMap.vector);
 }
 
 static ptrdiff_t
 EmitCheck(JSContext *cx, JSCodeGenerator *cg, JSOp op, ptrdiff_t delta)
 {
     jsbytecode *base, *limit, *next;
     ptrdiff_t offset, length;
     size_t incr, size;
@@ -2308,40 +2305,36 @@ BindNameToSlot(JSContext *cx, JSCodeGene
         } else {
             if (!cg->bindings.addUpvar(cx, atom))
                 return JS_FALSE;
 
             index = cg->upvarIndices->count();
             if (!cg->upvarIndices->add(p, atom, index))
                 return JS_FALSE;
 
-            UpvarCookie *vector = cg->upvarMap.vector;
-            uint32 length = cg->roLexdeps->count();
-            if (!vector || cg->upvarMap.length != length) {
-                vector = (UpvarCookie *) cx->realloc_(vector, length * sizeof *vector);
-                if (!vector) {
-                    JS_ReportOutOfMemory(cx);
-                    return JS_FALSE;
-                }
-                cg->upvarMap.vector = vector;
-                cg->upvarMap.length = length;
-            }
+            UpvarCookies &upvarMap = cg->upvarMap;
+            /* upvarMap should have the same number of UpvarCookies as there are lexdeps. */
+            size_t lexdepCount = cg->roLexdeps->count();
+
+            JS_ASSERT_IF(!upvarMap.empty(), lexdepCount == upvarMap.length());
+            if (upvarMap.empty() && !upvarMap.appendN(UpvarCookie(), lexdepCount))
+                return JS_FALSE;
 
             uintN slot = cookie.slot();
             if (slot != UpvarCookie::CALLEE_SLOT && dn_kind != JSDefinition::ARG) {
                 JSTreeContext *tc = cg;
                 do {
                     tc = tc->parent;
                 } while (tc->staticLevel != level);
                 if (tc->inFunction())
                     slot += tc->fun()->nargs;
             }
 
-            JS_ASSERT(index < cg->upvarMap.length);
-            vector[index].set(skip, slot);
+            JS_ASSERT(index < upvarMap.length());
+            upvarMap[index].set(skip, slot);
         }
 
         pn->pn_op = JSOP_GETFCSLOT;
         JS_ASSERT((index & JS_BITMASK(16)) == index);
         pn->pn_cookie.set(0, index);
         pn->pn_dflags |= PND_BOUND;
         return JS_TRUE;
     }
--- a/js/src/jsemit.h
+++ b/js/src/jsemit.h
@@ -639,17 +639,18 @@ struct JSCodeGenerator : public JSTreeCo
 
     JSGCConstList   constList;      /* constants to be included with the script */
 
     JSCGObjectList  objectList;     /* list of emitted objects */
     JSCGObjectList  regexpList;     /* list of emitted regexp that will be
                                        cloned during execution */
 
     js::OwnedAtomIndexMapPtr upvarIndices; /* map of atoms to upvar indexes */
-    JSUpvarArray    upvarMap;       /* indexed upvar pairs (JS_realloc'ed) */
+
+    js::UpvarCookies upvarMap;      /* indexed upvar slot locations */
 
     typedef js::Vector<js::GlobalSlotArray::Entry, 16> GlobalUseVector;
 
     GlobalUseVector globalUses;     /* per-script global uses */
     js::OwnedAtomIndexMapPtr globalMap; /* per-script map of global name to globalUses vector */
 
     /* Vectors of pn_cookie slot values. */
     typedef js::Vector<uint32, 8> SlotVector;
--- a/js/src/jsprvtd.h
+++ b/js/src/jsprvtd.h
@@ -150,16 +150,17 @@ class CallReceiver;
 class CallArgs;
 
 struct Compiler;
 struct Parser;
 class TokenStream;
 struct Token;
 struct TokenPos;
 struct TokenPtr;
+class UpvarCookie;
 
 class TempAllocPolicy;
 
 template <class T,
           size_t MinInlineCapacity = 0,
           class AllocPolicy = TempAllocPolicy>
 class Vector;
 
@@ -187,19 +188,20 @@ struct PropertyCacheEntry;
 
 struct Shape;
 struct EmptyShape;
 class Bindings;
 
 class MultiDeclRange;
 class ParseMapPool;
 class DefnOrHeader;
-typedef js::InlineMap<JSAtom *, JSDefinition *, 24> AtomDefnMap;
-typedef js::InlineMap<JSAtom *, jsatomid, 24> AtomIndexMap;
-typedef js::InlineMap<JSAtom *, DefnOrHeader, 24> AtomDOHMap;
+typedef InlineMap<JSAtom *, JSDefinition *, 24> AtomDefnMap;
+typedef InlineMap<JSAtom *, jsatomid, 24> AtomIndexMap;
+typedef InlineMap<JSAtom *, DefnOrHeader, 24> AtomDOHMap;
+typedef Vector<UpvarCookie> UpvarCookies;
 
 } /* namespace js */
 
 } /* export "C++" */
 
 #else
 
 typedef struct JSAtom JSAtom;
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -1295,22 +1295,21 @@ JSScript::NewScriptFromCG(JSContext *cx,
     if (cg->callsEval())
         script->usesEval = true;
     if (cg->flags & TCF_FUN_USES_ARGUMENTS)
         script->usesArguments = true;
     if (cg->flags & TCF_HAS_SINGLETONS)
         script->hasSingletons = true;
 
     if (cg->hasUpvarIndices()) {
-        JS_ASSERT(cg->upvarIndices->count() <= cg->upvarMap.length);
-        memcpy(script->upvars()->vector, cg->upvarMap.vector,
-               cg->upvarIndices->count() * sizeof(uint32));
+        JS_ASSERT(cg->upvarIndices->count() <= cg->upvarMap.length());
+        memcpy(script->upvars()->vector, cg->upvarMap.begin(),
+               cg->upvarIndices->count() * sizeof(cg->upvarMap[0]));
         cg->upvarIndices->clear();
-        cx->free_(cg->upvarMap.vector);
-        cg->upvarMap.vector = NULL;
+        cg->upvarMap.clear();
     }
 
     if (cg->globalUses.length()) {
         memcpy(script->globals()->vector, &cg->globalUses[0],
                cg->globalUses.length() * sizeof(GlobalSlotArray::Entry));
     }
 
     if (script->nClosedArgs)