Bug 739512: Patch 10: add JSScripts::hasConsts() et al. r=dvander.
authorNicholas Nethercote <nnethercote@mozilla.com>
Tue, 10 Apr 2012 23:51:10 -0700
changeset 92782 34e6551d2bc1281112464f1a06dc0febbe15cde0
parent 92781 df884799ad23fb44c5bf222154f965d40539a5af
child 92783 0831ce6ba72ffdb1d020e7ecbd5468ac076950d4
push id8869
push usernnethercote@mozilla.com
push dateTue, 01 May 2012 00:57:18 +0000
treeherdermozilla-inbound@0831ce6ba72f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdvander
bugs739512
milestone15.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 739512: Patch 10: add JSScripts::hasConsts() et al. r=dvander.
js/src/frontend/BytecodeCompiler.cpp
js/src/jsdbgapi.cpp
js/src/jsinterp.cpp
js/src/jsobj.cpp
js/src/jsopcode.cpp
js/src/jsscript.cpp
js/src/jsscript.h
js/src/methodjit/InvokeHelpers.cpp
js/src/shell/js.cpp
js/src/vm/Debugger.cpp
js/src/vm/ScopeObject.cpp
--- a/js/src/frontend/BytecodeCompiler.cpp
+++ b/js/src/frontend/BytecodeCompiler.cpp
@@ -107,17 +107,17 @@ DefineGlobals(JSContext *cx, GlobalScope
      * go through all global uses. Each global use indexes into globalScope->defs.
      * Use this information to repoint each use to the correct slot in the global
      * object.
      */
     while (worklist.length()) {
         JSScript *outer = worklist.back();
         worklist.popBack();
 
-        if (JSScript::isValidOffset(outer->objectsOffset)) {
+        if (outer->hasObjects()) {
             JSObjectArray *arr = outer->objects();
 
             /*
              * If this is an eval script, don't treat the saved caller function
              * stored in the first object slot as an inner function.
              */
             size_t start = outer->savedCallerFun ? 1 : 0;
 
@@ -127,26 +127,24 @@ DefineGlobals(JSContext *cx, GlobalScope
                     continue;
                 JSFunction *fun = obj->toFunction();
                 JS_ASSERT(fun->isInterpreted());
                 JSScript *inner = fun->script();
                 if (outer->function() && outer->function()->isHeavyweight()) {
                     outer->isOuterFunction = true;
                     inner->isInnerFunction = true;
                 }
-                if (!JSScript::isValidOffset(inner->globalsOffset) &&
-                    !JSScript::isValidOffset(inner->objectsOffset)) {
+                if (!inner->hasGlobals() && !inner->hasObjects())
                     continue;
-                }
                 if (!worklist.append(inner))
                     return false;
             }
         }
 
-        if (!JSScript::isValidOffset(outer->globalsOffset))
+        if (!outer->hasGlobals())
             continue;
 
         GlobalSlotArray *globalUses = outer->globals();
         uint32_t nGlobalUses = globalUses->length;
         for (uint32_t i = 0; i < nGlobalUses; i++) {
             uint32_t index = globalUses->vector[i].slot;
             JS_ASSERT(index < globalScope.defs.length());
             globalUses->vector[i].slot = globalScope.defs[index].knownSlot;
--- a/js/src/jsdbgapi.cpp
+++ b/js/src/jsdbgapi.cpp
@@ -1012,35 +1012,35 @@ JS_GetScriptTotalSize(JSContext *cx, JSS
     if (script->filename)
         nbytes += strlen(script->filename) + 1;
 
     notes = script->notes();
     for (sn = notes; !SN_IS_TERMINATOR(sn); sn = SN_NEXT(sn))
         continue;
     nbytes += (sn - notes + 1) * sizeof *sn;
 
-    if (JSScript::isValidOffset(script->objectsOffset)) {
+    if (script->hasObjects()) {
         objarray = script->objects();
         size_t i = objarray->length;
         nbytes += sizeof *objarray + i * sizeof objarray->vector[0];
         do {
             nbytes += JS_GetObjectTotalSize(cx, objarray->vector[--i]);
         } while (i != 0);
     }
 
-    if (JSScript::isValidOffset(script->regexpsOffset)) {
+    if (script->hasRegexps()) {
         objarray = script->regexps();
         size_t i = objarray->length;
         nbytes += sizeof *objarray + i * sizeof objarray->vector[0];
         do {
             nbytes += JS_GetObjectTotalSize(cx, objarray->vector[--i]);
         } while (i != 0);
     }
 
-    if (JSScript::isValidOffset(script->trynotesOffset)) {
+    if (script->hasTrynotes()) {
         nbytes += sizeof(JSTryNoteArray) +
             script->trynotes()->length * sizeof(JSTryNote);
     }
 
     principals = script->principals;
     if (principals) {
         JS_ASSERT(principals->refcount);
         pbytes = sizeof *principals;
--- a/js/src/jsinterp.cpp
+++ b/js/src/jsinterp.cpp
@@ -1012,17 +1012,17 @@ js::UnwindForUncatchableException(JSCont
     }
 }
 
 TryNoteIter::TryNoteIter(const FrameRegs &regs)
   : regs(regs),
     script(regs.fp()->script()),
     pcOffset(regs.pc - script->main())
 {
-    if (JSScript::isValidOffset(script->trynotesOffset)) {
+    if (script->hasTrynotes()) {
         tn = script->trynotes()->vector;
         tnEnd = tn + script->trynotes()->length;
     } else {
         tn = tnEnd = NULL;
     }
     settle();
 }
 
--- a/js/src/jsobj.cpp
+++ b/js/src/jsobj.cpp
@@ -812,17 +812,17 @@ EvalCacheLookup(JSContext *cx, JSLinearS
                     /*
                      * Source matches. Make sure there are no inner objects
                      * which might use the wrong parent and/or call scope by
                      * reusing the previous eval's script. Skip the script's
                      * first object, which entrains the eval's scope.
                      */
                     JS_ASSERT(script->objects()->length >= 1);
                     if (script->objects()->length == 1 &&
-                        !JSScript::isValidOffset(script->regexpsOffset)) {
+                        !script->hasRegexps()) {
                         JS_ASSERT(staticLevel == script->staticLevel);
                         *scriptp = script->evalHashLink();
                         script->evalHashLink() = NULL;
                         return script;
                     }
                 }
             }
         }
--- a/js/src/jsopcode.cpp
+++ b/js/src/jsopcode.cpp
@@ -1817,17 +1817,17 @@ GetLocal(SprintStack *ss, int i)
      * for the block containing this local by its stack index, i.
      *
      * In case of destructuring's use of JSOP_GETLOCAL, however, there may be
      * no such local. This could mean no blocks (no script objects at all, or
      * none of the script's object literals are blocks), or the stack slot i is
      * not in a block. In either case, return GetStr(ss, i).
      */
     JSScript *script = ss->printer->script;
-    if (!JSScript::isValidOffset(script->objectsOffset))
+    if (!script->hasObjects())
         return GetStr(ss, i);
 
     // In case of a let variable, the stack points to a JSOP_ENTERBLOCK opcode.
     // Get the object number from the block instead of iterating all objects and
     // hoping the right object is found.
     if (off <= -2 && ss->printer->pcstack) {
         jsbytecode *pc = ss->printer->pcstack[-2 - off];
 
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -423,17 +423,17 @@ js::XDRScript(XDRState<mode> *xdr, JSScr
     nargs = nvars = Bindings::BINDING_COUNT_LIMIT;
 #endif
     uint32_t argsVars;
     if (mode == XDR_ENCODE) {
         script = *scriptp;
         JS_ASSERT_IF(parentScript, parentScript->compartment() == script->compartment());
     
         /* Should not XDR scripts optimized for a single global object. */
-        JS_ASSERT(!JSScript::isValidOffset(script->globalsOffset));
+        JS_ASSERT(!script->hasGlobals());
 
         nargs = script->bindings.numArgs();
         nvars = script->bindings.numVars();
         argsVars = (nargs << 16) | nvars;
     }
     if (!xdr->codeUint32(&argsVars))
         return false;
     if (mode == XDR_DECODE) {
@@ -530,23 +530,23 @@ js::XDRScript(XDRState<mode> *xdr, JSScr
         lineno = script->lineno;
         nslots = (uint32_t)script->nslots;
         nslots = (uint32_t)((script->staticLevel << 16) | script->nslots);
         natoms = script->natoms;
 
         notes = script->notes();
         nsrcnotes = script->numNotes();
 
-        if (JSScript::isValidOffset(script->constsOffset))
+        if (script->hasConsts())
             nconsts = script->consts()->length;
-        if (JSScript::isValidOffset(script->objectsOffset))
+        if (script->hasObjects())
             nobjects = script->objects()->length;
-        if (JSScript::isValidOffset(script->regexpsOffset))
+        if (script->hasRegexps())
             nregexps = script->regexps()->length;
-        if (JSScript::isValidOffset(script->trynotesOffset))
+        if (script->hasTrynotes())
             ntrynotes = script->trynotes()->length;
         /* no globals when encoding;  see assertion above */
         nClosedArgs = script->numClosedArgs();
         nClosedVars = script->numClosedVars();
 
         nTypeSets = script->nTypeSets;
 
         if (script->noScriptRval)
@@ -1988,27 +1988,27 @@ JSScript::markChildren(JSTracer *trc)
 {
     JS_ASSERT_IF(trc->runtime->gcStrictCompartmentChecking, compartment()->isCollecting());
 
     for (uint32_t i = 0; i < natoms; ++i) {
         if (atoms[i])
             MarkString(trc, &atoms[i], "atom");
     }
 
-    if (JSScript::isValidOffset(objectsOffset)) {
+    if (hasObjects()) {
         JSObjectArray *objarray = objects();
         MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
     }
 
-    if (JSScript::isValidOffset(regexpsOffset)) {
+    if (hasRegexps()) {
         JSObjectArray *objarray = regexps();
         MarkObjectRange(trc, objarray->length, objarray->vector, "objects");
     }
 
-    if (JSScript::isValidOffset(constsOffset)) {
+    if (hasConsts()) {
         JSConstArray *constarray = consts();
         MarkValueRange(trc, constarray->length, constarray->vector, "consts");
     }
 
     if (function())
         MarkObject(trc, &function_, "function");
 
     if (!isCachedEval && globalObject)
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -731,57 +731,65 @@ struct JSScript : public js::gc::Cell
     uint32_t numNotes();  /* Number of srcnote slots in the srcnotes section */
 
     /* Script notes are allocated right after the code. */
     jssrcnote *notes() { return (jssrcnote *)(code + length); }
 
     static const uint8_t INVALID_OFFSET = 0xFF;
     static bool isValidOffset(uint8_t offset) { return offset != INVALID_OFFSET; }
 
+    bool hasConsts()        { return isValidOffset(constsOffset);     }
+    bool hasObjects()       { return isValidOffset(objectsOffset);    }
+    bool hasRegexps()       { return isValidOffset(regexpsOffset);    }
+    bool hasTrynotes()      { return isValidOffset(trynotesOffset);   }
+    bool hasGlobals()       { return isValidOffset(globalsOffset);    }
+    bool hasClosedArgs()    { return isValidOffset(closedArgsOffset); }
+    bool hasClosedVars()    { return isValidOffset(closedVarsOffset); }
+
     JSConstArray *consts() {
-        JS_ASSERT(isValidOffset(constsOffset));
+        JS_ASSERT(hasConsts());
         return reinterpret_cast<JSConstArray *>(data + constsOffset);
     }
 
     JSObjectArray *objects() {
-        JS_ASSERT(isValidOffset(objectsOffset));
+        JS_ASSERT(hasObjects());
         return reinterpret_cast<JSObjectArray *>(data + objectsOffset);
     }
 
     JSObjectArray *regexps() {
-        JS_ASSERT(isValidOffset(regexpsOffset));
+        JS_ASSERT(hasRegexps());
         return reinterpret_cast<JSObjectArray *>(data + regexpsOffset);
     }
 
     JSTryNoteArray *trynotes() {
-        JS_ASSERT(isValidOffset(trynotesOffset));
+        JS_ASSERT(hasTrynotes());
         return reinterpret_cast<JSTryNoteArray *>(data + trynotesOffset);
     }
 
     js::GlobalSlotArray *globals() {
-        JS_ASSERT(isValidOffset(globalsOffset));
+        JS_ASSERT(hasGlobals());
         return reinterpret_cast<js::GlobalSlotArray *>(data + globalsOffset);
     }
 
     js::ClosedSlotArray *closedArgs() {
-        JS_ASSERT(isValidOffset(closedArgsOffset));
+        JS_ASSERT(hasClosedArgs());
         return reinterpret_cast<js::ClosedSlotArray *>(data + closedArgsOffset);
     }
 
     js::ClosedSlotArray *closedVars() {
-        JS_ASSERT(isValidOffset(closedVarsOffset));
+        JS_ASSERT(hasClosedVars());
         return reinterpret_cast<js::ClosedSlotArray *>(data + closedVarsOffset);
     }
 
     uint32_t numClosedArgs() {
-        return isValidOffset(closedArgsOffset) ? closedArgs()->length : 0;
+        return hasClosedArgs() ? closedArgs()->length : 0;
     }
 
     uint32_t numClosedVars() {
-        return isValidOffset(closedVarsOffset) ? closedVars()->length : 0;
+        return hasClosedVars() ? closedVars()->length : 0;
     }
 
     js::HeapPtrAtom &getAtom(size_t index) const {
         JS_ASSERT(index < natoms);
         return atoms[index];
     }
 
     js::PropertyName *getName(size_t index) {
--- a/js/src/methodjit/InvokeHelpers.cpp
+++ b/js/src/methodjit/InvokeHelpers.cpp
@@ -73,17 +73,17 @@ using namespace JSC;
 using ic::Repatcher;
 
 static jsbytecode *
 FindExceptionHandler(JSContext *cx)
 {
     StackFrame *fp = cx->fp();
     JSScript *script = fp->script();
 
-    if (!JSScript::isValidOffset(script->trynotesOffset))
+    if (!script->hasTrynotes())
         return NULL;
 
   error:
     if (cx->isExceptionPending()) {
         for (TryNoteIter tni(cx->regs()); !tni.done(); ++tni) {
             JSTryNote *tn = *tni;
 
             UnwindScope(cx, tn->stackDepth);
--- a/js/src/shell/js.cpp
+++ b/js/src/shell/js.cpp
@@ -1656,17 +1656,17 @@ JS_STATIC_ASSERT(JSTRY_ITER == 2);
 
 static const char* const TryNoteNames[] = { "catch", "finally", "iter" };
 
 static JSBool
 TryNotes(JSContext *cx, JSScript *script, Sprinter *sp)
 {
     JSTryNote *tn, *tnlimit;
 
-    if (!JSScript::isValidOffset(script->trynotesOffset))
+    if (!script->hasTrynotes())
         return JS_TRUE;
 
     tn = script->trynotes()->vector;
     tnlimit = tn + script->trynotes()->length;
     Sprint(sp, "\nException table:\nkind      stack    start      end\n");
     do {
         JS_ASSERT(tn->kind < ArrayLength(TryNoteNames));
         Sprint(sp, " %-7s %6u %8u %8u\n",
@@ -1700,17 +1700,17 @@ DisassembleScript(JSContext *cx, JSScrip
 
     Root<JSScript*> scriptRoot(cx, &script);
 
     if (!js_Disassemble(cx, script, lines, sp))
         return false;
     SrcNotes(cx, script, sp);
     TryNotes(cx, script, sp);
 
-    if (recursive && JSScript::isValidOffset(script->objectsOffset)) {
+    if (recursive && script->hasObjects()) {
         JSObjectArray *objects = script->objects();
         for (unsigned i = 0; i != objects->length; ++i) {
             JSObject *obj = objects->vector[i];
             if (obj->isFunction()) {
                 Sprint(sp, "\n");
                 JSFunction *fun = obj->toFunction();
                 JSScript *nested = fun->maybeScript();
                 if (!DisassembleScript(cx, nested, fun, lines, recursive, sp))
--- a/js/src/vm/Debugger.cpp
+++ b/js/src/vm/Debugger.cpp
@@ -2526,17 +2526,17 @@ static JSBool
 DebuggerScript_getChildScripts(JSContext *cx, unsigned argc, Value *vp)
 {
     THIS_DEBUGSCRIPT_SCRIPT(cx, argc, vp, "getChildScripts", args, obj, script);
     Debugger *dbg = Debugger::fromChildJSObject(obj);
 
     JSObject *result = NewDenseEmptyArray(cx);
     if (!result)
         return false;
-    if (JSScript::isValidOffset(script->objectsOffset)) {
+    if (script->hasObjects()) {
         /*
          * script->savedCallerFun indicates that this is a direct eval script
          * and the calling function is stored as script->objects()->vector[0].
          * It is not really a child script of this script, so skip it.
          */
         JSObjectArray *objects = script->objects();
         for (uint32_t i = script->savedCallerFun ? 1 : 0; i < objects->length; i++) {
             JSObject *obj = objects->vector[i];
--- a/js/src/vm/ScopeObject.cpp
+++ b/js/src/vm/ScopeObject.cpp
@@ -901,17 +901,17 @@ js::XDRStaticBlockObject(XDRState<mode> 
     JSContext *cx = xdr->cx();
 
     StaticBlockObject *obj = NULL;
     uint32_t parentId = 0;
     uint32_t count = 0;
     uint32_t depthAndCount = 0;
     if (mode == XDR_ENCODE) {
         obj = *objp;
-        parentId = JSScript::isValidOffset(script->objectsOffset)
+        parentId = script->hasObjects()
                    ? FindObjectIndex(script->objects(), obj->enclosingBlock())
                    : NO_PARENT_INDEX;
         uint32_t depth = obj->stackDepth();
         JS_ASSERT(depth <= UINT16_MAX);
         count = obj->slotCount();
         JS_ASSERT(count <= UINT16_MAX);
         depthAndCount = (depth << 16) | uint16_t(count);
     }