From 003501c950a42f72c7be701e8cb2aad4d95c9ac6 Mon Sep 17 00:00:00 2001 From: Terrence Cole Date: Thu, 29 Nov 2012 10:22:12 -0800 Subject: [PATCH] Bug 816779 - Add some exact rooting assertions for JSScript; r=bhackett --HG-- extra : rebase_source : e8318b572b481d68d3b17f6bbd18df297c2f2fc1 --- js/src/builtin/Eval.cpp | 12 +- js/src/frontend/BytecodeCompiler.cpp | 48 ++++---- js/src/frontend/BytecodeCompiler.h | 2 +- js/src/frontend/BytecodeEmitter.cpp | 3 +- js/src/gc/Marking.cpp | 10 +- js/src/gc/Root.h | 31 ++--- js/src/ion/Bailouts.cpp | 8 +- js/src/ion/C1Spewer.cpp | 3 +- js/src/ion/C1Spewer.h | 9 +- js/src/ion/CompileInfo.h | 4 +- js/src/ion/ExecutionModeInlines.h | 10 +- js/src/ion/Ion.cpp | 43 +++---- js/src/ion/Ion.h | 16 +-- js/src/ion/IonCaches.cpp | 4 +- js/src/ion/IonCaches.h | 2 +- js/src/ion/IonCode.h | 2 +- js/src/ion/IonCompartment.h | 2 +- js/src/ion/IonFrameIterator.h | 6 +- js/src/ion/IonFrames.cpp | 4 +- js/src/ion/IonMacroAssembler.h | 2 +- js/src/ion/IonSpewer.cpp | 4 +- js/src/ion/IonSpewer.h | 11 +- js/src/ion/JSONSpewer.cpp | 2 +- js/src/ion/JSONSpewer.h | 5 +- js/src/ion/LIR-Common.h | 2 +- js/src/ion/MIR.h | 12 +- js/src/ion/MIRGraph.h | 4 +- js/src/ion/PcScriptCache.h | 4 +- js/src/ion/SnapshotWriter.h | 2 +- js/src/ion/Snapshots.cpp | 16 +-- js/src/ion/TypeOracle.cpp | 72 ++++++------ js/src/ion/TypeOracle.h | 144 ++++++++++++----------- js/src/ion/VMFunctions.cpp | 2 +- js/src/ion/VMFunctions.h | 2 +- js/src/ion/arm/CodeGenerator-arm.cpp | 2 +- js/src/ion/shared/CodeGenerator-shared.h | 4 +- js/src/ion/x86/CodeGenerator-x86.cpp | 2 +- js/src/jsalloc.h | 1 - js/src/jsanalyze.cpp | 12 +- js/src/jsanalyze.h | 32 ++--- js/src/jsapi.cpp | 2 +- js/src/jscntxt.cpp | 2 +- js/src/jscntxt.h | 4 +- js/src/jsfun.cpp | 10 +- js/src/jsgc.cpp | 2 +- js/src/jsinfer.cpp | 52 ++++---- js/src/jsinfer.h | 7 +- js/src/jsinferinlines.h | 44 ++++--- js/src/jsinterp.cpp | 5 +- js/src/jsobj.cpp | 36 +++--- js/src/jsprobes.cpp | 18 +-- js/src/jsprobes.h | 30 ++--- js/src/jspropertycache.cpp | 2 +- js/src/jsprvtd.h | 6 +- js/src/jsscript.cpp | 26 ++-- js/src/jsscript.h | 55 ++++----- js/src/jsscriptinlines.h | 8 +- js/src/methodjit/Compiler.cpp | 16 +-- js/src/methodjit/InvokeHelpers.cpp | 8 +- js/src/methodjit/MethodJIT.h | 2 +- js/src/methodjit/PolyIC.cpp | 6 +- js/src/methodjit/StubCalls.cpp | 3 +- js/src/shell/js.cpp | 68 ++++++----- js/src/vm/ForkJoin.h | 1 + js/src/vm/GlobalObject.cpp | 2 +- js/src/vm/ObjectImpl.cpp | 1 + js/src/vm/SPSProfiler.cpp | 2 +- js/src/vm/SPSProfiler.h | 2 +- js/src/vm/ScopeObject.cpp | 2 +- js/src/vm/ScopeObject.h | 2 +- js/src/vm/Stack-inl.h | 19 ++- js/src/vm/Stack.cpp | 6 +- js/src/vm/Stack.h | 22 ++-- js/src/vm/Xdr.cpp | 2 +- 74 files changed, 531 insertions(+), 498 deletions(-) diff --git a/js/src/builtin/Eval.cpp b/js/src/builtin/Eval.cpp index 24f8cb5f5585..5214a74f7758 100644 --- a/js/src/builtin/Eval.cpp +++ b/js/src/builtin/Eval.cpp @@ -35,7 +35,7 @@ AssertInnerizedScopeChain(JSContext *cx, JSObject &scopeobj) } static bool -IsEvalCacheCandidate(JSScript *script) +IsEvalCacheCandidate(UnrootedScript script) { // 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 @@ -57,7 +57,7 @@ EvalCacheHashPolicy::hash(const EvalCacheLookup &l) } /* static */ bool -EvalCacheHashPolicy::match(JSScript *script, const EvalCacheLookup &l) +EvalCacheHashPolicy::match(UnrootedScript script, const EvalCacheLookup &l) { JS_ASSERT(IsEvalCacheCandidate(script)); @@ -121,13 +121,13 @@ class EvalScriptGuard if (p_) { script_ = *p_; cx_->runtime->evalCache.remove(p_); - js_CallNewScriptHook(cx_, script_, NULL); + CallNewScriptHook(cx_, script_, NullPtr()); script_->isCachedEval = false; script_->isActiveEval = true; } } - void setNewScript(JSScript *script) { + void setNewScript(UnrootedScript script) { // JSScript::initFromEmitter has already called js_CallNewScriptHook. JS_ASSERT(!script_ && script); script_ = script; @@ -274,8 +274,8 @@ EvalKernel(JSContext *cx, const CallArgs &args, EvalType evalType, StackFrame *c .setNoScriptRval(false) .setPrincipals(principals) .setOriginPrincipals(originPrincipals); - JSScript *compiled = frontend::CompileScript(cx, scopeobj, caller, options, - chars, length, stableStr, staticLevel); + UnrootedScript compiled = frontend::CompileScript(cx, scopeobj, caller, options, + chars, length, stableStr, staticLevel); if (!compiled) return false; diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index 68a636d92147..cd9b65e11e82 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -37,7 +37,7 @@ CheckLength(JSContext *cx, size_t length) } static bool -SetSourceMap(JSContext *cx, TokenStream &tokenStream, ScriptSource *ss, JSScript *script) +SetSourceMap(JSContext *cx, TokenStream &tokenStream, ScriptSource *ss, UnrootedScript script) { if (tokenStream.hasSourceMap()) { if (!ss->setSourceMap(cx, tokenStream.releaseSourceMap(), script->filename)) @@ -46,7 +46,7 @@ SetSourceMap(JSContext *cx, TokenStream &tokenStream, ScriptSource *ss, JSScript return true; } -JSScript * +UnrootedScript frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *callerFrame, const CompileOptions &options, StableCharPtr chars, size_t length, @@ -76,17 +76,17 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call JS_ASSERT_IF(staticLevel != 0, callerFrame); if (!CheckLength(cx, length)) - return NULL; + return UnrootedScript(NULL); JS_ASSERT_IF(staticLevel != 0, options.sourcePolicy != CompileOptions::LAZY_SOURCE); ScriptSource *ss = cx->new_(); if (!ss) - return NULL; + return UnrootedScript(NULL); ScriptSourceHolder ssh(cx->runtime, ss); SourceCompressionToken sct(cx); switch (options.sourcePolicy) { case CompileOptions::SAVE_SOURCE: if (!ss->setSourceCopy(cx, chars, length, false, &sct)) - return NULL; + return UnrootedScript(NULL); break; case CompileOptions::LAZY_SOURCE: ss->setSourceRetrievable(); @@ -97,26 +97,26 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call Parser parser(cx, options, chars, length, /* foldConstants = */ true); if (!parser.init()) - return NULL; + return UnrootedScript(NULL); parser.sct = &sct; GlobalSharedContext globalsc(cx, scopeChain, StrictModeFromContext(cx)); ParseContext pc(&parser, &globalsc, staticLevel, /* bodyid = */ 0); if (!pc.init()) - return NULL; + return UnrootedScript(NULL); bool savedCallerFun = options.compileAndGo && callerFrame && callerFrame->isFunctionFrame(); Rooted script(cx, JSScript::Create(cx, NullPtr(), savedCallerFun, options, staticLevel, ss, 0, length)); if (!script) - return NULL; + return UnrootedScript(NULL); // Global/eval script bindings are always empty (all names are added to the // scope dynamically via JSOP_DEFFUN/VAR). InternalHandle bindings(script, &script->bindings); if (!Bindings::initWithTemporaryStorage(cx, bindings, 0, 0, NULL)) - return NULL; + return UnrootedScript(NULL); // We can specialize a bit for the given scope chain if that scope chain is the global object. JSObject *globalScope = scopeChain && scopeChain == &scopeChain->global() ? (JSObject*) scopeChain : NULL; @@ -126,7 +126,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call BytecodeEmitter bce(/* parent = */ NULL, &parser, &globalsc, script, callerFrame, !!globalScope, options.lineno, options.selfHostingMode); if (!bce.init()) - return NULL; + return UnrootedScript(NULL); /* If this is a direct call to eval, inherit the caller's strictness. */ if (callerFrame && callerFrame->script()->strict) @@ -141,7 +141,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call JSAtom *atom = AtomizeString(cx, source); jsatomid _; if (!atom || !bce.makeAtomIndex(atom, &_)) - return NULL; + return UnrootedScript(NULL); } if (callerFrame && callerFrame->isFunctionFrame()) { @@ -153,7 +153,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call JSFunction *fun = callerFrame->fun(); ObjectBox *funbox = parser.newFunctionBox(fun, &pc, fun->strict()); if (!funbox) - return NULL; + return UnrootedScript(NULL); bce.objectList.add(funbox); } } @@ -173,25 +173,25 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call if (tt == TOK_EOF) break; JS_ASSERT(tt == TOK_ERROR); - return NULL; + return UnrootedScript(NULL); } pn = parser.statement(); if (!pn) - return NULL; + return UnrootedScript(NULL); if (canHaveDirectives) { if (!parser.maybeParseDirective(pn, &canHaveDirectives)) - return NULL; + return UnrootedScript(NULL); } if (!FoldConstants(cx, pn, &parser)) - return NULL; + return UnrootedScript(NULL); if (!NameFunctions(cx, pn)) - return NULL; + return UnrootedScript(NULL); if (!EmitTree(cx, &bce, pn)) - return NULL; + return UnrootedScript(NULL); #if JS_HAS_XML_SUPPORT if (!pn->isKind(PNK_SEMI) || !pn->pn_kid || !pn->pn_kid->isXMLItem()) @@ -201,7 +201,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call } if (!SetSourceMap(cx, tokenStream, ss, script)) - return NULL; + return UnrootedScript(NULL); #if JS_HAS_XML_SUPPORT /* @@ -212,7 +212,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call */ if (pn && onlyXML && !callerFrame) { parser.reportError(NULL, JSMSG_XML_WHOLE_PROGRAM); - return NULL; + return UnrootedScript(NULL); } #endif @@ -222,7 +222,7 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call for (AtomDefnRange r = pc.lexdeps->all(); !r.empty(); r.popFront()) { if (r.front().key() == arguments) { parser.reportError(NULL, JSMSG_ARGUMENTS_AND_REST); - return NULL; + return UnrootedScript(NULL); } } } @@ -232,15 +232,15 @@ frontend::CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *call * do have to emit that here. */ if (Emit1(cx, &bce, JSOP_STOP) < 0) - return NULL; + return UnrootedScript(NULL); if (!JSScript::fullyInitFromEmitter(cx, script, &bce)) - return NULL; + return UnrootedScript(NULL); bce.tellDebuggerAboutCompiledScript(cx); if (!sct.complete()) - return NULL; + return UnrootedScript(NULL); return script; } diff --git a/js/src/frontend/BytecodeCompiler.h b/js/src/frontend/BytecodeCompiler.h index 95e1cf1afa0d..7e7d92f7a8bd 100644 --- a/js/src/frontend/BytecodeCompiler.h +++ b/js/src/frontend/BytecodeCompiler.h @@ -13,7 +13,7 @@ namespace js { namespace frontend { -JSScript * +UnrootedScript CompileScript(JSContext *cx, HandleObject scopeChain, StackFrame *callerFrame, const CompileOptions &options, StableCharPtr chars, size_t length, JSString *source_ = NULL, unsigned staticLevel = 0); diff --git a/js/src/frontend/BytecodeEmitter.cpp b/js/src/frontend/BytecodeEmitter.cpp index 988eb9896e1f..b475830dffcd 100644 --- a/js/src/frontend/BytecodeEmitter.cpp +++ b/js/src/frontend/BytecodeEmitter.cpp @@ -1688,7 +1688,8 @@ BytecodeEmitter::needsImplicitThis() void BytecodeEmitter::tellDebuggerAboutCompiledScript(JSContext *cx) { - js_CallNewScriptHook(cx, script, script->function()); + RootedFunction function(cx, script->function()); + CallNewScriptHook(cx, script, function); if (!parent) { GlobalObject *compileAndGoGlobal = NULL; if (script->compileAndGo) diff --git a/js/src/gc/Marking.cpp b/js/src/gc/Marking.cpp index e5080dbb0f0d..07b57f5fd1e7 100644 --- a/js/src/gc/Marking.cpp +++ b/js/src/gc/Marking.cpp @@ -68,7 +68,7 @@ static inline void PushMarkStack(GCMarker *gcmarker, JSFunction *thing); static inline void -PushMarkStack(GCMarker *gcmarker, JSScript *thing); +PushMarkStack(GCMarker *gcmarker, UnrootedScript thing); static inline void PushMarkStack(GCMarker *gcmarker, UnrootedShape thing); @@ -83,7 +83,7 @@ namespace js { namespace gc { static void MarkChildren(JSTracer *trc, JSString *str); -static void MarkChildren(JSTracer *trc, JSScript *script); +static void MarkChildren(JSTracer *trc, UnrootedScript script); static void MarkChildren(JSTracer *trc, UnrootedShape shape); static void MarkChildren(JSTracer *trc, UnrootedBaseShape base); static void MarkChildren(JSTracer *trc, types::TypeObject *type); @@ -646,7 +646,7 @@ gc::MarkCrossCompartmentSlot(JSTracer *trc, RawObject src, HeapSlot *dst, const /*** Special Marking ***/ void -gc::MarkObject(JSTracer *trc, HeapPtr *thingp, const char *name) +gc::MarkObject(JSTracer *trc, HeapPtr *thingp, const char *name) { JS_SET_TRACING_NAME(trc, name); MarkInternal(trc, thingp->unsafeGet()); @@ -719,7 +719,7 @@ PushMarkStack(GCMarker *gcmarker, types::TypeObject *thing) } static void -PushMarkStack(GCMarker *gcmarker, JSScript *thing) +PushMarkStack(GCMarker *gcmarker, UnrootedScript thing) { JS_COMPARTMENT_ASSERT(gcmarker->runtime, thing); @@ -926,7 +926,7 @@ gc::MarkChildren(JSTracer *trc, JSString *str) } static void -gc::MarkChildren(JSTracer *trc, JSScript *script) +gc::MarkChildren(JSTracer *trc, UnrootedScript script) { script->markChildren(trc); } diff --git a/js/src/gc/Root.h b/js/src/gc/Root.h index 4c7925506514..b3f512d10d50 100644 --- a/js/src/gc/Root.h +++ b/js/src/gc/Root.h @@ -13,6 +13,7 @@ #include "mozilla/TypeTraits.h" #include "mozilla/GuardObjects.h" +#include "js/Utility.h" #include "js/TemplateLib.h" #include "jspubtd.h" @@ -243,6 +244,8 @@ class Handle : public js::HandleBase operator T() const { return get(); } T operator->() const { return get(); } + bool operator!=(const T &other) { return *ptr != other; } + private: Handle() {} @@ -338,7 +341,7 @@ typedef JSFunction * RawFunction; typedef JSScript * RawScript; typedef JSString * RawString; typedef jsid RawId; -typedef Value RawValue; +typedef JS::Value RawValue; /* * InternalHandle is a handle to an internal pointer into a gcthing. Use @@ -393,7 +396,7 @@ class InternalHandle * fromMarkedLocation(). */ InternalHandle(T *field) - : holder(reinterpret_cast(&NullPtr::constNullValue)), + : holder(reinterpret_cast(&JS::NullPtr::constNullValue)), offset(uintptr_t(field)) {} }; @@ -428,7 +431,7 @@ class Unrooted : ptr_(root.get()) { JS_ASSERT(ptr_ != UninitializedTag()); - EnterAssertNoGCScope(); + JS::EnterAssertNoGCScope(); } /* @@ -444,31 +447,31 @@ class Unrooted : ptr_(static_cast(static_cast(other))) { if (ptr_ != UninitializedTag()) - EnterAssertNoGCScope(); + JS::EnterAssertNoGCScope(); } Unrooted(const Unrooted &other) : ptr_(other.ptr_) { if (ptr_ != UninitializedTag()) - EnterAssertNoGCScope(); + JS::EnterAssertNoGCScope(); } Unrooted(const T &p) : ptr_(p) { JS_ASSERT(ptr_ != UninitializedTag()); - EnterAssertNoGCScope(); + JS::EnterAssertNoGCScope(); } Unrooted(const JS::NullPtr &) : ptr_(NULL) { - EnterAssertNoGCScope(); + JS::EnterAssertNoGCScope(); } ~Unrooted() { if (ptr_ != UninitializedTag()) - LeaveAssertNoGCScope(); + JS::LeaveAssertNoGCScope(); } void drop() { if (ptr_ != UninitializedTag()) - LeaveAssertNoGCScope(); + JS::LeaveAssertNoGCScope(); ptr_ = UninitializedTag(); } @@ -476,14 +479,14 @@ class Unrooted Unrooted &operator=(T other) { JS_ASSERT(other != UninitializedTag()); if (ptr_ == UninitializedTag()) - EnterAssertNoGCScope(); + JS::EnterAssertNoGCScope(); ptr_ = other; return *this; } Unrooted &operator=(Unrooted other) { JS_ASSERT(other.ptr_ != UninitializedTag()); if (ptr_ == UninitializedTag()) - EnterAssertNoGCScope(); + JS::EnterAssertNoGCScope(); ptr_ = other.ptr_; return *this; } @@ -771,7 +774,7 @@ Unrooted::Unrooted(const Rooted &root, : ptr_(root.get()) { JS_ASSERT(ptr_ != UninitializedTag()); - EnterAssertNoGCScope(); + JS::EnterAssertNoGCScope(); } #endif /* DEBUG */ @@ -780,7 +783,7 @@ typedef Rooted RootedFunction; typedef Rooted RootedScript; typedef Rooted RootedString; typedef Rooted RootedId; -typedef Rooted RootedValue; +typedef Rooted RootedValue; /* * Mark a stack location as a root for the rooting analysis, without actually @@ -925,7 +928,7 @@ namespace js { */ inline void MaybeCheckStackRoots(JSContext *cx, bool relax = true) { - AssertCanGC(); + JS::AssertCanGC(); #if defined(DEBUG) && defined(JS_GC_ZEAL) && defined(JSGC_ROOT_ANALYSIS) && !defined(JS_THREADSAFE) if (relax && NeedRelaxedRootChecks()) return; diff --git a/js/src/ion/Bailouts.cpp b/js/src/ion/Bailouts.cpp index c289aa1305e2..1c429d753b38 100644 --- a/js/src/ion/Bailouts.cpp +++ b/js/src/ion/Bailouts.cpp @@ -536,7 +536,7 @@ uint32_t ion::BoundsCheckFailure() { JSContext *cx = GetIonContext()->cx; - JSScript *script = GetBailedJSScript(cx); + UnrootedScript script = GetBailedJSScript(cx); IonSpew(IonSpew_Bailouts, "Bounds check failure %s:%d", script->filename, script->lineno); @@ -557,7 +557,7 @@ uint32_t ion::ShapeGuardFailure() { JSContext *cx = GetIonContext()->cx; - JSScript *script = GetBailedJSScript(cx); + UnrootedScript script = GetBailedJSScript(cx); JS_ASSERT(script->hasIonScript()); JS_ASSERT(!script->ion->invalidated()); @@ -573,7 +573,7 @@ uint32_t ion::CachedShapeGuardFailure() { JSContext *cx = GetIonContext()->cx; - JSScript *script = GetBailedJSScript(cx); + UnrootedScript script = GetBailedJSScript(cx); JS_ASSERT(script->hasIonScript()); JS_ASSERT(!script->ion->invalidated()); @@ -622,7 +622,7 @@ ion::ThunkToInterpreter(Value *vp) br->entryfp()->clearRunningInIon(); ScriptFrameIter iter(cx); StackFrame *fp = NULL; - Rooted script(cx, NULL); + Rooted script(cx); do { fp = iter.interpFrame(); script = iter.script(); diff --git a/js/src/ion/C1Spewer.cpp b/js/src/ion/C1Spewer.cpp index d9954715f3e2..60e9244d3269 100644 --- a/js/src/ion/C1Spewer.cpp +++ b/js/src/ion/C1Spewer.cpp @@ -27,7 +27,7 @@ C1Spewer::init(const char *path) } void -C1Spewer::beginFunction(MIRGraph *graph, JSScript *script) +C1Spewer::beginFunction(MIRGraph *graph, HandleScript script) { if (!spewout_) return; @@ -78,7 +78,6 @@ C1Spewer::spewIntervals(const char *pass, LinearScanAllocator *regalloc) void C1Spewer::endFunction() { - return; } void diff --git a/js/src/ion/C1Spewer.h b/js/src/ion/C1Spewer.h index 992c4fd8b4ab..92a7888a574f 100644 --- a/js/src/ion/C1Spewer.h +++ b/js/src/ion/C1Spewer.h @@ -10,6 +10,9 @@ #ifndef jsion_c1spewer_h__ #define jsion_c1spewer_h__ +#include "gc/Root.h" +#include "jsscript.h" + namespace js { namespace ion { @@ -23,16 +26,16 @@ class LInstruction; class C1Spewer { MIRGraph *graph; - JSScript *script; + HandleScript script; FILE *spewout_; public: C1Spewer() - : graph(NULL), script(NULL), spewout_(NULL) + : graph(NULL), script(NullPtr()), spewout_(NULL) { } bool init(const char *path); - void beginFunction(MIRGraph *graph, JSScript *script); + void beginFunction(MIRGraph *graph, HandleScript script); void spewPass(const char *pass); void spewIntervals(const char *pass, LinearScanAllocator *regalloc); void endFunction(); diff --git a/js/src/ion/CompileInfo.h b/js/src/ion/CompileInfo.h index 3793e656f6d9..06c75ae5954c 100644 --- a/js/src/ion/CompileInfo.h +++ b/js/src/ion/CompileInfo.h @@ -30,7 +30,7 @@ enum ExecutionMode { class CompileInfo { public: - CompileInfo(JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing, + CompileInfo(UnrootedScript script, JSFunction *fun, jsbytecode *osrPc, bool constructing, ExecutionMode executionMode) : script_(script), fun_(fun), osrPc_(osrPc), constructing_(constructing), executionMode_(executionMode) @@ -39,7 +39,7 @@ class CompileInfo nslots_ = script->nslots + CountArgSlots(fun); } - JSScript *script() const { + UnrootedScript script() const { return script_; } JSFunction *fun() const { diff --git a/js/src/ion/ExecutionModeInlines.h b/js/src/ion/ExecutionModeInlines.h index 0994c9569711..4a97bd83b267 100644 --- a/js/src/ion/ExecutionModeInlines.h +++ b/js/src/ion/ExecutionModeInlines.h @@ -11,7 +11,7 @@ namespace js { namespace ion { -static inline bool HasIonScript(JSScript *script, ExecutionMode cmode) +static inline bool HasIonScript(UnrootedScript script, ExecutionMode cmode) { switch (cmode) { case SequentialExecution: return script->hasIonScript(); @@ -21,7 +21,7 @@ static inline bool HasIonScript(JSScript *script, ExecutionMode cmode) return false; } -static inline IonScript *GetIonScript(JSScript *script, ExecutionMode cmode) +static inline IonScript *GetIonScript(UnrootedScript script, ExecutionMode cmode) { switch (cmode) { case SequentialExecution: return script->ion; @@ -31,7 +31,7 @@ static inline IonScript *GetIonScript(JSScript *script, ExecutionMode cmode) return NULL; } -static inline void SetIonScript(JSScript *script, ExecutionMode cmode, IonScript *ionScript) +static inline void SetIonScript(UnrootedScript script, ExecutionMode cmode, IonScript *ionScript) { switch (cmode) { case SequentialExecution: script->ion = ionScript; return; @@ -58,7 +58,7 @@ static inline bool CanIonCompile(JSContext *cx, HandleFunction fun, ExecutionMod return CanIonCompile(script, cmode); } -static inline bool CompilingOffThread(JSScript *script, ExecutionMode cmode) +static inline bool CompilingOffThread(UnrootedScript script, ExecutionMode cmode) { switch (cmode) { case SequentialExecution: return script->isIonCompilingOffThread(); @@ -78,7 +78,7 @@ static inline bool CompilingOffThread(HandleScript script, ExecutionMode cmode) return false; } -static inline bool Disabled(JSScript *script, ExecutionMode cmode) { +static inline bool Disabled(UnrootedScript script, ExecutionMode cmode) { switch (cmode) { case SequentialExecution: return script->isIonCompilingOffThread(); case ParallelExecution: return script->isParallelIonCompilingOffThread(); diff --git a/js/src/ion/Ion.cpp b/js/src/ion/Ion.cpp index 9a36658740d0..647943392062 100644 --- a/js/src/ion/Ion.cpp +++ b/js/src/ion/Ion.cpp @@ -479,7 +479,7 @@ IonScript::New(JSContext *cx, uint32_t frameSlots, uint32_t frameSize, size_t sn size_t paddedPrebarrierEntriesSize = AlignBytes(prebarrierEntries * sizeof(CodeOffsetLabel), DataAlignment); size_t paddedSafepointSize = AlignBytes(safepointsSize, DataAlignment); - size_t paddedScriptSize = AlignBytes(scriptEntries * sizeof(JSScript *), DataAlignment); + size_t paddedScriptSize = AlignBytes(scriptEntries * sizeof(RawScript), DataAlignment); size_t bytes = paddedSnapshotsSize + paddedBailoutSize + paddedConstantsSize + @@ -770,7 +770,7 @@ ion::ToggleBarriers(JSCompartment *comp, bool needs) IonContext ictx(NULL, comp, NULL); AutoFlushCache afc("ToggleBarriers"); for (gc::CellIterUnderGC i(comp, gc::FINALIZE_SCRIPT); !i.done(); i.next()) { - JSScript *script = i.get(); + UnrootedScript script = i.get(); if (script->hasIonScript()) script->ion->toggleBarriers(needs); } @@ -1122,7 +1122,7 @@ static const size_t BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12; template static bool -IonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing, +IonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing, CompileContext &compileContext) { AssertCanGC(); @@ -1184,7 +1184,8 @@ SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph, JS_ASSERT(!builder->script()->ion); JSContext *cx = GetIonContext()->cx; - IonSpewNewFunction(graph, builder->script()); + RootedScript builderScript(cx, builder->script()); + IonSpewNewFunction(graph, builderScript); if (!builder->build()) { IonSpew(IonSpew_Abort, "Builder failed to build."); @@ -1228,7 +1229,7 @@ SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph, } bool -TestIonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing) +TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing) { SequentialCompileContext compileContext; if (!IonCompile(cx, script, fun, osrPc, constructing, compileContext)) { @@ -1280,7 +1281,7 @@ CheckFrame(StackFrame *fp) } static bool -CheckScript(JSScript *script) +CheckScript(UnrootedScript script) { if (script->needsArgsObj()) { // Functions with arguments objects, are not supported yet. @@ -1297,7 +1298,7 @@ CheckScript(JSScript *script) } static bool -CheckScriptSize(JSScript *script) +CheckScriptSize(UnrootedScript script) { if (!js_IonOptions.limitScriptSize) return true; @@ -1320,7 +1321,7 @@ CheckScriptSize(JSScript *script) } static MethodStatus -Compile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing) +Compile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing) { JS_ASSERT(ion::IsEnabled(cx)); JS_ASSERT_IF(osrPc != NULL, (JSOp)*osrPc == JSOP_LOOPENTRY); @@ -1393,7 +1394,7 @@ ion::CanEnterAtBranch(JSContext *cx, HandleScript script, StackFrame *fp, jsbyte } // Attempt compilation. Returns Method_Compiled if already compiled. - JSFunction *fun = fp->isFunctionFrame() ? fp->fun() : NULL; + RootedFunction fun(cx, fp->isFunctionFrame() ? fp->fun() : NULL); MethodStatus status = Compile(cx, script, fun, pc, fp->isConstructing()); if (status != Method_Compiled) { if (status == Method_CantCompile) @@ -1442,7 +1443,7 @@ ion::CanEnter(JSContext *cx, HandleScript script, StackFrame *fp, bool newType) } // Attempt compilation. Returns Method_Compiled if already compiled. - JSFunction *fun = fp->isFunctionFrame() ? fp->fun() : NULL; + RootedFunction fun(cx, fp->isFunctionFrame() ? fp->fun() : NULL); MethodStatus status = Compile(cx, script, fun, NULL, fp->isConstructing()); if (status != Method_Compiled) { if (status == Method_CantCompile) @@ -1707,7 +1708,7 @@ InvalidateActivation(FreeOp *fop, uint8_t *ionTop, bool invalidateAll) JS_ASSERT(it.isScripted()); IonSpew(IonSpew_Invalidate, "#%d JS frame @ %p, %s:%d (fun: %p, script: %p, pc %p)", frameno, it.fp(), it.script()->filename, it.script()->lineno, - it.maybeCallee(), it.script(), it.returnAddressToFp()); + it.maybeCallee(), (RawScript)it.script(), it.returnAddressToFp()); break; } case IonFrame_Rectifier: @@ -1881,7 +1882,7 @@ ion::Invalidate(types::TypeCompartment &types, FreeOp *fop, break; } JS_ASSERT(co.isValid()); - JSScript *script = co.script; + UnrootedScript script = co.script; IonScript *ionScript = GetIonScript(script, executionMode); JSCompartment *compartment = script->compartment(); @@ -1907,12 +1908,14 @@ ion::Invalidate(types::TypeCompartment &types, FreeOp *fop, void ion::Invalidate(JSContext *cx, const Vector &invalid, bool resetUses) { + AutoAssertNoGC nogc; ion::Invalidate(cx->compartment->types, cx->runtime->defaultFreeOp(), invalid, resetUses); } bool -ion::Invalidate(JSContext *cx, JSScript *script, bool resetUses) +ion::Invalidate(JSContext *cx, UnrootedScript script, bool resetUses) { + AutoAssertNoGC nogc; JS_ASSERT(script->hasIonScript()); Vector scripts(cx); @@ -1924,7 +1927,7 @@ ion::Invalidate(JSContext *cx, JSScript *script, bool resetUses) } void -ion::FinishInvalidation(FreeOp *fop, JSScript *script) +ion::FinishInvalidation(FreeOp *fop, UnrootedScript script) { if (!script->hasIonScript()) return; @@ -1957,7 +1960,7 @@ ion::MarkShapeFromIon(JSRuntime *rt, Shape **shapep) } void -ion::ForbidCompilation(JSContext *cx, JSScript *script) +ion::ForbidCompilation(JSContext *cx, UnrootedScript script) { IonSpew(IonSpew_Abort, "Disabling Ion compilation of script %s:%d", script->filename, script->lineno); @@ -1978,7 +1981,7 @@ ion::ForbidCompilation(JSContext *cx, JSScript *script) } uint32_t -ion::UsesBeforeIonRecompile(JSScript *script, jsbytecode *pc) +ion::UsesBeforeIonRecompile(UnrootedScript script, jsbytecode *pc) { JS_ASSERT(pc == script->code || JSOp(*pc) == JSOP_LOOPENTRY); @@ -2053,7 +2056,7 @@ AutoFlushInhibitor::~AutoFlushInhibitor() int js::ion::LabelBase::id_count = 0; void -ion::PurgeCaches(JSScript *script, JSCompartment *c) { +ion::PurgeCaches(UnrootedScript script, JSCompartment *c) { if (script->hasIonScript()) script->ion->purgeCaches(c); @@ -2062,7 +2065,7 @@ ion::PurgeCaches(JSScript *script, JSCompartment *c) { } size_t -ion::MemoryUsed(JSScript *script, JSMallocSizeOfFun mallocSizeOf) { +ion::MemoryUsed(UnrootedScript script, JSMallocSizeOfFun mallocSizeOf) { size_t result = 0; if (script->hasIonScript()) @@ -2075,7 +2078,7 @@ ion::MemoryUsed(JSScript *script, JSMallocSizeOfFun mallocSizeOf) { } void -ion::DestroyIonScripts(FreeOp *fop, JSScript *script) { +ion::DestroyIonScripts(FreeOp *fop, UnrootedScript script) { if (script->hasIonScript()) ion::IonScript::Destroy(fop, script->ion); @@ -2084,7 +2087,7 @@ ion::DestroyIonScripts(FreeOp *fop, JSScript *script) { } void -ion::TraceIonScripts(JSTracer* trc, JSScript *script) { +ion::TraceIonScripts(JSTracer* trc, UnrootedScript script) { if (script->hasIonScript()) ion::IonScript::Trace(trc, script->ion); diff --git a/js/src/ion/Ion.h b/js/src/ion/Ion.h index 5b7409090afa..ff42e8a02201 100644 --- a/js/src/ion/Ion.h +++ b/js/src/ion/Ion.h @@ -281,7 +281,7 @@ IonExecStatus FastInvoke(JSContext *cx, HandleFunction fun, CallArgsList &args); void Invalidate(types::TypeCompartment &types, FreeOp *fop, const Vector &invalid, bool resetUses = true); void Invalidate(JSContext *cx, const Vector &invalid, bool resetUses = true); -bool Invalidate(JSContext *cx, JSScript *script, bool resetUses = true); +bool Invalidate(JSContext *cx, UnrootedScript script, bool resetUses = true); void MarkValueFromIon(JSRuntime *rt, Value *vp); void MarkShapeFromIon(JSRuntime *rt, Shape **shapep); @@ -295,20 +295,20 @@ class CodeGenerator; CodeGenerator *CompileBackEnd(MIRGenerator *mir); void AttachFinishedCompilations(JSContext *cx); void FinishOffThreadBuilder(IonBuilder *builder); -bool TestIonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing); +bool TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing); static inline bool IsEnabled(JSContext *cx) { return cx->hasRunOption(JSOPTION_ION) && cx->typeInferenceEnabled(); } -void ForbidCompilation(JSContext *cx, JSScript *script); -uint32_t UsesBeforeIonRecompile(JSScript *script, jsbytecode *pc); +void ForbidCompilation(JSContext *cx, UnrootedScript script); +uint32_t UsesBeforeIonRecompile(UnrootedScript script, jsbytecode *pc); -void PurgeCaches(JSScript *script, JSCompartment *c); -size_t MemoryUsed(JSScript *script, JSMallocSizeOfFun mallocSizeOf); -void DestroyIonScripts(FreeOp *fop, JSScript *script); -void TraceIonScripts(JSTracer* trc, JSScript *script); +void PurgeCaches(UnrootedScript script, JSCompartment *c); +size_t MemoryUsed(UnrootedScript script, JSMallocSizeOfFun mallocSizeOf); +void DestroyIonScripts(FreeOp *fop, UnrootedScript script); +void TraceIonScripts(JSTracer* trc, UnrootedScript script); } // namespace ion } // namespace js diff --git a/js/src/ion/IonCaches.cpp b/js/src/ion/IonCaches.cpp index c45eeb794784..c7d0a9bf7d05 100644 --- a/js/src/ion/IonCaches.cpp +++ b/js/src/ion/IonCaches.cpp @@ -795,7 +795,7 @@ js::ion::GetPropertyCache(JSContext *cx, size_t cacheIndex, HandleObject obj, Mu AutoFlushCache afc ("GetPropertyCache"); const SafepointIndex *safepointIndex; void *returnAddr; - JSScript *topScript = GetTopIonJSScript(cx, &safepointIndex, &returnAddr); + RootedScript topScript(cx, GetTopIonJSScript(cx, &safepointIndex, &returnAddr)); IonScript *ion = topScript->ionScript(); IonCacheGetProperty &cache = ion->getCache(cacheIndex).toGetProperty(); @@ -1348,7 +1348,7 @@ js::ion::SetPropertyCache(JSContext *cx, size_t cacheIndex, HandleObject obj, Ha void *returnAddr; const SafepointIndex *safepointIndex; - JSScript *script = GetTopIonJSScript(cx, &safepointIndex, &returnAddr); + RootedScript script(cx, GetTopIonJSScript(cx, &safepointIndex, &returnAddr)); IonScript *ion = script->ion; IonCacheSetProperty &cache = ion->getCache(cacheIndex).toSetProperty(); RootedPropertyName name(cx, cache.name()); diff --git a/js/src/ion/IonCaches.h b/js/src/ion/IonCaches.h index 60e450b433fd..59d1d9507d8e 100644 --- a/js/src/ion/IonCaches.h +++ b/js/src/ion/IonCaches.h @@ -228,7 +228,7 @@ class IonCache return *(IonCacheName *)this; } - void setScriptedLocation(JSScript *script, jsbytecode *pc) { + void setScriptedLocation(UnrootedScript script, jsbytecode *pc) { JS_ASSERT(!idempotent_); this->script = script; this->pc = pc; diff --git a/js/src/ion/IonCode.h b/js/src/ion/IonCode.h index ccff03790e4b..c8bf896d8e49 100644 --- a/js/src/ion/IonCode.h +++ b/js/src/ion/IonCode.h @@ -328,7 +328,7 @@ struct IonScript size_t safepointsSize() const { return safepointsSize_; } - JSScript *getScript(size_t i) const { + UnrootedScript getScript(size_t i) const { JS_ASSERT(i < scriptEntries_); return scriptList()[i]; } diff --git a/js/src/ion/IonCompartment.h b/js/src/ion/IonCompartment.h index d9280f895b73..4ee3b4494ee7 100644 --- a/js/src/ion/IonCompartment.h +++ b/js/src/ion/IonCompartment.h @@ -225,7 +225,7 @@ class IonActivation // Called from JSCompartment::discardJitCode(). void InvalidateAll(FreeOp *fop, JSCompartment *comp); -void FinishInvalidation(FreeOp *fop, JSScript *script); +void FinishInvalidation(FreeOp *fop, UnrootedScript script); } // namespace ion } // namespace js diff --git a/js/src/ion/IonFrameIterator.h b/js/src/ion/IonFrameIterator.h index e92d2c1a71f1..76cf6c83f101 100644 --- a/js/src/ion/IonFrameIterator.h +++ b/js/src/ion/IonFrameIterator.h @@ -129,7 +129,7 @@ class IonFrameIterator JSFunction *callee() const; JSFunction *maybeCallee() const; unsigned numActualArgs() const; - JSScript *script() const; + UnrootedScript script() const; Value *nativeVp() const; Value *actualArgs() const; @@ -291,8 +291,8 @@ class InlineFrameIterator template inline void forEachCanonicalActualArg(Op op, unsigned start, unsigned count) const; - JSScript *script() const { - return script_; + UnrootedScript script() const { + return script_.get(); } jsbytecode *pc() const { return pc_; diff --git a/js/src/ion/IonFrames.cpp b/js/src/ion/IonFrames.cpp index c7307aa6cb2a..88d52b1561e2 100644 --- a/js/src/ion/IonFrames.cpp +++ b/js/src/ion/IonFrames.cpp @@ -155,7 +155,7 @@ IonFrameIterator::isEntryJSFrame() const return true; } -JSScript * +UnrootedScript IonFrameIterator::script() const { AutoAssertNoGC nogc; @@ -401,7 +401,7 @@ MarkCalleeToken(JSTracer *trc, CalleeToken token) } case CalleeToken_Script: { - JSScript *script = CalleeTokenToScript(token); + UnrootedScript script = CalleeTokenToScript(token); MarkScriptRoot(trc, &script, "ion-entry"); JS_ASSERT(script == CalleeTokenToScript(token)); break; diff --git a/js/src/ion/IonMacroAssembler.h b/js/src/ion/IonMacroAssembler.h index 6bebd265c204..f634c5cf458c 100644 --- a/js/src/ion/IonMacroAssembler.h +++ b/js/src/ion/IonMacroAssembler.h @@ -647,7 +647,7 @@ class MacroAssembler : public MacroAssemblerSpecific bind(&stackFull); } - void spsPushFrame(SPSProfiler *p, const char *str, JSScript *s, Register temp) { + void spsPushFrame(SPSProfiler *p, const char *str, UnrootedScript s, Register temp) { Label stackFull; spsProfileEntryAddress(p, 0, temp, &stackFull); diff --git a/js/src/ion/IonSpewer.cpp b/js/src/ion/IonSpewer.cpp index 7a1d5447d225..01bf54d35f32 100644 --- a/js/src/ion/IonSpewer.cpp +++ b/js/src/ion/IonSpewer.cpp @@ -41,7 +41,7 @@ ion::EnableIonDebugLogging() } void -ion::IonSpewNewFunction(MIRGraph *graph, JSScript *function) +ion::IonSpewNewFunction(MIRGraph *graph, HandleScript function) { if (!js_IonOptions.parallelCompilation) ionspewer.beginFunction(graph, function); @@ -94,7 +94,7 @@ IonSpewer::init() } void -IonSpewer::beginFunction(MIRGraph *graph, JSScript *function) +IonSpewer::beginFunction(MIRGraph *graph, HandleScript function) { if (!inited_) return; diff --git a/js/src/ion/IonSpewer.h b/js/src/ion/IonSpewer.h index b21070a5b2b4..87b19bf7c6f9 100644 --- a/js/src/ion/IonSpewer.h +++ b/js/src/ion/IonSpewer.h @@ -72,27 +72,28 @@ class IonSpewer { private: MIRGraph *graph; - JSScript *function; + HandleScript function; C1Spewer c1Spewer; JSONSpewer jsonSpewer; bool inited_; + public: IonSpewer() - : graph(NULL), function(NULL), inited_(false) + : graph(NULL), function(NullPtr()), inited_(false) { } // File output is terminated safely upon destruction. ~IonSpewer(); bool init(); - void beginFunction(MIRGraph *graph, JSScript *); + void beginFunction(MIRGraph *graph, HandleScript); void spewPass(const char *pass); void spewPass(const char *pass, LinearScanAllocator *ra); void endFunction(); }; -void IonSpewNewFunction(MIRGraph *graph, JSScript *function); +void IonSpewNewFunction(MIRGraph *graph, HandleScript function); void IonSpewPass(const char *pass); void IonSpewPass(const char *pass, LinearScanAllocator *ra); void IonSpewEndFunction(); @@ -115,7 +116,7 @@ void EnableIonDebugLogging(); #else -static inline void IonSpewNewFunction(MIRGraph *graph, JSScript *function) +static inline void IonSpewNewFunction(MIRGraph *graph, HandleScript function) { } static inline void IonSpewPass(const char *pass) { } diff --git a/js/src/ion/JSONSpewer.cpp b/js/src/ion/JSONSpewer.cpp index fe202f9208eb..486d0064f67a 100644 --- a/js/src/ion/JSONSpewer.cpp +++ b/js/src/ion/JSONSpewer.cpp @@ -178,7 +178,7 @@ JSONSpewer::init(const char *path) } void -JSONSpewer::beginFunction(JSScript *script) +JSONSpewer::beginFunction(UnrootedScript script) { if (inFunction_) endFunction(); diff --git a/js/src/ion/JSONSpewer.h b/js/src/ion/JSONSpewer.h index b8b4e95c5697..af16cc4361ea 100644 --- a/js/src/ion/JSONSpewer.h +++ b/js/src/ion/JSONSpewer.h @@ -10,6 +10,9 @@ #include +#include "gc/Root.h" +#include "jsscript.h" + struct JSScript; namespace js { @@ -57,7 +60,7 @@ class JSONSpewer ~JSONSpewer(); bool init(const char *path); - void beginFunction(JSScript *script); + void beginFunction(UnrootedScript script); void beginPass(const char * pass); void spewMDef(MDefinition *def); void spewMResumePoint(MResumePoint *rp); diff --git a/js/src/ion/LIR-Common.h b/js/src/ion/LIR-Common.h index 00f19905e491..4c832eb753ee 100644 --- a/js/src/ion/LIR-Common.h +++ b/js/src/ion/LIR-Common.h @@ -3264,7 +3264,7 @@ class LFunctionBoundary : public LInstructionHelper<0, 0, 1> return getTemp(0); } - JSScript *script() { + UnrootedScript script() { return mir_->toFunctionBoundary()->script(); } diff --git a/js/src/ion/MIR.h b/js/src/ion/MIR.h index 6f976af45943..467064d0f84a 100644 --- a/js/src/ion/MIR.h +++ b/js/src/ion/MIR.h @@ -4473,7 +4473,7 @@ class MBindNameCache CompilerRootScript script_; jsbytecode *pc_; - MBindNameCache(MDefinition *scopeChain, PropertyName *name, JSScript *script, jsbytecode *pc) + MBindNameCache(MDefinition *scopeChain, PropertyName *name, UnrootedScript script, jsbytecode *pc) : MUnaryInstruction(scopeChain), name_(name), script_(script), pc_(pc) { setResultType(MIRType_Object); @@ -4482,7 +4482,7 @@ class MBindNameCache public: INSTRUCTION_HEADER(BindNameCache) - static MBindNameCache *New(MDefinition *scopeChain, PropertyName *name, JSScript *script, + static MBindNameCache *New(MDefinition *scopeChain, PropertyName *name, UnrootedScript script, jsbytecode *pc) { return new MBindNameCache(scopeChain, name, script, pc); } @@ -4496,7 +4496,7 @@ class MBindNameCache PropertyName *name() const { return name_; } - JSScript *script() const { + UnrootedScript script() const { return script_; } jsbytecode *pc() const { @@ -5675,7 +5675,7 @@ class MFunctionBoundary : public MNullaryInstruction Type type_; unsigned inlineLevel_; - MFunctionBoundary(JSScript *script, Type type, unsigned inlineLevel) + MFunctionBoundary(UnrootedScript script, Type type, unsigned inlineLevel) : script_(script), type_(type), inlineLevel_(inlineLevel) { JS_ASSERT_IF(type != Inline_Exit, script != NULL); @@ -5686,12 +5686,12 @@ class MFunctionBoundary : public MNullaryInstruction public: INSTRUCTION_HEADER(FunctionBoundary) - static MFunctionBoundary *New(JSScript *script, Type type, + static MFunctionBoundary *New(UnrootedScript script, Type type, unsigned inlineLevel = 0) { return new MFunctionBoundary(script, type, inlineLevel); } - JSScript *script() { + UnrootedScript script() { return script_; } diff --git a/js/src/ion/MIRGraph.h b/js/src/ion/MIRGraph.h index 849ca09e0c3f..009cf151e5a3 100644 --- a/js/src/ion/MIRGraph.h +++ b/js/src/ion/MIRGraph.h @@ -468,7 +468,7 @@ class MIRGraph MStart *osrStart_; // List of compiled/inlined scripts. - Vector scripts_; + Vector scripts_; size_t numBlocks_; @@ -587,7 +587,7 @@ class MIRGraph MStart *osrStart() { return osrStart_; } - bool addScript(JSScript *script) { + bool addScript(UnrootedScript script) { // The same script may be inlined multiple times, add it only once. for (size_t i = 0; i < scripts_.length(); i++) { if (scripts_[i] == script) diff --git a/js/src/ion/PcScriptCache.h b/js/src/ion/PcScriptCache.h index 560bd46f83e4..70863ff70606 100644 --- a/js/src/ion/PcScriptCache.h +++ b/js/src/ion/PcScriptCache.h @@ -20,7 +20,7 @@ struct PcScriptCacheEntry { uint8_t *returnAddress; // Key into the hash table. jsbytecode *pc; // Cached PC. - JSScript *script; // Cached script. + RawScript script; // Cached script. }; struct PcScriptCache @@ -46,7 +46,7 @@ struct PcScriptCache bool get(JSRuntime *rt, uint32_t hash, uint8_t *addr, MutableHandleScript scriptRes, jsbytecode **pcRes); - void add(uint32_t hash, uint8_t *addr, jsbytecode *pc, JSScript *script) { + void add(uint32_t hash, uint8_t *addr, jsbytecode *pc, UnrootedScript script) { entries[hash].returnAddress = addr; entries[hash].pc = pc; entries[hash].script = script; diff --git a/js/src/ion/SnapshotWriter.h b/js/src/ion/SnapshotWriter.h index 6a1b336a30bb..bb9a1560a53f 100644 --- a/js/src/ion/SnapshotWriter.h +++ b/js/src/ion/SnapshotWriter.h @@ -34,7 +34,7 @@ class SnapshotWriter public: SnapshotOffset startSnapshot(uint32_t frameCount, BailoutKind kind, bool resumeAfter); - void startFrame(JSFunction *fun, JSScript *script, jsbytecode *pc, uint32_t exprStack); + void startFrame(JSFunction *fun, UnrootedScript script, jsbytecode *pc, uint32_t exprStack); #ifdef TRACK_SNAPSHOTS void trackFrame(uint32_t pcOpcode, uint32_t mirOpcode, uint32_t mirId, uint32_t lirOpcode, uint32_t lirId); diff --git a/js/src/ion/Snapshots.cpp b/js/src/ion/Snapshots.cpp index d559d84bc193..677859970da6 100644 --- a/js/src/ion/Snapshots.cpp +++ b/js/src/ion/Snapshots.cpp @@ -31,7 +31,7 @@ using namespace js::ion; // Snapshot body, repeated "frame count" times, from oldest frame to newest frame. // Note that the first frame doesn't have the "parent PC" field. // -// [ptr] Debug only: JSScript * +// [ptr] Debug only: RawScript // [vwu] pc offset // [vwu] # of slots, including nargs // [slot*] N slot entries, where N = nargs + nfixed + stackDepth @@ -136,10 +136,10 @@ SnapshotReader::readFrameHeader() #ifdef DEBUG union { - JSScript *script; - uint8_t bytes[sizeof(JSScript *)]; + RawScript script; + uint8_t bytes[sizeof(RawScript)]; } u; - for (size_t i = 0; i < sizeof(JSScript *); i++) + for (size_t i = 0; i < sizeof(RawScript); i++) u.bytes[i] = reader_.readByte(); script_ = u.script; #endif @@ -307,7 +307,7 @@ SnapshotWriter::startSnapshot(uint32_t frameCount, BailoutKind kind, bool resume } void -SnapshotWriter::startFrame(JSFunction *fun, JSScript *script, jsbytecode *pc, uint32_t exprStack) +SnapshotWriter::startFrame(JSFunction *fun, UnrootedScript script, jsbytecode *pc, uint32_t exprStack) { JS_ASSERT(CountArgSlots(fun) < SNAPSHOT_MAX_NARGS); JS_ASSERT(exprStack < SNAPSHOT_MAX_STACK); @@ -322,11 +322,11 @@ SnapshotWriter::startFrame(JSFunction *fun, JSScript *script, jsbytecode *pc, ui #ifdef DEBUG union { - JSScript *script; - uint8_t bytes[sizeof(JSScript *)]; + RawScript script; + uint8_t bytes[sizeof(RawScript)]; } u; u.script = script; - for (size_t i = 0; i < sizeof(JSScript *); i++) + for (size_t i = 0; i < sizeof(RawScript); i++) writer_.writeByte(u.bytes[i]); #endif diff --git a/js/src/ion/TypeOracle.cpp b/js/src/ion/TypeOracle.cpp index c0a350c649b0..696a1160925b 100644 --- a/js/src/ion/TypeOracle.cpp +++ b/js/src/ion/TypeOracle.cpp @@ -18,11 +18,11 @@ using namespace js::types; using namespace js::analyze; bool -TypeInferenceOracle::init(JSContext *cx, JSScript *script) +TypeInferenceOracle::init(JSContext *cx, HandleScript script) { this->cx = cx; this->script_.init(script); - return script->ensureRanInference(cx); + return JSScript::ensureRanInference(cx, script); } MIRType @@ -64,7 +64,7 @@ TypeInferenceOracle::getMIRType(HeapTypeSet *types) } TypeOracle::UnaryTypes -TypeInferenceOracle::unaryTypes(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::unaryTypes(UnrootedScript script, jsbytecode *pc) { JS_ASSERT(script == this->script()); @@ -75,7 +75,7 @@ TypeInferenceOracle::unaryTypes(JSScript *script, jsbytecode *pc) } TypeOracle::BinaryTypes -TypeInferenceOracle::binaryTypes(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::binaryTypes(UnrootedScript script, jsbytecode *pc) { JS_ASSERT(script == this->script()); @@ -95,7 +95,7 @@ TypeInferenceOracle::binaryTypes(JSScript *script, jsbytecode *pc) } TypeOracle::Unary -TypeInferenceOracle::unaryOp(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::unaryOp(UnrootedScript script, jsbytecode *pc) { JS_ASSERT(script == this->script()); @@ -106,7 +106,7 @@ TypeInferenceOracle::unaryOp(JSScript *script, jsbytecode *pc) } TypeOracle::Binary -TypeInferenceOracle::binaryOp(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::binaryOp(UnrootedScript script, jsbytecode *pc) { JS_ASSERT(script == this->script()); @@ -126,7 +126,7 @@ TypeInferenceOracle::binaryOp(JSScript *script, jsbytecode *pc) } StackTypeSet * -TypeInferenceOracle::thisTypeSet(JSScript *script) +TypeInferenceOracle::thisTypeSet(UnrootedScript script) { JS_ASSERT(script == this->script()); return TypeScript::ThisTypes(script); @@ -205,20 +205,20 @@ TypeInferenceOracle::getOsrTypes(jsbytecode *osrPc, Vector &slotTypes) } StackTypeSet * -TypeInferenceOracle::parameterTypeSet(JSScript *script, size_t index) +TypeInferenceOracle::parameterTypeSet(UnrootedScript script, size_t index) { JS_ASSERT(script == this->script()); return TypeScript::ArgTypes(script, index); } StackTypeSet * -TypeInferenceOracle::propertyRead(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::propertyRead(UnrootedScript script, jsbytecode *pc) { return script->analysis()->pushedTypes(pc, 0); } StackTypeSet * -TypeInferenceOracle::propertyReadBarrier(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::propertyReadBarrier(HandleScript script, jsbytecode *pc) { if (script->analysis()->typeBarriers(cx, pc)) return script->analysis()->bytecodeTypes(pc); @@ -226,12 +226,12 @@ TypeInferenceOracle::propertyReadBarrier(JSScript *script, jsbytecode *pc) } bool -TypeInferenceOracle::propertyReadIdempotent(JSScript *script, jsbytecode *pc, HandleId id) +TypeInferenceOracle::propertyReadIdempotent(HandleScript script, jsbytecode *pc, HandleId id) { if (script->analysis()->getCode(pc).notIdempotent) return false; - if (id.get() != MakeTypeId(cx, id)) + if (id != MakeTypeId(cx, id)) return false; StackTypeSet *types = script->analysis()->poppedTypes(pc, 0); @@ -257,7 +257,7 @@ TypeInferenceOracle::propertyReadIdempotent(JSScript *script, jsbytecode *pc, Ha } bool -TypeInferenceOracle::propertyReadAccessGetter(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::propertyReadAccessGetter(UnrootedScript script, jsbytecode *pc) { return script->analysis()->getCode(pc).accessGetter; } @@ -281,14 +281,14 @@ TypeInferenceOracle::inObjectIsDenseArray(HandleScript script, jsbytecode *pc) } bool -TypeInferenceOracle::inArrayIsPacked(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::inArrayIsPacked(UnrootedScript script, jsbytecode *pc) { StackTypeSet *types = script->analysis()->poppedTypes(pc, 0); return !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED_ARRAY); } bool -TypeInferenceOracle::elementReadIsDenseArray(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::elementReadIsDenseArray(UnrootedScript script, jsbytecode *pc) { // Check whether the object is a dense array and index is int32 or double. StackTypeSet *obj = script->analysis()->poppedTypes(pc, 1); @@ -306,7 +306,7 @@ TypeInferenceOracle::elementReadIsDenseArray(JSScript *script, jsbytecode *pc) } bool -TypeInferenceOracle::elementReadIsTypedArray(JSScript *script, jsbytecode *pc, int *arrayType) +TypeInferenceOracle::elementReadIsTypedArray(UnrootedScript script, jsbytecode *pc, int *arrayType) { // Check whether the object is a typed array and index is int32 or double. StackTypeSet *obj = script->analysis()->poppedTypes(pc, 1); @@ -346,7 +346,7 @@ TypeInferenceOracle::elementReadIsTypedArray(JSScript *script, jsbytecode *pc, i } bool -TypeInferenceOracle::elementReadIsString(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::elementReadIsString(UnrootedScript script, jsbytecode *pc) { // Check for string[index]. StackTypeSet *value = script->analysis()->poppedTypes(pc, 1); @@ -370,14 +370,14 @@ TypeInferenceOracle::elementReadIsString(JSScript *script, jsbytecode *pc) } bool -TypeInferenceOracle::elementReadIsPacked(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::elementReadIsPacked(UnrootedScript script, jsbytecode *pc) { StackTypeSet *types = script->analysis()->poppedTypes(pc, 1); return !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED_ARRAY); } void -TypeInferenceOracle::elementReadGeneric(JSScript *script, jsbytecode *pc, bool *cacheable, bool *monitorResult) +TypeInferenceOracle::elementReadGeneric(UnrootedScript script, jsbytecode *pc, bool *cacheable, bool *monitorResult) { MIRType obj = getMIRType(script->analysis()->poppedTypes(pc, 1)); MIRType id = getMIRType(script->analysis()->poppedTypes(pc, 0)); @@ -415,7 +415,7 @@ TypeInferenceOracle::elementWriteIsDenseArray(HandleScript script, jsbytecode *p } bool -TypeInferenceOracle::elementWriteIsTypedArray(JSScript *script, jsbytecode *pc, int *arrayType) +TypeInferenceOracle::elementWriteIsTypedArray(UnrootedScript script, jsbytecode *pc, int *arrayType) { // Check whether the object is a dense array and index is int32 or double. StackTypeSet *obj = script->analysis()->poppedTypes(pc, 2); @@ -440,20 +440,20 @@ TypeInferenceOracle::elementWriteIsTypedArray(JSScript *script, jsbytecode *pc, } bool -TypeInferenceOracle::elementWriteIsPacked(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::elementWriteIsPacked(UnrootedScript script, jsbytecode *pc) { StackTypeSet *types = script->analysis()->poppedTypes(pc, 2); return !types->hasObjectFlags(cx, types::OBJECT_FLAG_NON_PACKED_ARRAY); } bool -TypeInferenceOracle::setElementHasWrittenHoles(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::setElementHasWrittenHoles(UnrootedScript script, jsbytecode *pc) { return script->analysis()->getCode(pc).arrayWriteHole; } MIRType -TypeInferenceOracle::elementWrite(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::elementWrite(UnrootedScript script, jsbytecode *pc) { StackTypeSet *objTypes = script->analysis()->poppedTypes(pc, 2); MIRType elementType = MIRType_None; @@ -502,14 +502,14 @@ TypeInferenceOracle::propertyWriteCanSpecialize(UnrootedScript script, jsbytecod } bool -TypeInferenceOracle::propertyWriteNeedsBarrier(JSScript *script, jsbytecode *pc, jsid id) +TypeInferenceOracle::propertyWriteNeedsBarrier(UnrootedScript script, jsbytecode *pc, jsid id) { StackTypeSet *types = script->analysis()->poppedTypes(pc, 1); return types->propertyNeedsBarrier(cx, id); } bool -TypeInferenceOracle::elementWriteNeedsBarrier(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::elementWriteNeedsBarrier(UnrootedScript script, jsbytecode *pc) { // Return true if SETELEM-like instructions need a write barrier before modifying // a property. The object is the third value popped by SETELEM. @@ -518,7 +518,7 @@ TypeInferenceOracle::elementWriteNeedsBarrier(JSScript *script, jsbytecode *pc) } StackTypeSet * -TypeInferenceOracle::getCallTarget(JSScript *caller, uint32_t argc, jsbytecode *pc) +TypeInferenceOracle::getCallTarget(UnrootedScript caller, uint32_t argc, jsbytecode *pc) { JS_ASSERT(caller == this->script()); JS_ASSERT(js_CodeSpec[*pc].format & JOF_INVOKE && JSOp(*pc) != JSOP_EVAL); @@ -528,7 +528,7 @@ TypeInferenceOracle::getCallTarget(JSScript *caller, uint32_t argc, jsbytecode * } StackTypeSet * -TypeInferenceOracle::getCallArg(JSScript *script, uint32_t argc, uint32_t arg, jsbytecode *pc) +TypeInferenceOracle::getCallArg(UnrootedScript script, uint32_t argc, uint32_t arg, jsbytecode *pc) { JS_ASSERT(argc >= arg); // Bytecode order: Function, This, Arg0, Arg1, ..., ArgN, Call. @@ -537,13 +537,13 @@ TypeInferenceOracle::getCallArg(JSScript *script, uint32_t argc, uint32_t arg, j } StackTypeSet * -TypeInferenceOracle::getCallReturn(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::getCallReturn(UnrootedScript script, jsbytecode *pc) { return script->analysis()->pushedTypes(pc, 0); } bool -TypeInferenceOracle::canInlineCall(JSScript *caller, jsbytecode *pc) +TypeInferenceOracle::canInlineCall(HandleScript caller, jsbytecode *pc) { JS_ASSERT(types::IsInlinableCall(pc)); @@ -576,7 +576,7 @@ TypeInferenceOracle::canEnterInlinedFunction(JSFunction *target) } HeapTypeSet * -TypeInferenceOracle::globalPropertyWrite(JSScript *script, jsbytecode *pc, jsid id, +TypeInferenceOracle::globalPropertyWrite(UnrootedScript script, jsbytecode *pc, jsid id, bool *canSpecialize) { *canSpecialize = !script->analysis()->getCode(pc).monitoredTypes; @@ -587,7 +587,7 @@ TypeInferenceOracle::globalPropertyWrite(JSScript *script, jsbytecode *pc, jsid } StackTypeSet * -TypeInferenceOracle::returnTypeSet(JSScript *script, jsbytecode *pc, types::StackTypeSet **barrier) +TypeInferenceOracle::returnTypeSet(UnrootedScript script, jsbytecode *pc, types::StackTypeSet **barrier) { if (script->analysis()->getCode(pc).monitoredTypesReturn) *barrier = script->analysis()->bytecodeTypes(pc); @@ -597,14 +597,14 @@ TypeInferenceOracle::returnTypeSet(JSScript *script, jsbytecode *pc, types::Stac } StackTypeSet * -TypeInferenceOracle::aliasedVarBarrier(JSScript *script, jsbytecode *pc, types::StackTypeSet **barrier) +TypeInferenceOracle::aliasedVarBarrier(UnrootedScript script, jsbytecode *pc, types::StackTypeSet **barrier) { *barrier = script->analysis()->bytecodeTypes(pc); return script->analysis()->pushedTypes(pc, 0); } HeapTypeSet * -TypeInferenceOracle::globalPropertyTypeSet(JSScript *script, jsbytecode *pc, jsid id) +TypeInferenceOracle::globalPropertyTypeSet(UnrootedScript script, jsbytecode *pc, jsid id) { TypeObject *type = script->global().getType(cx); if (type->unknownProperties()) @@ -624,21 +624,21 @@ TypeInferenceOracle::isArgumentObject(types::StackTypeSet *obj) } LazyArgumentsType -TypeInferenceOracle::propertyReadMagicArguments(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::propertyReadMagicArguments(UnrootedScript script, jsbytecode *pc) { StackTypeSet *obj = script->analysis()->poppedTypes(pc, 0); return isArgumentObject(obj); } LazyArgumentsType -TypeInferenceOracle::elementReadMagicArguments(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::elementReadMagicArguments(UnrootedScript script, jsbytecode *pc) { StackTypeSet *obj = script->analysis()->poppedTypes(pc, 1); return isArgumentObject(obj); } LazyArgumentsType -TypeInferenceOracle::elementWriteMagicArguments(JSScript *script, jsbytecode *pc) +TypeInferenceOracle::elementWriteMagicArguments(UnrootedScript script, jsbytecode *pc) { StackTypeSet *obj = script->analysis()->poppedTypes(pc, 2); return isArgumentObject(obj); diff --git a/js/src/ion/TypeOracle.h b/js/src/ion/TypeOracle.h index 8bb124d2fc44..b55d6f57dd74 100644 --- a/js/src/ion/TypeOracle.h +++ b/js/src/ion/TypeOracle.h @@ -44,81 +44,81 @@ class TypeOracle }; public: - virtual UnaryTypes unaryTypes(JSScript *script, jsbytecode *pc) = 0; - virtual BinaryTypes binaryTypes(JSScript *script, jsbytecode *pc) = 0; - virtual Unary unaryOp(JSScript *script, jsbytecode *pc) = 0; - virtual Binary binaryOp(JSScript *script, jsbytecode *pc) = 0; - virtual types::StackTypeSet *thisTypeSet(JSScript *script) { return NULL; } + virtual UnaryTypes unaryTypes(UnrootedScript script, jsbytecode *pc) = 0; + virtual BinaryTypes binaryTypes(UnrootedScript script, jsbytecode *pc) = 0; + virtual Unary unaryOp(UnrootedScript script, jsbytecode *pc) = 0; + virtual Binary binaryOp(UnrootedScript script, jsbytecode *pc) = 0; + virtual types::StackTypeSet *thisTypeSet(UnrootedScript script) { return NULL; } virtual bool getOsrTypes(jsbytecode *osrPc, Vector &slotTypes) { return true; } - virtual types::StackTypeSet *parameterTypeSet(JSScript *script, size_t index) { return NULL; } - virtual types::HeapTypeSet *globalPropertyTypeSet(JSScript *script, jsbytecode *pc, jsid id) { + virtual types::StackTypeSet *parameterTypeSet(UnrootedScript script, size_t index) { return NULL; } + virtual types::HeapTypeSet *globalPropertyTypeSet(UnrootedScript script, jsbytecode *pc, jsid id) { return NULL; } - virtual types::StackTypeSet *propertyRead(JSScript *script, jsbytecode *pc) { + virtual types::StackTypeSet *propertyRead(UnrootedScript script, jsbytecode *pc) { return NULL; } - virtual types::StackTypeSet *propertyReadBarrier(JSScript *script, jsbytecode *pc) { + virtual types::StackTypeSet *propertyReadBarrier(HandleScript script, jsbytecode *pc) { return NULL; } - virtual bool propertyReadIdempotent(JSScript *script, jsbytecode *pc, HandleId id) { + virtual bool propertyReadIdempotent(HandleScript script, jsbytecode *pc, HandleId id) { return false; } - virtual bool propertyReadAccessGetter(JSScript *script, jsbytecode *pc) { + virtual bool propertyReadAccessGetter(UnrootedScript script, jsbytecode *pc) { return false; } - virtual types::HeapTypeSet *globalPropertyWrite(JSScript *script, jsbytecode *pc, + virtual types::HeapTypeSet *globalPropertyWrite(UnrootedScript script, jsbytecode *pc, jsid id, bool *canSpecialize) { *canSpecialize = true; return NULL; } - virtual types::StackTypeSet *returnTypeSet(JSScript *script, jsbytecode *pc, types::StackTypeSet **barrier) { + virtual types::StackTypeSet *returnTypeSet(UnrootedScript script, jsbytecode *pc, types::StackTypeSet **barrier) { *barrier = NULL; return NULL; } virtual bool inObjectIsDenseArray(HandleScript script, jsbytecode *pc) { return false; } - virtual bool inArrayIsPacked(JSScript *script, jsbytecode *pc) { + virtual bool inArrayIsPacked(UnrootedScript script, jsbytecode *pc) { return false; } - virtual bool elementReadIsDenseArray(JSScript *script, jsbytecode *pc) { + virtual bool elementReadIsDenseArray(UnrootedScript script, jsbytecode *pc) { return false; } - virtual bool elementReadIsTypedArray(JSScript *script, jsbytecode *pc, int *arrayType) { + virtual bool elementReadIsTypedArray(UnrootedScript script, jsbytecode *pc, int *arrayType) { return false; } - virtual bool elementReadIsString(JSScript *script, jsbytecode *pc) { + virtual bool elementReadIsString(UnrootedScript script, jsbytecode *pc) { return false; } - virtual bool elementReadIsPacked(JSScript *script, jsbytecode *pc) { + virtual bool elementReadIsPacked(UnrootedScript script, jsbytecode *pc) { return false; } - virtual void elementReadGeneric(JSScript *script, jsbytecode *pc, bool *cacheable, bool *monitorResult) { + virtual void elementReadGeneric(UnrootedScript script, jsbytecode *pc, bool *cacheable, bool *monitorResult) { *cacheable = false; *monitorResult = true; } - virtual bool setElementHasWrittenHoles(JSScript *script, jsbytecode *pc) { + virtual bool setElementHasWrittenHoles(UnrootedScript script, jsbytecode *pc) { return true; } virtual bool elementWriteIsDenseArray(HandleScript script, jsbytecode *pc) { return false; } - virtual bool elementWriteIsTypedArray(JSScript *script, jsbytecode *pc, int *arrayType) { + virtual bool elementWriteIsTypedArray(UnrootedScript script, jsbytecode *pc, int *arrayType) { return false; } - virtual bool elementWriteIsPacked(JSScript *script, jsbytecode *pc) { + virtual bool elementWriteIsPacked(UnrootedScript script, jsbytecode *pc) { return false; } virtual bool propertyWriteCanSpecialize(UnrootedScript script, jsbytecode *pc) { return true; } - virtual bool propertyWriteNeedsBarrier(JSScript *script, jsbytecode *pc, jsid id) { + virtual bool propertyWriteNeedsBarrier(UnrootedScript script, jsbytecode *pc, jsid id) { return true; } - virtual bool elementWriteNeedsBarrier(JSScript *script, jsbytecode *pc) { + virtual bool elementWriteNeedsBarrier(UnrootedScript script, jsbytecode *pc) { return true; } - virtual MIRType elementWrite(JSScript *script, jsbytecode *pc) { + virtual MIRType elementWrite(UnrootedScript script, jsbytecode *pc) { return MIRType_None; } virtual bool arrayPrototypeHasIndexedProperty() { @@ -129,18 +129,18 @@ class TypeOracle } /* |pc| must be a |JSOP_CALL|. */ - virtual types::StackTypeSet *getCallTarget(JSScript *caller, uint32_t argc, jsbytecode *pc) { + virtual types::StackTypeSet *getCallTarget(UnrootedScript caller, uint32_t argc, jsbytecode *pc) { // Same assertion as TypeInferenceOracle::getCallTarget. JS_ASSERT(js_CodeSpec[*pc].format & JOF_INVOKE && JSOp(*pc) != JSOP_EVAL); return NULL; } - virtual types::StackTypeSet *getCallArg(JSScript *script, uint32_t argc, uint32_t arg, jsbytecode *pc) { + virtual types::StackTypeSet *getCallArg(UnrootedScript script, uint32_t argc, uint32_t arg, jsbytecode *pc) { return NULL; } - virtual types::StackTypeSet *getCallReturn(JSScript *script, jsbytecode *pc) { + virtual types::StackTypeSet *getCallReturn(UnrootedScript script, jsbytecode *pc) { return NULL; } - virtual bool canInlineCall(JSScript *caller, jsbytecode *pc) { + virtual bool canInlineCall(HandleScript caller, jsbytecode *pc) { return false; } virtual bool canEnterInlinedFunction(JSFunction *callee) { @@ -150,16 +150,18 @@ class TypeOracle virtual LazyArgumentsType isArgumentObject(types::StackTypeSet *obj) { return MaybeArguments; } - virtual LazyArgumentsType propertyReadMagicArguments(JSScript *script, jsbytecode *pc) { + virtual LazyArgumentsType propertyReadMagicArguments(UnrootedScript script, jsbytecode *pc) { return MaybeArguments; } - virtual LazyArgumentsType elementReadMagicArguments(JSScript *script, jsbytecode *pc) { + virtual LazyArgumentsType elementReadMagicArguments(UnrootedScript script, jsbytecode *pc) { return MaybeArguments; } - virtual LazyArgumentsType elementWriteMagicArguments(JSScript *script, jsbytecode *pc) { + virtual LazyArgumentsType elementWriteMagicArguments(UnrootedScript script, jsbytecode *pc) { return MaybeArguments; } - virtual types::StackTypeSet *aliasedVarBarrier(JSScript *script, jsbytecode *pc, types::StackTypeSet **barrier) { + virtual types::StackTypeSet *aliasedVarBarrier(UnrootedScript script, jsbytecode *pc, + types::StackTypeSet **barrier) + { return NULL; } }; @@ -167,26 +169,26 @@ class TypeOracle class DummyOracle : public TypeOracle { public: - UnaryTypes unaryTypes(JSScript *script, jsbytecode *pc) { + UnaryTypes unaryTypes(UnrootedScript script, jsbytecode *pc) { UnaryTypes u; u.inTypes = NULL; u.outTypes = NULL; return u; } - BinaryTypes binaryTypes(JSScript *script, jsbytecode *pc) { + BinaryTypes binaryTypes(UnrootedScript script, jsbytecode *pc) { BinaryTypes b; b.lhsTypes = NULL; b.rhsTypes = NULL; b.outTypes = NULL; return b; } - Unary unaryOp(JSScript *script, jsbytecode *pc) { + Unary unaryOp(UnrootedScript script, jsbytecode *pc) { Unary u; u.ival = MIRType_Int32; u.rval = MIRType_Int32; return u; } - Binary binaryOp(JSScript *script, jsbytecode *pc) { + Binary binaryOp(UnrootedScript script, jsbytecode *pc) { Binary b; b.lhs = MIRType_Int32; b.rhs = MIRType_Int32; @@ -206,52 +208,52 @@ class TypeInferenceOracle : public TypeOracle public: TypeInferenceOracle() : cx(NULL), script_(NULL) {} - bool init(JSContext *cx, JSScript *script); + bool init(JSContext *cx, HandleScript script); UnrootedScript script() { return script_.get(); } - UnaryTypes unaryTypes(JSScript *script, jsbytecode *pc); - BinaryTypes binaryTypes(JSScript *script, jsbytecode *pc); - Unary unaryOp(JSScript *script, jsbytecode *pc); - Binary binaryOp(JSScript *script, jsbytecode *pc); - types::StackTypeSet *thisTypeSet(JSScript *script); + UnaryTypes unaryTypes(UnrootedScript script, jsbytecode *pc); + BinaryTypes binaryTypes(UnrootedScript script, jsbytecode *pc); + Unary unaryOp(UnrootedScript script, jsbytecode *pc); + Binary binaryOp(UnrootedScript script, jsbytecode *pc); + types::StackTypeSet *thisTypeSet(UnrootedScript script); bool getOsrTypes(jsbytecode *osrPc, Vector &slotTypes); - types::StackTypeSet *parameterTypeSet(JSScript *script, size_t index); - types::HeapTypeSet *globalPropertyTypeSet(JSScript *script, jsbytecode *pc, jsid id); - types::StackTypeSet *propertyRead(JSScript *script, jsbytecode *pc); - types::StackTypeSet *propertyReadBarrier(JSScript *script, jsbytecode *pc); - bool propertyReadIdempotent(JSScript *script, jsbytecode *pc, HandleId id); - bool propertyReadAccessGetter(JSScript *script, jsbytecode *pc); - types::HeapTypeSet *globalPropertyWrite(JSScript *script, jsbytecode *pc, jsid id, bool *canSpecialize); - types::StackTypeSet *returnTypeSet(JSScript *script, jsbytecode *pc, types::StackTypeSet **barrier); - types::StackTypeSet *getCallTarget(JSScript *caller, uint32_t argc, jsbytecode *pc); - types::StackTypeSet *getCallArg(JSScript *caller, uint32_t argc, uint32_t arg, jsbytecode *pc); - types::StackTypeSet *getCallReturn(JSScript *caller, jsbytecode *pc); + types::StackTypeSet *parameterTypeSet(UnrootedScript script, size_t index); + types::HeapTypeSet *globalPropertyTypeSet(UnrootedScript script, jsbytecode *pc, jsid id); + types::StackTypeSet *propertyRead(UnrootedScript script, jsbytecode *pc); + types::StackTypeSet *propertyReadBarrier(HandleScript script, jsbytecode *pc); + bool propertyReadIdempotent(HandleScript script, jsbytecode *pc, HandleId id); + bool propertyReadAccessGetter(UnrootedScript script, jsbytecode *pc); + types::HeapTypeSet *globalPropertyWrite(UnrootedScript script, jsbytecode *pc, jsid id, bool *canSpecialize); + types::StackTypeSet *returnTypeSet(UnrootedScript script, jsbytecode *pc, types::StackTypeSet **barrier); + types::StackTypeSet *getCallTarget(UnrootedScript caller, uint32_t argc, jsbytecode *pc); + types::StackTypeSet *getCallArg(UnrootedScript caller, uint32_t argc, uint32_t arg, jsbytecode *pc); + types::StackTypeSet *getCallReturn(UnrootedScript caller, jsbytecode *pc); bool inObjectIsDenseArray(HandleScript script, jsbytecode *pc); - bool inArrayIsPacked(JSScript *script, jsbytecode *pc); - bool elementReadIsDenseArray(JSScript *script, jsbytecode *pc); - bool elementReadIsTypedArray(JSScript *script, jsbytecode *pc, int *atype); - bool elementReadIsString(JSScript *script, jsbytecode *pc); - bool elementReadIsPacked(JSScript *script, jsbytecode *pc); - void elementReadGeneric(JSScript *script, jsbytecode *pc, bool *cacheable, bool *monitorResult); + bool inArrayIsPacked(UnrootedScript script, jsbytecode *pc); + bool elementReadIsDenseArray(UnrootedScript script, jsbytecode *pc); + bool elementReadIsTypedArray(UnrootedScript script, jsbytecode *pc, int *atype); + bool elementReadIsString(UnrootedScript script, jsbytecode *pc); + bool elementReadIsPacked(UnrootedScript script, jsbytecode *pc); + void elementReadGeneric(UnrootedScript script, jsbytecode *pc, bool *cacheable, bool *monitorResult); bool elementWriteIsDenseArray(HandleScript script, jsbytecode *pc); - bool elementWriteIsTypedArray(JSScript *script, jsbytecode *pc, int *arrayType); - bool elementWriteIsPacked(JSScript *script, jsbytecode *pc); - bool setElementHasWrittenHoles(JSScript *script, jsbytecode *pc); + bool elementWriteIsTypedArray(UnrootedScript script, jsbytecode *pc, int *arrayType); + bool elementWriteIsPacked(UnrootedScript script, jsbytecode *pc); + bool setElementHasWrittenHoles(UnrootedScript script, jsbytecode *pc); bool propertyWriteCanSpecialize(UnrootedScript script, jsbytecode *pc); - bool propertyWriteNeedsBarrier(JSScript *script, jsbytecode *pc, jsid id); - bool elementWriteNeedsBarrier(JSScript *script, jsbytecode *pc); - MIRType elementWrite(JSScript *script, jsbytecode *pc); + bool propertyWriteNeedsBarrier(UnrootedScript script, jsbytecode *pc, jsid id); + bool elementWriteNeedsBarrier(UnrootedScript script, jsbytecode *pc); + MIRType elementWrite(UnrootedScript script, jsbytecode *pc); bool arrayPrototypeHasIndexedProperty(); bool canInlineCalls(); - bool canInlineCall(JSScript *caller, jsbytecode *pc); + bool canInlineCall(HandleScript caller, jsbytecode *pc); bool canEnterInlinedFunction(JSFunction *callee); - types::StackTypeSet *aliasedVarBarrier(JSScript *script, jsbytecode *pc, types::StackTypeSet **barrier); + types::StackTypeSet *aliasedVarBarrier(UnrootedScript script, jsbytecode *pc, types::StackTypeSet **barrier); LazyArgumentsType isArgumentObject(types::StackTypeSet *obj); - LazyArgumentsType propertyReadMagicArguments(JSScript *script, jsbytecode *pc); - LazyArgumentsType elementReadMagicArguments(JSScript *script, jsbytecode *pc); - LazyArgumentsType elementWriteMagicArguments(JSScript *script, jsbytecode *pc); + LazyArgumentsType propertyReadMagicArguments(UnrootedScript script, jsbytecode *pc); + LazyArgumentsType elementReadMagicArguments(UnrootedScript script, jsbytecode *pc); + LazyArgumentsType elementWriteMagicArguments(UnrootedScript script, jsbytecode *pc); }; static inline MIRType diff --git a/js/src/ion/VMFunctions.cpp b/js/src/ion/VMFunctions.cpp index 586099bdcb33..335134ba83b6 100644 --- a/js/src/ion/VMFunctions.cpp +++ b/js/src/ion/VMFunctions.cpp @@ -56,7 +56,7 @@ InvokeFunction(JSContext *cx, JSFunction *fun, uint32_t argc, Value *argv, Value if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx)) return false; if (!fun->nonLazyScript()->canIonCompile()) { - JSScript *script = GetTopIonJSScript(cx); + UnrootedScript script = GetTopIonJSScript(cx); if (script->hasIonScript() && ++script->ion->slowCallCount >= js_IonOptions.slowCallLimit) { diff --git a/js/src/ion/VMFunctions.h b/js/src/ion/VMFunctions.h index 0b654a861581..5e0cfcbbf070 100644 --- a/js/src/ion/VMFunctions.h +++ b/js/src/ion/VMFunctions.h @@ -219,7 +219,7 @@ template <> struct TypeToArgProperties { static const uint32_t result = TypeToArgProperties::result | VMFunction::ByRef; }; template <> struct TypeToArgProperties { - static const uint32_t result = TypeToArgProperties::result | VMFunction::ByRef; + static const uint32_t result = TypeToArgProperties::result | VMFunction::ByRef; }; template <> struct TypeToArgProperties { static const uint32_t result = TypeToArgProperties::result | VMFunction::ByRef; diff --git a/js/src/ion/arm/CodeGenerator-arm.cpp b/js/src/ion/arm/CodeGenerator-arm.cpp index 33325e07387b..9c620ba22578 100644 --- a/js/src/ion/arm/CodeGenerator-arm.cpp +++ b/js/src/ion/arm/CodeGenerator-arm.cpp @@ -1105,7 +1105,7 @@ CodeGeneratorARM::linkAbsoluteLabels() // On arm, everything should just go in a pool. # if 0 JS_NOT_REACHED("Absolute Labels NYI"); - JSScript *script = gen->info().script(); + UnrootedScript script = gen->info().script(); IonCode *method = script->ion->method(); for (size_t i = 0; i < deferredDoubles_.length(); i++) { diff --git a/js/src/ion/shared/CodeGenerator-shared.h b/js/src/ion/shared/CodeGenerator-shared.h index 140f806114a4..f342f2c6b197 100644 --- a/js/src/ion/shared/CodeGenerator-shared.h +++ b/js/src/ion/shared/CodeGenerator-shared.h @@ -333,14 +333,14 @@ class OutOfLineCode : public TempObject uint32_t framePushed() const { return framePushed_; } - void setSource(JSScript *script, jsbytecode *pc) { + void setSource(UnrootedScript script, jsbytecode *pc) { script_ = script; pc_ = pc; } jsbytecode *pc() { return pc_; } - JSScript *script() { + UnrootedScript script() { return script_; } }; diff --git a/js/src/ion/x86/CodeGenerator-x86.cpp b/js/src/ion/x86/CodeGenerator-x86.cpp index 9d909137615a..b1fce1698a3f 100644 --- a/js/src/ion/x86/CodeGenerator-x86.cpp +++ b/js/src/ion/x86/CodeGenerator-x86.cpp @@ -137,7 +137,7 @@ CodeGeneratorX86::visitUnbox(LUnbox *unbox) void CodeGeneratorX86::linkAbsoluteLabels() { - JSScript *script = gen->info().script(); + UnrootedScript script = gen->info().script(); IonCode *method = script->ion->method(); for (size_t i = 0; i < deferredDoubles_.length(); i++) { diff --git a/js/src/jsalloc.h b/js/src/jsalloc.h index 259456ff7e2d..b8912a36a209 100644 --- a/js/src/jsalloc.h +++ b/js/src/jsalloc.h @@ -8,7 +8,6 @@ #ifndef jsalloc_h_ #define jsalloc_h_ -#include "jspubtd.h" #include "jsutil.h" namespace js { diff --git a/js/src/jsanalyze.cpp b/js/src/jsanalyze.cpp index d89f108f59f0..48a10ed664c6 100644 --- a/js/src/jsanalyze.cpp +++ b/js/src/jsanalyze.cpp @@ -22,10 +22,9 @@ using namespace js::analyze; #ifdef DEBUG void -analyze::PrintBytecode(JSContext *cx, JSScript *scriptArg, jsbytecode *pc) +analyze::PrintBytecode(JSContext *cx, HandleScript script, jsbytecode *pc) { - RootedScript script(cx, scriptArg); - + AssertCanGC(); printf("#%u:", script->id()); Sprinter sprinter(cx); if (!sprinter.init()) @@ -1965,7 +1964,7 @@ CrossScriptSSA::foldValue(const CrossSSAValue &cv) const Frame &frame = getFrame(cv.frame); const SSAValue &v = cv.v; - JSScript *parentScript = NULL; + UnrootedScript parentScript = NULL; ScriptAnalysis *parentAnalysis = NULL; if (frame.parent != INVALID_FRAME) { parentScript = getFrame(frame.parent).script; @@ -1998,7 +1997,7 @@ CrossScriptSSA::foldValue(const CrossSSAValue &cv) * If there is a single inline callee with a single return site, * propagate back to that. */ - JSScript *callee = NULL; + UnrootedScript callee = NULL; uint32_t calleeFrame = INVALID_FRAME; for (unsigned i = 0; i < numFrames(); i++) { if (iterFrame(i).parent == cv.frame && iterFrame(i).parentpc == pc) { @@ -2050,6 +2049,7 @@ ScriptAnalysis::printSSA(JSContext *cx) printf("\n"); + RootedScript script(cx, script_); for (unsigned offset = 0; offset < script_->length; offset++) { Bytecode *code = maybeCode(offset); if (!code) @@ -2057,7 +2057,7 @@ ScriptAnalysis::printSSA(JSContext *cx) jsbytecode *pc = script_->code + offset; - PrintBytecode(cx, script_, pc); + PrintBytecode(cx, script, pc); SlotValue *newv = code->newValues; if (newv) { diff --git a/js/src/jsanalyze.h b/js/src/jsanalyze.h index 6e9568d5c101..818e0c337e92 100644 --- a/js/src/jsanalyze.h +++ b/js/src/jsanalyze.h @@ -173,7 +173,7 @@ class Bytecode }; static inline unsigned -GetDefCount(JSScript *script, unsigned offset) +GetDefCount(UnrootedScript script, unsigned offset) { JS_ASSERT(offset < script->length); jsbytecode *pc = script->code + offset; @@ -202,7 +202,7 @@ GetDefCount(JSScript *script, unsigned offset) } static inline unsigned -GetUseCount(JSScript *script, unsigned offset) +GetUseCount(UnrootedScript script, unsigned offset) { JS_ASSERT(offset < script->length); jsbytecode *pc = script->code + offset; @@ -331,7 +331,7 @@ NegateCompareOp(JSOp op) } static inline unsigned -FollowBranch(JSContext *cx, JSScript *script, unsigned offset) +FollowBranch(JSContext *cx, UnrootedScript script, unsigned offset) { /* * Get the target offset of a branch. For GOTO opcodes implementing @@ -359,18 +359,18 @@ static inline uint32_t ThisSlot() { static inline uint32_t ArgSlot(uint32_t arg) { return 2 + arg; } -static inline uint32_t LocalSlot(JSScript *script, uint32_t local) { +static inline uint32_t LocalSlot(UnrootedScript script, uint32_t local) { return 2 + (script->function() ? script->function()->nargs : 0) + local; } -static inline uint32_t TotalSlots(JSScript *script) { +static inline uint32_t TotalSlots(UnrootedScript script) { return LocalSlot(script, 0) + script->nfixed; } -static inline uint32_t StackSlot(JSScript *script, uint32_t index) { +static inline uint32_t StackSlot(UnrootedScript script, uint32_t index) { return TotalSlots(script) + index; } -static inline uint32_t GetBytecodeSlot(JSScript *script, jsbytecode *pc) +static inline uint32_t GetBytecodeSlot(UnrootedScript script, jsbytecode *pc) { switch (JSOp(*pc)) { @@ -546,7 +546,7 @@ struct LifetimeVariable } /* Return true if the variable cannot decrease during the body of a loop. */ - bool nonDecreasing(JSScript *script, LoopAnalysis *loop) const { + bool nonDecreasing(UnrootedScript script, LoopAnalysis *loop) const { Lifetime *segment = lifetime ? lifetime : saved; while (segment && segment->start <= loop->backedge) { if (segment->start >= loop->head && segment->write) { @@ -862,7 +862,7 @@ class ScriptAnalysis public: - ScriptAnalysis(JSScript *script) { + ScriptAnalysis(UnrootedScript script) { PodZero(this); this->script_ = script; #ifdef DEBUG @@ -1264,8 +1264,9 @@ class CrossScriptSSA uint32_t parent; jsbytecode *parentpc; - Frame(uint32_t index, JSScript *script, uint32_t depth, uint32_t parent, jsbytecode *parentpc) - : index(index), script(script), depth(depth), parent(parent), parentpc(parentpc) + Frame(uint32_t index, UnrootedScript script, uint32_t depth, uint32_t parent, + jsbytecode *parentpc) + : index(index), script(script), depth(depth), parent(parent), parentpc(parentpc) {} }; @@ -1282,7 +1283,7 @@ class CrossScriptSSA return inlineFrames[i - 1]; } - JSScript *outerScript() { return outerFrame.script; } + UnrootedScript outerScript() { return outerFrame.script; } /* Total length of scripts preceding a frame. */ size_t frameLength(uint32_t index) { @@ -1298,13 +1299,14 @@ class CrossScriptSSA return getFrame(cv.frame).script->analysis()->getValueTypes(cv.v); } - bool addInlineFrame(JSScript *script, uint32_t depth, uint32_t parent, jsbytecode *parentpc) + bool addInlineFrame(UnrootedScript script, uint32_t depth, uint32_t parent, + jsbytecode *parentpc) { uint32_t index = inlineFrames.length(); return inlineFrames.append(Frame(index, script, depth, parent, parentpc)); } - CrossScriptSSA(JSContext *cx, JSScript *outer) + CrossScriptSSA(JSContext *cx, UnrootedScript outer) : outerFrame(OUTER_FRAME, outer, 0, INVALID_FRAME, NULL), inlineFrames(cx) {} @@ -1316,7 +1318,7 @@ class CrossScriptSSA }; #ifdef DEBUG -void PrintBytecode(JSContext *cx, JSScript *script, jsbytecode *pc); +void PrintBytecode(JSContext *cx, HandleScript script, jsbytecode *pc); #endif } /* namespace analyze */ diff --git a/js/src/jsapi.cpp b/js/src/jsapi.cpp index a622c0a5709c..0eb7d8b7379e 100644 --- a/js/src/jsapi.cpp +++ b/js/src/jsapi.cpp @@ -7141,7 +7141,7 @@ JS::AssertArgumentsAreSane(JSContext *cx, const JS::Value &value) #endif /* DEBUG */ JS_PUBLIC_API(void *) -JS_EncodeScript(JSContext *cx, JSRawScript scriptArg, uint32_t *lengthp) +JS_EncodeScript(JSContext *cx, RawScript scriptArg, uint32_t *lengthp) { XDREncoder encoder(cx); RootedScript script(cx, scriptArg); diff --git a/js/src/jscntxt.cpp b/js/src/jscntxt.cpp index 176a068372e6..40687f325961 100644 --- a/js/src/jscntxt.cpp +++ b/js/src/jscntxt.cpp @@ -516,7 +516,7 @@ checkReportFlags(JSContext *cx, unsigned *flags) * We assume that if the top frame is a native, then it is strict if * the nearest scripted frame is strict, see bug 536306. */ - JSScript *script = cx->stack.currentScript(); + UnrootedScript script = cx->stack.currentScript(); if (script && script->strict) *flags &= ~JSREPORT_WARNING; else if (cx->hasStrictOption()) diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 511c2e9cc7ab..2da7ac4b43eb 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -204,10 +204,10 @@ struct EvalCacheHashPolicy typedef EvalCacheLookup Lookup; static HashNumber hash(const Lookup &l); - static bool match(JSScript *script, const EvalCacheLookup &l); + static bool match(UnrootedScript script, const EvalCacheLookup &l); }; -typedef HashSet EvalCache; +typedef HashSet EvalCache; class NativeIterCache { diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index d2bf0b5d467a..76902410ecfb 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -425,7 +425,7 @@ js::XDRInterpretedFunction(XDRState *xdr, HandleObject enclosingScope, Han return false; JS_ASSERT(fun->nargs == fun->nonLazyScript()->bindings.numArgs()); RootedScript script(cx, fun->nonLazyScript()); - js_CallNewScriptHook(cx, script, fun); + CallNewScriptHook(cx, script, fun); objp.set(fun); } @@ -451,7 +451,7 @@ js::CloneInterpretedFunction(JSContext *cx, HandleObject enclosingScope, HandleF return NULL; RootedScript srcScript(cx, srcFun->nonLazyScript()); - RawScript clonedScript = CloneScript(cx, enclosingScope, clone, srcScript); + RootedScript clonedScript(cx, CloneScript(cx, enclosingScope, clone, srcScript)); if (!clonedScript) return NULL; @@ -464,7 +464,7 @@ js::CloneInterpretedFunction(JSContext *cx, HandleObject enclosingScope, HandleF return NULL; RootedScript cloneScript(cx, clone->nonLazyScript()); - js_CallNewScriptHook(cx, cloneScript, clone); + CallNewScriptHook(cx, cloneScript, clone); return clone; } @@ -1520,7 +1520,7 @@ js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent, clone->mutableScript().init(NULL); - RawScript cscript = CloneScript(cx, scope, clone, script); + RootedScript cscript(cx, CloneScript(cx, scope, clone, script)); if (!cscript) return NULL; @@ -1530,7 +1530,7 @@ js_CloneFunctionObject(JSContext *cx, HandleFunction fun, HandleObject parent, GlobalObject *global = script->compileAndGo ? &script->global() : NULL; script = clone->nonLazyScript(); - js_CallNewScriptHook(cx, script, clone); + CallNewScriptHook(cx, script, clone); Debugger::onNewScript(cx, script, global); } } diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index daee84e0521d..265317db2543 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -4571,7 +4571,7 @@ js::StopPCCountProfiling(JSContext *cx) for (CompartmentsIter c(rt); !c.done(); c.next()) { for (CellIter i(c, FINALIZE_SCRIPT); !i.done(); i.next()) { - JSScript *script = i.get(); + RawScript script = i.get(); if (script->hasScriptCounts && script->types) { ScriptAndCounts sac; sac.script = script; diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index 9ef2d2f3c130..f6668c99f1d2 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -528,7 +528,7 @@ enum PropertyAccessKind { template class TypeConstraintProp : public TypeConstraint { - JSScript *script_; + RawScript script_; public: jsbytecode *pc; @@ -542,7 +542,7 @@ class TypeConstraintProp : public TypeConstraint /* Property being accessed. */ jsid id; - TypeConstraintProp(JSScript *script, jsbytecode *pc, StackTypeSet *target, jsid id) + TypeConstraintProp(UnrootedScript script, jsbytecode *pc, StackTypeSet *target, jsid id) : script_(script), pc(pc), target(target), id(id) { JS_ASSERT(script && pc && target); @@ -595,7 +595,7 @@ HeapTypeSet::addGetProperty(JSContext *cx, HandleScript script, jsbytecode *pc, template class TypeConstraintCallProp : public TypeConstraint { - JSScript *script_; + RawScript script_; public: jsbytecode *callpc; @@ -603,7 +603,7 @@ class TypeConstraintCallProp : public TypeConstraint /* Property being accessed. */ jsid id; - TypeConstraintCallProp(JSScript *script, jsbytecode *callpc, jsid id) + TypeConstraintCallProp(UnrootedScript script, jsbytecode *callpc, jsid id) : script_(script), callpc(callpc), id(id) { JS_ASSERT(script && callpc); @@ -640,7 +640,7 @@ HeapTypeSet::addCallProperty(JSContext *cx, HandleScript script, jsbytecode *pc, */ class TypeConstraintSetElement : public TypeConstraint { - JSScript *script_; + RawScript script_; public: jsbytecode *pc; @@ -648,7 +648,7 @@ class TypeConstraintSetElement : public TypeConstraint StackTypeSet *objectTypes; StackTypeSet *valueTypes; - TypeConstraintSetElement(JSScript *script, jsbytecode *pc, + TypeConstraintSetElement(UnrootedScript script, jsbytecode *pc, StackTypeSet *objectTypes, StackTypeSet *valueTypes) : script_(script), pc(pc), objectTypes(objectTypes), valueTypes(valueTypes) @@ -698,7 +698,7 @@ StackTypeSet::addCall(JSContext *cx, TypeCallsite *site) /* Constraints for arithmetic operations. */ class TypeConstraintArith : public TypeConstraint { - JSScript *script_; + RawScript script_; public: jsbytecode *pc; @@ -709,7 +709,7 @@ class TypeConstraintArith : public TypeConstraint /* For addition operations, the other operand. */ TypeSet *other; - TypeConstraintArith(JSScript *script, jsbytecode *pc, TypeSet *target, TypeSet *other) + TypeConstraintArith(UnrootedScript script, jsbytecode *pc, TypeSet *target, TypeSet *other) : script_(script), pc(pc), target(target), other(other) { JS_ASSERT(target); @@ -730,12 +730,12 @@ StackTypeSet::addArith(JSContext *cx, HandleScript script, jsbytecode *pc, TypeS /* Subset constraint which transforms primitive values into appropriate objects. */ class TypeConstraintTransformThis : public TypeConstraint { - JSScript *script_; + RawScript script_; public: TypeSet *target; - TypeConstraintTransformThis(JSScript *script, TypeSet *target) + TypeConstraintTransformThis(UnrootedScript script, TypeSet *target) : script_(script), target(target) {} @@ -756,14 +756,14 @@ StackTypeSet::addTransformThis(JSContext *cx, HandleScript script, TypeSet *targ */ class TypeConstraintPropagateThis : public TypeConstraint { - JSScript *script_; + RawScript script_; public: jsbytecode *callpc; Type type; StackTypeSet *types; - TypeConstraintPropagateThis(JSScript *script, jsbytecode *callpc, Type type, StackTypeSet *types) + TypeConstraintPropagateThis(UnrootedScript script, jsbytecode *callpc, Type type, StackTypeSet *types) : script_(script), callpc(callpc), type(type), types(types) {} @@ -918,11 +918,11 @@ void ScriptAnalysis::breakTypeBarriersSSA(JSContext *cx, const SSAValue &v) class TypeConstraintSubsetBarrier : public TypeConstraint { public: - JSScript *script; + RawScript script; jsbytecode *pc; TypeSet *target; - TypeConstraintSubsetBarrier(JSScript *script, jsbytecode *pc, TypeSet *target) + TypeConstraintSubsetBarrier(UnrootedScript script, jsbytecode *pc, TypeSet *target) : script(script), pc(pc), target(target) {} @@ -931,7 +931,8 @@ class TypeConstraintSubsetBarrier : public TypeConstraint void newType(JSContext *cx, TypeSet *source, Type type) { if (!target->hasType(type)) { - if (!script->ensureRanAnalysis(cx)) + RootedScript scriptRoot(cx, script); + if (!JSScript::ensureRanAnalysis(cx, scriptRoot)) return; script->analysis()->addTypeBarrier(cx, pc, target, type); } @@ -2090,10 +2091,10 @@ AddPendingRecompile(JSContext *cx, HandleScript script, jsbytecode *pc, */ class TypeConstraintFreezeStack : public TypeConstraint { - JSScript *script_; + RawScript script_; public: - TypeConstraintFreezeStack(JSScript *script) + TypeConstraintFreezeStack(UnrootedScript script) : script_(script) {} @@ -2397,7 +2398,7 @@ types::UseNewTypeForInitializer(JSContext *cx, HandleScript script, jsbytecode * AutoEnterTypeInference enter(cx); - if (!script->ensureRanAnalysis(cx)) + if (!JSScript::ensureRanAnalysis(cx, script)) return false; return !script->analysis()->getCode(pc).inLoop; @@ -2647,9 +2648,9 @@ void TypeCompartment::monitorBytecode(JSContext *cx, HandleScript script, uint32_t offset, bool returnOnly) { - AutoAssertNoGC nogc; + AssertCanGC(); - if (!script->ensureRanInference(cx)) + if (!JSScript::ensureRanInference(cx, script)) return; ScriptAnalysis *analysis = script->analysis(); @@ -4642,6 +4643,8 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, MutableHandleObject pbaseobj, Vector *initializerList) { + AssertCanGC(); + /* * When invoking 'new' on the specified script, try to find some properties * which will definitely be added to the created object before it has a @@ -4661,7 +4664,7 @@ AnalyzeNewScriptProperties(JSContext *cx, TypeObject *type, JSFunction *fun, } RootedScript script(cx, fun->nonLazyScript()); - if (!script->ensureRanAnalysis(cx) || !script->ensureRanInference(cx)) { + if (!JSScript::ensureRanAnalysis(cx, script) || !JSScript::ensureRanInference(cx, script)) { pbaseobj.set(NULL); cx->compartment->types.setPendingNukeTypes(cx); return false; @@ -5131,13 +5134,14 @@ ScriptAnalysis::printTypes(JSContext *cx) } printf("\n"); + RootedScript script(cx, script_); for (unsigned offset = 0; offset < script_->length; offset++) { if (!maybeCode(offset)) continue; jsbytecode *pc = script_->code + offset; - PrintBytecode(cx, script_, pc); + PrintBytecode(cx, script, pc); if (js_CodeSpec[*pc].format & JOF_DECOMPOSE) continue; @@ -5282,7 +5286,7 @@ types::TypeDynamicResult(JSContext *cx, HandleScript script, jsbytecode *pc, Typ /* Directly update associated type sets for applicable bytecodes. */ if (js_CodeSpec[*pc].format & JOF_TYPESET) { - if (!script->ensureRanAnalysis(cx)) { + if (!JSScript::ensureRanAnalysis(cx, script)) { cx->compartment->types.setPendingNukeTypes(cx); return; } @@ -5385,7 +5389,7 @@ types::TypeMonitorResult(JSContext *cx, HandleScript script, jsbytecode *pc, con AutoEnterTypeInference enter(cx); - if (!script->ensureRanAnalysis(cx)) { + if (!JSScript::ensureRanAnalysis(cx, script)) { cx->compartment->types.setPendingNukeTypes(cx); return; } diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index 5290f09da5a1..b956c8954b46 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -13,7 +13,6 @@ #include "jsalloc.h" #include "jsfriendapi.h" -#include "jsprvtd.h" #include "ds/LifoAlloc.h" #include "gc/Barrier.h" @@ -21,6 +20,8 @@ #include "js/HashTable.h" #include "js/Vector.h" +ForwardDeclareJS(Script); + namespace JS { struct TypeInferenceSizes; } @@ -1105,7 +1106,7 @@ struct TypeCallsite /* Type set receiving the return value of this call. */ StackTypeSet *returnTypes; - inline TypeCallsite(JSContext *cx, JSScript *script, jsbytecode *pc, + inline TypeCallsite(JSContext *cx, UnrootedScript script, jsbytecode *pc, bool isNew, unsigned argumentCount); }; @@ -1131,7 +1132,7 @@ class TypeScript /* Array of type type sets for variables and JOF_TYPESET ops. */ TypeSet *typeArray() { return (TypeSet *) (uintptr_t(this) + sizeof(TypeScript)); } - static inline unsigned NumTypeSets(RawScript script); + static inline unsigned NumTypeSets(UnrootedScript script); static inline HeapTypeSet *ReturnTypes(RawScript script); static inline StackTypeSet *ThisTypes(RawScript script); diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 15a5b4da3275..36770bedae59 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -415,7 +415,7 @@ struct AutoEnterCompilation JS_ASSERT(info.outputIndex == RecompileInfo::NoCompilerRunning); } - bool init(JSScript *script, bool constructing, unsigned chunkIndex) + bool init(UnrootedScript script, bool constructing, unsigned chunkIndex) { CompilerOutput co; co.script = script; @@ -534,7 +534,7 @@ TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing) JSFunction *fun = callee->toFunction(); if (fun->isInterpreted()) { js::RootedScript script(cx, fun->nonLazyScript()); - if (!script->ensureRanAnalysis(cx)) + if (!JSScript::ensureRanAnalysis(cx, script)) return false; if (cx->typeInferenceEnabled()) TypeMonitorCallSlow(cx, callee, args, constructing); @@ -662,7 +662,7 @@ FixObjectType(JSContext *cx, HandleObject obj) cx->compartment->types.fixObjectType(cx, obj); } -/* Interface helpers for JSScript */ +/* Interface helpers for RawScript */ extern void TypeMonitorResult(JSContext *cx, HandleScript script, jsbytecode *pc, const js::Value &rval); extern void TypeDynamicResult(JSContext *cx, HandleScript script, jsbytecode *pc, @@ -740,7 +740,7 @@ UseNewTypeForClone(JSFunction *fun) ///////////////////////////////////////////////////////////////////// /* static */ inline unsigned -TypeScript::NumTypeSets(RawScript script) +TypeScript::NumTypeSets(UnrootedScript script) { return script->nTypeSets + analyze::TotalSlots(script); } @@ -748,6 +748,7 @@ TypeScript::NumTypeSets(RawScript script) /* static */ inline HeapTypeSet * TypeScript::ReturnTypes(RawScript script) { + AutoAssertNoGC nogc; TypeSet *types = script->types->typeArray() + script->nTypeSets + js::analyze::CalleeSlot(); return types->toHeapTypeSet(); } @@ -755,6 +756,7 @@ TypeScript::ReturnTypes(RawScript script) /* static */ inline StackTypeSet * TypeScript::ThisTypes(RawScript script) { + AutoAssertNoGC nogc; TypeSet *types = script->types->typeArray() + script->nTypeSets + js::analyze::ThisSlot(); return types->toStackTypeSet(); } @@ -768,6 +770,7 @@ TypeScript::ThisTypes(RawScript script) /* static */ inline StackTypeSet * TypeScript::ArgTypes(RawScript script, unsigned i) { + AutoAssertNoGC nogc; JS_ASSERT(i < script->function()->nargs); TypeSet *types = script->types->typeArray() + script->nTypeSets + js::analyze::ArgSlot(i); return types->toStackTypeSet(); @@ -776,6 +779,7 @@ TypeScript::ArgTypes(RawScript script, unsigned i) /* static */ inline StackTypeSet * TypeScript::LocalTypes(RawScript script, unsigned i) { + AutoAssertNoGC nogc; JS_ASSERT(i < script->nfixed); TypeSet *types = script->types->typeArray() + script->nTypeSets + js::analyze::LocalSlot(script, i); return types->toStackTypeSet(); @@ -784,6 +788,7 @@ TypeScript::LocalTypes(RawScript script, unsigned i) /* static */ inline StackTypeSet * TypeScript::SlotTypes(RawScript script, unsigned slot) { + AutoAssertNoGC nogc; JS_ASSERT(slot < js::analyze::TotalSlots(script)); TypeSet *types = script->types->typeArray() + script->nTypeSets + slot; return types->toStackTypeSet(); @@ -792,6 +797,7 @@ TypeScript::SlotTypes(RawScript script, unsigned slot) /* static */ inline TypeObject * TypeScript::StandardType(JSContext *cx, HandleScript script, JSProtoKey key) { + AssertCanGC(); js::RootedObject proto(cx); if (!js_GetClassPrototype(cx, key, &proto, NULL)) return NULL; @@ -990,7 +996,7 @@ TypeScript::SetThis(JSContext *cx, HandleScript script, Type type) ThisTypes(script)->addType(cx, type); if (analyze) - script->ensureRanInference(cx); + JSScript::ensureRanInference(cx, script); } } @@ -1478,7 +1484,7 @@ TypeSet::getTypeObject(unsigned i) const ///////////////////////////////////////////////////////////////////// inline -TypeCallsite::TypeCallsite(JSContext *cx, JSScript *script, jsbytecode *pc, +TypeCallsite::TypeCallsite(JSContext *cx, UnrootedScript script, jsbytecode *pc, bool isNew, unsigned argumentCount) : script(script), pc(pc), isNew(isNew), argumentCount(argumentCount), thisTypes(NULL), returnTypes(NULL) @@ -1715,31 +1721,31 @@ JSScript::ensureHasTypes(JSContext *cx) return types || makeTypes(cx); } -inline bool -JSScript::ensureRanAnalysis(JSContext *cx) +/* static */ inline bool +JSScript::ensureRanAnalysis(JSContext *cx, JS::HandleScript script) { + AssertCanGC(); js::analyze::AutoEnterAnalysis aea(cx->compartment); - js::RootedScript self(cx, this); - if (!self->ensureHasTypes(cx)) + if (!script->ensureHasTypes(cx)) return false; - if (!self->hasAnalysis() && !self->makeAnalysis(cx)) + if (!script->hasAnalysis() && !script->makeAnalysis(cx)) return false; - JS_ASSERT(self->analysis()->ranBytecode()); + JS_ASSERT(script->analysis()->ranBytecode()); return true; } -inline bool -JSScript::ensureRanInference(JSContext *cx) +/* static */ inline bool +JSScript::ensureRanInference(JSContext *cx, JS::HandleScript script) { - js::RootedScript self(cx, this); - if (!ensureRanAnalysis(cx)) + AssertCanGC(); + if (!script->ensureRanAnalysis(cx, script)) return false; - if (!self->analysis()->ranInference()) { + if (!script->analysis()->ranInference()) { js::types::AutoEnterTypeInference enter(cx); - self->analysis()->analyzeTypes(cx); + script->analysis()->analyzeTypes(cx); } - return !self->analysis()->OOM() && + return !script->analysis()->OOM() && !cx->compartment->types.pendingNukeTypes; } diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 9cfef84e8ed4..f3f5462a8c42 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -527,7 +527,7 @@ js::ExecuteKernel(JSContext *cx, HandleScript script, JSObject &scopeChain, cons if (!cx->stack.pushExecuteFrame(cx, script, thisv, scopeChain, type, evalInFrame, &efg)) return false; - if (!script->ensureRanAnalysis(cx)) + if (!JSScript::ensureRanAnalysis(cx, script)) return false; TypeScript::SetThis(cx, script, efg.fp()->thisValue()); @@ -1174,6 +1174,7 @@ js::Interpret(JSContext *cx, StackFrame *entryFrame, InterpMode interpMode) RootedPropertyName rootName0(cx); RootedId rootId0(cx); RootedShape rootShape0(cx); + RootedScript rootScript0(cx); DebugOnly blockDepth; if (!entryFrame) @@ -2360,7 +2361,7 @@ BEGIN_CASE(JSOP_FUNCALL) InitialFrameFlags initial = construct ? INITIAL_CONSTRUCT : INITIAL_NONE; bool newType = cx->typeInferenceEnabled() && UseNewType(cx, script, regs.pc); - RawScript funScript = fun->getOrCreateScript(cx); + RootedScript funScript(cx, fun->getOrCreateScript(cx)); if (!funScript) goto error; if (!cx->stack.pushInlineFrame(cx, regs, args, *fun, funScript, initial)) diff --git a/js/src/jsobj.cpp b/js/src/jsobj.cpp index 572b0f85dfc8..1c949351897d 100644 --- a/js/src/jsobj.cpp +++ b/js/src/jsobj.cpp @@ -2416,7 +2416,7 @@ js_CreateThisForFunction(JSContext *cx, HandleObject callee, bool newType) * checking whether document.all is defined. */ static bool -Detecting(JSContext *cx, JSScript *script, jsbytecode *pc) +Detecting(JSContext *cx, UnrootedScript script, jsbytecode *pc) { /* General case: a branch or equality op follows the access. */ JSOp op = JSOp(*pc); @@ -2467,7 +2467,7 @@ js_InferFlags(JSContext *cx, unsigned defaultFlags) * handle the case of cross-compartment property access. */ jsbytecode *pc; - JSScript *script = cx->stack.currentScript(&pc, ContextStack::ALLOW_CROSS_COMPARTMENT); + UnrootedScript script = cx->stack.currentScript(&pc, ContextStack::ALLOW_CROSS_COMPARTMENT); if (!script) return defaultFlags; @@ -4069,6 +4069,8 @@ static JS_ALWAYS_INLINE bool LookupPropertyWithFlagsInline(JSContext *cx, HandleObject obj, HandleId id, unsigned flags, MutableHandleObject objp, MutableHandleShape propp) { + AssertCanGC(); + /* Search scopes starting with obj and following the prototype link. */ RootedObject current(cx, obj); while (true) { @@ -4201,12 +4203,14 @@ js_NativeGetInline(JSContext *cx, Handle receiver, Handle if (shape->hasDefaultGetter()) return true; - jsbytecode *pc; - JSScript *script = cx->stack.currentScript(&pc); - if (script && script->hasAnalysis()) { - analyze::Bytecode *code = script->analysis()->maybeCode(pc); - if (code) - code->accessGetter = true; + { + jsbytecode *pc; + UnrootedScript script = cx->stack.currentScript(&pc); + if (script && script->hasAnalysis()) { + analyze::Bytecode *code = script->analysis()->maybeCode(pc); + if (code) + code->accessGetter = true; + } } if (!shape->get(cx, receiver, obj, pobj, vp)) @@ -4316,7 +4320,7 @@ js_GetPropertyHelperInline(JSContext *cx, HandleObject obj, HandleObject receive return true; /* Don't warn repeatedly for the same script. */ - JSScript *script = cx->stack.currentScript(); + RootedScript script(cx, cx->stack.currentScript()); if (!script || script->warnedAboutUndefinedProp) return true; @@ -4431,13 +4435,15 @@ js::GetMethod(JSContext *cx, HandleObject obj, HandleId id, unsigned getHow, Mut JS_FRIEND_API(bool) js::CheckUndeclaredVarAssignment(JSContext *cx, JSString *propname) { - JSScript *script = cx->stack.currentScript(NULL, ContextStack::ALLOW_CROSS_COMPARTMENT); - if (!script) - return true; + { + UnrootedScript script = cx->stack.currentScript(NULL, ContextStack::ALLOW_CROSS_COMPARTMENT); + if (!script) + return true; - /* If neither cx nor the code is strict, then no check is needed. */ - if (!script->strict && !cx->hasStrictOption()) - return true; + /* If neither cx nor the code is strict, then no check is needed. */ + if (!script->strict && !cx->hasStrictOption()) + return true; + } JSAutoByteString bytes(cx, propname); return !!bytes && diff --git a/js/src/jsprobes.cpp b/js/src/jsprobes.cpp index b94d07d9c8e8..65df62b845b9 100644 --- a/js/src/jsprobes.cpp +++ b/js/src/jsprobes.cpp @@ -73,7 +73,7 @@ Probes::discardMJITCode(FreeOp *fop, mjit::JITScript *jscr, mjit::JITChunk *chun bool Probes::registerICCode(JSContext *cx, - mjit::JITChunk *chunk, JSScript *script, jsbytecode* pc, + mjit::JITChunk *chunk, UnrootedScript script, jsbytecode* pc, void *start, size_t size) { if (cx->runtime->spsProfiler.enabled() && @@ -149,7 +149,7 @@ Probes::shutdown() #ifdef INCLUDE_MOZILLA_DTRACE static const char * -ScriptFilename(const JSScript *script) +ScriptFilename(const UnrootedScript script) { if (!script) return Probes::nullName; @@ -176,7 +176,7 @@ FunctionName(JSContext *cx, const JSFunction *fun, JSAutoByteString* bytes) * a number of usually unused lines of code would cause. */ void -Probes::DTraceEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script) +Probes::DTraceEnterJSFun(JSContext *cx, JSFunction *fun, UnrootedScript script) { JSAutoByteString funNameBytes; JAVASCRIPT_FUNCTION_ENTRY(ScriptFilename(script), Probes::nullName, @@ -184,7 +184,7 @@ Probes::DTraceEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script) } void -Probes::DTraceExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script) +Probes::DTraceExitJSFun(JSContext *cx, JSFunction *fun, UnrootedScript script) { JSAutoByteString funNameBytes; JAVASCRIPT_FUNCTION_RETURN(ScriptFilename(script), Probes::nullName, @@ -196,7 +196,7 @@ Probes::DTraceExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script) static void current_location(JSContext *cx, int* lineno, char const **filename) { - JSScript *script = cx->stack.currentScript() + UnrootedScript script = cx->stack.currentScript() if (! script) { *lineno = -1; *filename = "(uninitialized)"; @@ -243,7 +243,7 @@ Probes::ETWShutdown() } bool -Probes::ETWEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter) +Probes::ETWEnterJSFun(JSContext *cx, JSFunction *fun, UnrootedScript script, int counter) { int lineno = script ? script->lineno : -1; JSAutoByteString bytes; @@ -253,7 +253,7 @@ Probes::ETWEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int coun } bool -Probes::ETWExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter) +Probes::ETWExitJSFun(JSContext *cx, JSFunction *fun, UnrootedScript script, int counter) { int lineno = script ? script->lineno : -1; JSAutoByteString bytes; @@ -425,14 +425,14 @@ Probes::ETWCustomMark(int marker) } bool -Probes::ETWStartExecution(JSScript *script) +Probes::ETWStartExecution(UnrootedScript script) { int lineno = script ? script->lineno : -1; return EventWriteEvtExecuteStart(ScriptFilename(script), lineno) == ERROR_SUCCESS; } bool -Probes::ETWStopExecution(JSScript *script) +Probes::ETWStopExecution(UnrootedScript script) { int lineno = script ? script->lineno : -1; return EventWriteEvtExecuteDone(ScriptFilename(script), lineno) == ERROR_SUCCESS; diff --git a/js/src/jsprobes.h b/js/src/jsprobes.h index d54d2e97bc14..4053ecbef27e 100644 --- a/js/src/jsprobes.h +++ b/js/src/jsprobes.h @@ -92,16 +92,16 @@ bool callTrackingActive(JSContext *); bool wantNativeAddressInfo(JSContext *); /* Entering a JS function */ -bool enterScript(JSContext *, JSScript *, JSFunction *, StackFrame *); +bool enterScript(JSContext *, UnrootedScript , JSFunction *, StackFrame *); /* About to leave a JS function */ -bool exitScript(JSContext *, JSScript *, JSFunction *, StackFrame *); +bool exitScript(JSContext *, UnrootedScript , JSFunction *, StackFrame *); /* Executing a script */ -bool startExecution(JSScript *script); +bool startExecution(UnrootedScript script); /* Script has completed execution */ -bool stopExecution(JSScript *script); +bool stopExecution(UnrootedScript script); /* Heap has been resized */ bool resizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize); @@ -223,7 +223,7 @@ discardMJITCode(FreeOp *fop, mjit::JITScript *jscr, mjit::JITChunk *chunk, void* */ bool registerICCode(JSContext *cx, - mjit::JITChunk *chunk, JSScript *script, jsbytecode* pc, + mjit::JITChunk *chunk, UnrootedScript script, jsbytecode* pc, void *start, size_t size); #endif /* JS_METHODJIT */ @@ -240,8 +240,8 @@ discardExecutableRegion(void *start, size_t size); * marshalling required for these probe points is expensive enough that it * shouldn't really matter. */ -void DTraceEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script); -void DTraceExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script); +void DTraceEnterJSFun(JSContext *cx, JSFunction *fun, UnrootedScript script); +void DTraceExitJSFun(JSContext *cx, JSFunction *fun, UnrootedScript script); /* * Internal: ETW-specific probe functions @@ -252,8 +252,8 @@ bool ETWCreateRuntime(JSRuntime *rt); bool ETWDestroyRuntime(JSRuntime *rt); bool ETWShutdown(); bool ETWCallTrackingActive(); -bool ETWEnterJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter); -bool ETWExitJSFun(JSContext *cx, JSFunction *fun, JSScript *script, int counter); +bool ETWEnterJSFun(JSContext *cx, JSFunction *fun, UnrootedScript script, int counter); +bool ETWExitJSFun(JSContext *cx, JSFunction *fun, UnrootedScript script, int counter); bool ETWCreateObject(JSContext *cx, JSObject *obj); bool ETWFinalizeObject(JSObject *obj); bool ETWResizeObject(JSContext *cx, JSObject *obj, size_t oldSize, size_t newSize); @@ -274,8 +274,8 @@ bool ETWGCEndSweepPhase(); bool ETWCustomMark(JSString *string); bool ETWCustomMark(const char *string); bool ETWCustomMark(int marker); -bool ETWStartExecution(JSScript *script); -bool ETWStopExecution(JSContext *cx, JSScript *script); +bool ETWStartExecution(UnrootedScript script); +bool ETWStopExecution(JSContext *cx, UnrootedScript script); bool ETWResizeHeap(JSCompartment *compartment, size_t oldSize, size_t newSize); #endif @@ -312,7 +312,7 @@ Probes::wantNativeAddressInfo(JSContext *cx) } inline bool -Probes::enterScript(JSContext *cx, JSScript *script, JSFunction *maybeFun, +Probes::enterScript(JSContext *cx, UnrootedScript script, JSFunction *maybeFun, StackFrame *fp) { bool ok = true; @@ -339,7 +339,7 @@ Probes::enterScript(JSContext *cx, JSScript *script, JSFunction *maybeFun, } inline bool -Probes::exitScript(JSContext *cx, JSScript *script, JSFunction *maybeFun, +Probes::exitScript(JSContext *cx, UnrootedScript script, JSFunction *maybeFun, StackFrame *fp) { bool ok = true; @@ -681,7 +681,7 @@ Probes::CustomMark(int marker) } inline bool -Probes::startExecution(JSScript *script) +Probes::startExecution(UnrootedScript script) { bool ok = true; @@ -699,7 +699,7 @@ Probes::startExecution(JSScript *script) } inline bool -Probes::stopExecution(JSScript *script) +Probes::stopExecution(UnrootedScript script) { bool ok = true; diff --git a/js/src/jspropertycache.cpp b/js/src/jspropertycache.cpp index f93e608f0dbd..e8119f7a4ab4 100644 --- a/js/src/jspropertycache.cpp +++ b/js/src/jspropertycache.cpp @@ -108,7 +108,7 @@ PropertyCache::fullTest(JSContext *cx, jsbytecode *pc, JSObject **objp, JSObject PropertyCacheEntry *entry) { JSObject *obj, *pobj; - JSScript *script = cx->stack.currentScript(); + RootedScript script(cx, cx->stack.currentScript()); JS_ASSERT(this == &cx->propertyCache()); JS_ASSERT(uint32_t(pc - script->code) < script->length); diff --git a/js/src/jsprvtd.h b/js/src/jsprvtd.h index 01703d554b53..31863bed21bb 100644 --- a/js/src/jsprvtd.h +++ b/js/src/jsprvtd.h @@ -278,7 +278,7 @@ typedef JSBool typedef void (* JSNewScriptHook)(JSContext *cx, const char *filename, /* URL of script */ - unsigned lineno, /* first line */ + unsigned lineno, /* first line */ JSScript *script, JSFunction *fun, void *callerdata); @@ -286,8 +286,8 @@ typedef void /* called just before script destruction */ typedef void (* JSDestroyScriptHook)(JSFreeOp *fop, - JSRawScript script, - void *callerdata); + JSScript *script, + void *callerdata); typedef void (* JSSourceHandler)(const char *filename, unsigned lineno, const jschar *str, diff --git a/js/src/jsscript.cpp b/js/src/jsscript.cpp index 822ef7fc9db1..39d979c06d40 100644 --- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -846,7 +846,7 @@ JSScript::initScriptCounts(JSContext *cx) return true; } -static inline ScriptCountsMap::Ptr GetScriptCountsMapEntry(JSScript *script) +static inline ScriptCountsMap::Ptr GetScriptCountsMapEntry(UnrootedScript script) { JS_ASSERT(script->hasScriptCounts); ScriptCountsMap *map = script->compartment()->scriptCountsMap; @@ -1571,14 +1571,14 @@ ScriptDataSize(uint32_t length, uint32_t nsrcnotes, uint32_t nbindings, uint32_t return size; } -JSScript * +UnrootedScript JSScript::Create(JSContext *cx, HandleObject enclosingScope, bool savedCallerFun, const CompileOptions &options, unsigned staticLevel, ScriptSource *ss, uint32_t bufStart, uint32_t bufEnd) { RootedScript script(cx, js_NewGCScript(cx)); if (!script) - return NULL; + return UnrootedScript(NULL); PodZero(script.get()); new (&script->bindings) Bindings; @@ -1610,7 +1610,7 @@ JSScript::Create(JSContext *cx, HandleObject enclosingScope, bool savedCallerFun // never trigger. Oh well. if (staticLevel > UINT16_MAX) { JS_ReportErrorNumber(cx, js_GetErrorMessage, NULL, JSMSG_TOO_DEEP, js_function_str); - return NULL; + return UnrootedScript(NULL); } script->staticLevel = uint16_t(staticLevel); @@ -1885,9 +1885,10 @@ JSScript::enclosingScriptsCompiledSuccessfully() const return true; } -JS_FRIEND_API(void) -js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun) +void +js::CallNewScriptHook(JSContext *cx, HandleScript script, HandleFunction fun) { + AssertCanGC(); JS_ASSERT(!script->isActiveEval); if (JSNewScriptHook hook = cx->runtime->debugHooks.newScriptHook) { AutoKeepAtoms keep(cx->runtime); @@ -1899,6 +1900,7 @@ js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun) void js::CallDestroyScriptHook(FreeOp *fop, RawScript script) { + // The hook will only call into JS if a GC is not running. if (JSDestroyScriptHook hook = fop->runtime()->debugHooks.destroyScriptHook) hook(fop, script, fop->runtime()->debugHooks.destroyScriptHookData); script->clearTraps(fop); @@ -2167,7 +2169,7 @@ Rebase(RawScript dst, RawScript src, T *srcp) return reinterpret_cast(dst->data + off); } -JSScript * +UnrootedScript js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, HandleScript src) { AssertCanGC(); @@ -2186,7 +2188,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, uint8_t *data = AllocScriptData(cx, size); if (!data) - return NULL; + return UnrootedScript(NULL); /* Bindings */ @@ -2194,7 +2196,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, InternalHandle bindingsHandle = InternalHandle::fromMarkedLocation(bindings.address()); if (!Bindings::clone(cx, bindingsHandle, data, src)) - return NULL; + return UnrootedScript(NULL); /* Objects */ @@ -2235,7 +2237,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, clone = CloneObjectLiteral(cx, cx->global(), obj); } if (!clone || !objects.append(clone)) - return NULL; + return UnrootedScript(NULL); } } @@ -2247,7 +2249,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, for (unsigned i = 0; i < nregexps; i++) { RawObject clone = CloneScriptRegExpObject(cx, vector[i]->asRegExp()); if (!clone || !regexps.append(clone)) - return NULL; + return UnrootedScript(NULL); } } @@ -2265,7 +2267,7 @@ js::CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, src->scriptSource(), src->sourceStart, src->sourceEnd)); if (!dst) { js_free(data); - return NULL; + return UnrootedScript(NULL); } AutoAssertNoGC nogc; diff --git a/js/src/jsscript.h b/js/src/jsscript.h index 559a04b3e6ae..b4bb74bcca3c 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -240,9 +240,9 @@ class ScriptCounts } }; -typedef HashMap, + DefaultHasher, SystemAllocPolicy> ScriptCountsMap; class DebugScript @@ -268,9 +268,9 @@ class DebugScript BreakpointSite *breakpoints[1]; }; -typedef HashMap, + DefaultHasher, SystemAllocPolicy> DebugScriptMap; struct ScriptSource; @@ -512,9 +512,9 @@ struct JSScript : public js::gc::Cell // public: - static JSScript *Create(JSContext *cx, js::HandleObject enclosingScope, bool savedCallerFun, - const JS::CompileOptions &options, unsigned staticLevel, - js::ScriptSource *ss, uint32_t sourceStart, uint32_t sourceEnd); + static js::UnrootedScript Create(JSContext *cx, js::HandleObject enclosingScope, bool savedCallerFun, + const JS::CompileOptions &options, unsigned staticLevel, + js::ScriptSource *ss, uint32_t sourceStart, uint32_t sourceEnd); // Three ways ways to initialize a JSScript. Callers of partiallyInit() // and fullyInitTrivial() are responsible for notifying the debugger after @@ -642,10 +642,10 @@ struct JSScript : public js::gc::Cell * Ensure the script has bytecode analysis information. Performed when the * script first runs, or first runs after a TypeScript GC purge. */ - inline bool ensureRanAnalysis(JSContext *cx); + static inline bool ensureRanAnalysis(JSContext *cx, JS::HandleScript script); /* Ensure the script has type inference analysis information. */ - inline bool ensureRanInference(JSContext *cx); + static inline bool ensureRanInference(JSContext *cx, JS::HandleScript script); inline bool hasAnalysis(); inline void clearAnalysis(); @@ -772,7 +772,7 @@ struct JSScript : public js::gc::Cell bool hasArray(ArrayKind kind) { return (hasArrayBits & (1 << kind)); } void setHasArray(ArrayKind kind) { hasArrayBits |= (1 << kind); } - void cloneHasArray(JSScript *script) { hasArrayBits = script->hasArrayBits; } + void cloneHasArray(js::UnrootedScript script) { hasArrayBits = script->hasArrayBits; } bool hasConsts() { return hasArray(CONSTS); } bool hasObjects() { return hasArray(OBJECTS); } @@ -920,8 +920,8 @@ struct JSScript : public js::gc::Cell void finalize(js::FreeOp *fop); - static inline void writeBarrierPre(JSScript *script); - static inline void writeBarrierPost(JSScript *script, void *addr); + static inline void writeBarrierPre(js::UnrootedScript script); + static inline void writeBarrierPost(js::UnrootedScript script, void *addr); static inline js::ThingRootKind rootKind() { return js::THING_ROOT_SCRIPT; } @@ -997,7 +997,7 @@ class AliasedFormalIter } public: - explicit inline AliasedFormalIter(JSScript *script); + explicit inline AliasedFormalIter(js::UnrootedScript script); bool done() const { return p_ == end_; } operator bool() const { return !done(); } @@ -1009,20 +1009,6 @@ class AliasedFormalIter unsigned scopeSlot() const { JS_ASSERT(!done()); return slot_; } }; -} /* namespace js */ - -/* - * New-script-hook calling is factored from JSScript::fullyInitFromEmitter() so - * that it and callers of XDRScript() can share this code. In the case of - * callers of XDRScript(), the hook should be invoked only after successful - * decode of any owning function (the fun parameter) or script object (null - * fun). - */ -extern JS_FRIEND_API(void) -js_CallNewScriptHook(JSContext *cx, JSScript *script, JSFunction *fun); - -namespace js { - struct SourceCompressionToken; struct ScriptSource @@ -1213,6 +1199,16 @@ struct SourceCompressionToken bool active() const { return !!ss; } }; +/* + * New-script-hook calling is factored from JSScript::fullyInitFromEmitter() so + * that it and callers of XDRScript() can share this code. In the case of + * callers of XDRScript(), the hook should be invoked only after successful + * decode of any owning function (the fun parameter) or script object (null + * fun). + */ +extern void +CallNewScriptHook(JSContext *cx, JS::HandleScript script, JS::HandleFunction fun); + extern void CallDestroyScriptHook(FreeOp *fop, js::RawScript script); @@ -1253,7 +1249,8 @@ FreeScriptFilenames(JSRuntime *rt); struct ScriptAndCounts { - JSScript *script; + /* This structure is stored and marked from the JSRuntime. */ + js::RawScript script; ScriptCounts scriptCounts; PCCounts &getPCCounts(jsbytecode *pc) const { @@ -1306,7 +1303,7 @@ enum LineOption { inline void CurrentScriptFileLineOrigin(JSContext *cx, unsigned *linenop, LineOption = NOT_CALLED_FROM_JSOP_EVAL); -extern JSScript * +extern UnrootedScript CloneScript(JSContext *cx, HandleObject enclosingScope, HandleFunction fun, HandleScript script); /* diff --git a/js/src/jsscriptinlines.h b/js/src/jsscriptinlines.h index 5de333f29c96..c5c5fd92cc50 100644 --- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -28,7 +28,7 @@ Bindings::Bindings() {} inline -AliasedFormalIter::AliasedFormalIter(JSScript *script) +AliasedFormalIter::AliasedFormalIter(js::UnrootedScript script) : begin_(script->bindings.bindingArray()), p_(begin_), end_(begin_ + (script->funHasAnyAliasedFormal ? script->bindings.numArgs() : 0)), @@ -151,7 +151,7 @@ JSScript::destroyMJITInfo(js::FreeOp *fop) #endif /* JS_METHODJIT */ inline void -JSScript::writeBarrierPre(JSScript *script) +JSScript::writeBarrierPre(js::UnrootedScript script) { #ifdef JSGC_INCREMENTAL if (!script) @@ -160,7 +160,7 @@ JSScript::writeBarrierPre(JSScript *script) JSCompartment *comp = script->compartment(); if (comp->needsBarrier()) { JS_ASSERT(!comp->rt->isHeapBusy()); - JSScript *tmp = script; + js::UnrootedScript tmp = script; MarkScriptUnbarriered(comp->barrierTracer(), &tmp, "write barrier"); JS_ASSERT(tmp == script); } @@ -168,7 +168,7 @@ JSScript::writeBarrierPre(JSScript *script) } inline void -JSScript::writeBarrierPost(JSScript *script, void *addr) +JSScript::writeBarrierPost(js::UnrootedScript script, void *addr) { } diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index b967adae6c92..1184a47a6df7 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -161,7 +161,7 @@ mjit::Compiler::compile() CompileStatus mjit::Compiler::checkAnalysis(HandleScript script) { - if (!script->ensureRanAnalysis(cx)) + if (!JSScript::ensureRanAnalysis(cx, script)) return Compile_Error; if (!script->analysis()->jaegerCompileable()) { @@ -169,7 +169,7 @@ mjit::Compiler::checkAnalysis(HandleScript script) return Compile_Abort; } - if (cx->typeInferenceEnabled() && !script->ensureRanInference(cx)) + if (cx->typeInferenceEnabled() && !JSScript::ensureRanInference(cx, script)) return Compile_Error; ScriptAnalysis *analysis = script->analysis(); @@ -672,9 +672,10 @@ mjit::SetChunkLimit(uint32_t limit) } JITScript * -MakeJITScript(JSContext *cx, JSScript *script) +MakeJITScript(JSContext *cx, HandleScript script) { - if (!script->ensureRanAnalysis(cx)) + AssertCanGC(); + if (!JSScript::ensureRanAnalysis(cx, script)) return NULL; ScriptAnalysis *analysis = script->analysis(); @@ -689,7 +690,7 @@ MakeJITScript(JSContext *cx, JSScript *script) if (!chunks.append(desc)) return NULL; } else { - if (!script->ensureRanInference(cx)) + if (!JSScript::ensureRanInference(cx, script)) return NULL; /* Outgoing edges within the current chunk. */ @@ -993,11 +994,10 @@ IonGetsFirstChance(JSContext *cx, JSScript *script, CompileRequest request) } CompileStatus -mjit::CanMethodJIT(JSContext *cx, JSScript *scriptArg, jsbytecode *pc, +mjit::CanMethodJIT(JSContext *cx, HandleScript script, jsbytecode *pc, bool construct, CompileRequest request, StackFrame *frame) { bool compiledOnce = false; - RootedScript script(cx, scriptArg); checkOutput: if (!cx->methodJitEnabled) return Compile_Abort; @@ -1020,7 +1020,7 @@ mjit::CanMethodJIT(JSContext *cx, JSScript *scriptArg, jsbytecode *pc, if (frame->hasPushedSPSFrame() != cx->runtime->spsProfiler.enabled()) return Compile_Skipped; } - + if (IonGetsFirstChance(cx, script, request)) return Compile_Skipped; diff --git a/js/src/methodjit/InvokeHelpers.cpp b/js/src/methodjit/InvokeHelpers.cpp index 946aab8653da..dd1cbe6a80be 100644 --- a/js/src/methodjit/InvokeHelpers.cpp +++ b/js/src/methodjit/InvokeHelpers.cpp @@ -613,7 +613,7 @@ js_InternalThrow(VMFrame &f) */ cx->jaegerRuntime().setLastUnfinished(Jaeger_Unfinished); - if (!script->ensureRanAnalysis(cx)) { + if (!JSScript::ensureRanAnalysis(cx, script)) { js_ReportOutOfMemory(cx); return NULL; } @@ -708,11 +708,11 @@ stubs::CrossChunkShim(VMFrame &f, void *edge_) mjit::ExpandInlineFrames(f.cx->compartment); - UnrootedScript script = f.script(); + RootedScript script(f.cx, f.script()); JS_ASSERT(edge->target < script->length); JS_ASSERT(script->code + edge->target == f.pc()); - CompileStatus status = CanMethodJIT(f.cx, DropUnrooted(script), f.pc(), + CompileStatus status = CanMethodJIT(f.cx, script, f.pc(), f.fp()->isConstructing(), CompileRequest_Interpreter, f.fp()); if (status == Compile_Error) @@ -758,7 +758,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM JSOp op = JSOp(*pc); - if (!script->ensureRanAnalysis(cx)) { + if (!JSScript::ensureRanAnalysis(cx, script)) { js_ReportOutOfMemory(cx); return js_InternalThrow(f); } diff --git a/js/src/methodjit/MethodJIT.h b/js/src/methodjit/MethodJIT.h index 027ef8d5a989..6087472c262b 100644 --- a/js/src/methodjit/MethodJIT.h +++ b/js/src/methodjit/MethodJIT.h @@ -914,7 +914,7 @@ enum CompileRequest }; CompileStatus -CanMethodJIT(JSContext *cx, JSScript *script, jsbytecode *pc, +CanMethodJIT(JSContext *cx, HandleScript script, jsbytecode *pc, bool construct, CompileRequest request, StackFrame *sp); inline void diff --git a/js/src/methodjit/PolyIC.cpp b/js/src/methodjit/PolyIC.cpp index e669d3074883..1b4e58d35ff0 100644 --- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -419,9 +419,9 @@ class SetPropCompiler : public PICStubCompiler return false; jsbytecode *pc; - JSScript *script = cx->stack.currentScript(&pc); + RootedScript script(cx, cx->stack.currentScript(&pc)); - if (!script->ensureRanInference(cx) || monitor.recompiled()) + if (!JSScript::ensureRanInference(cx, script) || monitor.recompiled()) return false; JS_ASSERT(*pc == JSOP_SETPROP || *pc == JSOP_SETNAME); @@ -2219,7 +2219,7 @@ frameCountersOffset(VMFrame &f) } jsbytecode *pc; - JSScript *script = cx->stack.currentScript(&pc); + UnrootedScript script = cx->stack.currentScript(&pc); offset += pc - script->code; return offset; diff --git a/js/src/methodjit/StubCalls.cpp b/js/src/methodjit/StubCalls.cpp index bc3fd2fd1e12..9365b03ebf3d 100644 --- a/js/src/methodjit/StubCalls.cpp +++ b/js/src/methodjit/StubCalls.cpp @@ -834,7 +834,8 @@ stubs::TriggerIonCompile(VMFrame &f) if (*osrPC != JSOP_LOOPENTRY) osrPC = NULL; - if (!ion::TestIonCompile(f.cx, script, script->function(), osrPC, f.fp()->isConstructing())) { + RootedFunction scriptFunction(f.cx, script->function()); + if (!ion::TestIonCompile(f.cx, script, scriptFunction, osrPC, f.fp()->isConstructing())) { if (f.cx->isExceptionPending()) THROW(); } diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 9e22913b01be..e4bc0936448d 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -520,9 +520,9 @@ static void Process(JSContext *cx, JSObject *obj_, const char *filename, bool forceTTY) { bool ok, hitEOF; - JSScript *script; + RootedScript script(cx); jsval result; - JSString *str; + RootedString str(cx); char *buffer; size_t size; jschar *uc_buffer; @@ -1055,7 +1055,7 @@ Evaluate(JSContext *cx, unsigned argc, jsval *vp) options |= JSOPTION_NO_SCRIPT_RVAL; JS_SetOptions(cx, options); - JSScript *script = JS_CompileUCScript(cx, global, codeChars, codeLength, fileName, lineNumber); + RootedScript script(cx, JS_CompileUCScript(cx, global, codeChars, codeLength, fileName, lineNumber)); JS_SetOptions(cx, saved); if (!script) return false; @@ -1201,7 +1201,7 @@ Run(JSContext *cx, unsigned argc, jsval *vp) JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL); int64_t startClock = PRMJ_Now(); - JSScript *script = JS_CompileUCScript(cx, thisobj, ucbuf, buflen, filename.ptr(), 1); + RootedScript script(cx, JS_CompileUCScript(cx, thisobj, ucbuf, buflen, filename.ptr(), 1)); JS_SetOptions(cx, oldopts); if (!script || !JS_ExecuteScript(cx, thisobj, script, NULL)) return false; @@ -1450,12 +1450,12 @@ AssertJit(JSContext *cx, unsigned argc, jsval *vp) return true; } -static JSScript * +static UnrootedScript ValueToScript(JSContext *cx, jsval v, JSFunction **funp = NULL) { RootedFunction fun(cx, JS_ValueToFunction(cx, v)); if (!fun) - return NULL; + return UnrootedScript(NULL); RootedScript script(cx); fun->maybeGetOrCreateScript(cx, &script); @@ -1491,19 +1491,19 @@ SetDebug(JSContext *cx, unsigned argc, jsval *vp) return ok; } -static JSScript * +static UnrootedScript GetTopScript(JSContext *cx) { - JSScript *script; - JS_DescribeScriptedCaller(cx, &script, NULL); + RootedScript script(cx); + JS_DescribeScriptedCaller(cx, script.address(), NULL); return script; } static JSBool -GetScriptAndPCArgs(JSContext *cx, unsigned argc, jsval *argv, JSScript **scriptp, +GetScriptAndPCArgs(JSContext *cx, unsigned argc, jsval *argv, MutableHandleScript scriptp, int32_t *ip) { - JSScript *script = GetTopScript(cx); + RootedScript script(cx, GetTopScript(cx)); *ip = 0; if (argc != 0) { jsval v = argv[0]; @@ -1525,13 +1525,13 @@ GetScriptAndPCArgs(JSContext *cx, unsigned argc, jsval *argv, JSScript **scriptp } } - *scriptp = script; + scriptp.set(script); return true; } static JSTrapStatus -TrapHandler(JSContext *cx, JSScript *, jsbytecode *pc, jsval *rval, +TrapHandler(JSContext *cx, RawScript, jsbytecode *pc, jsval *rval, jsval closure) { JSString *str = JSVAL_TO_STRING(closure); @@ -1563,7 +1563,7 @@ static JSBool Trap(JSContext *cx, unsigned argc, jsval *vp) { JSString *str; - JSScript *script; + RootedScript script(cx); int32_t i; jsval *argv = JS_ARGV(cx, vp); @@ -1589,7 +1589,7 @@ Trap(JSContext *cx, unsigned argc, jsval *vp) static JSBool Untrap(JSContext *cx, unsigned argc, jsval *vp) { - JSScript *script; + RootedScript script(cx); int32_t i; if (!GetScriptAndPCArgs(cx, argc, JS_ARGV(cx, vp), &script, &i)) @@ -1600,7 +1600,7 @@ Untrap(JSContext *cx, unsigned argc, jsval *vp) } static JSTrapStatus -DebuggerAndThrowHandler(JSContext *cx, JSScript *script, jsbytecode *pc, jsval *rval, +DebuggerAndThrowHandler(JSContext *cx, RawScript script, jsbytecode *pc, jsval *rval, void *closure) { return TrapHandler(cx, script, pc, rval, STRING_TO_JSVAL((JSString *)closure)); @@ -1678,7 +1678,7 @@ LineToPC(JSContext *cx, unsigned argc, jsval *vp) static JSBool PCToLine(JSContext *cx, unsigned argc, jsval *vp) { - JSScript *script; + RootedScript script(cx); int32_t i; unsigned lineno; @@ -1694,7 +1694,7 @@ PCToLine(JSContext *cx, unsigned argc, jsval *vp) #ifdef DEBUG static void -UpdateSwitchTableBounds(JSContext *cx, JSScript *script, unsigned offset, +UpdateSwitchTableBounds(JSContext *cx, HandleScript script, unsigned offset, unsigned *start, unsigned *end) { jsbytecode *pc; @@ -1734,7 +1734,7 @@ UpdateSwitchTableBounds(JSContext *cx, JSScript *script, unsigned offset, } static void -SrcNotes(JSContext *cx, JSScript *script, Sprinter *sp) +SrcNotes(JSContext *cx, HandleScript script, Sprinter *sp) { Sprint(sp, "\nSource notes:\n"); Sprint(sp, "%4s %4s %5s %6s %-8s %s\n", @@ -1851,7 +1851,7 @@ Notes(JSContext *cx, unsigned argc, jsval *vp) jsval *argv = JS_ARGV(cx, vp); for (unsigned i = 0; i < argc; i++) { - JSScript *script = ValueToScript(cx, argv[i]); + RootedScript script (cx, ValueToScript(cx, argv[i])); if (!script) return false; @@ -1872,7 +1872,7 @@ JS_STATIC_ASSERT(JSTRY_ITER == 2); static const char* const TryNoteNames[] = { "catch", "finally", "iter" }; static JSBool -TryNotes(JSContext *cx, JSScript *script, Sprinter *sp) +TryNotes(JSContext *cx, HandleScript script, Sprinter *sp) { JSTryNote *tn, *tnlimit; @@ -1892,11 +1892,9 @@ TryNotes(JSContext *cx, JSScript *script, Sprinter *sp) } static bool -DisassembleScript(JSContext *cx, JSScript *script_, JSFunction *fun, bool lines, bool recursive, +DisassembleScript(JSContext *cx, HandleScript script, JSFunction *fun, bool lines, bool recursive, Sprinter *sp) { - Rooted script(cx, script_); - if (fun) { Sprint(sp, "flags:"); if (fun->isLambda()) @@ -1928,7 +1926,7 @@ DisassembleScript(JSContext *cx, JSScript *script_, JSFunction *fun, bool lines, RawFunction fun = obj->toFunction(); RootedScript script(cx); fun->maybeGetOrCreateScript(cx, &script); - if (!DisassembleScript(cx, script.get(), fun, lines, recursive, sp)) + if (!DisassembleScript(cx, script, fun, lines, recursive, sp)) return false; } } @@ -1987,7 +1985,7 @@ DisassembleToSprinter(JSContext *cx, unsigned argc, jsval *vp, Sprinter *sprinte } else { for (unsigned i = 0; i < p.argc; i++) { JSFunction *fun; - JSScript *script = ValueToScript(cx, p.argv[i], &fun); + RootedScript script (cx, ValueToScript(cx, p.argv[i], &fun)); if (!script) return false; if (!DisassembleScript(cx, script, fun, p.lines, p.recursive, sprinter)) @@ -2056,7 +2054,7 @@ DisassFile(JSContext *cx, unsigned argc, jsval *vp) CompileOptions options(cx); options.setUTF8(true) .setFileAndLine(filename.ptr(), 1); - JSScript *script = JS::Compile(cx, thisobj, options, filename.ptr()); + RootedScript script (cx, JS::Compile(cx, thisobj, options, filename.ptr())); JS_SetOptions(cx, oldopts); if (!script) return false; @@ -2429,7 +2427,7 @@ GetPDA(JSContext *cx, unsigned argc, jsval *vp) static JSBool GetSLX(JSContext *cx, unsigned argc, jsval *vp) { - JSScript *script; + RootedScript script(cx); script = ValueToScript(cx, argc == 0 ? JSVAL_VOID : vp[2]); if (!script) @@ -2608,10 +2606,10 @@ EvalInContext(JSContext *cx, unsigned argc, jsval *vp) return true; } - JSScript *script; + RootedScript script(cx); unsigned lineno; - JS_DescribeScriptedCaller(cx, &script, &lineno); + JS_DescribeScriptedCaller(cx, script.address(), &lineno); jsval rval; { Maybe ac; @@ -3314,7 +3312,7 @@ Snarf(JSContext *cx, unsigned argc, jsval *vp) return false; /* Get the currently executing script's name. */ - JSScript *script = GetTopScript(cx); + RootedScript script(cx, GetTopScript(cx)); JS_ASSERT(script->filename); const char *pathname = filename.ptr(); #ifdef XP_UNIX @@ -3381,8 +3379,8 @@ static JSBool DecompileThisScript(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); - JSScript *script = NULL; - if (!JS_DescribeScriptedCaller(cx, &script, NULL)) { + RootedScript script (cx); + if (!JS_DescribeScriptedCaller(cx, script.address(), NULL)) { args.rval().setString(cx->runtime->emptyString); return true; } @@ -3397,8 +3395,8 @@ static JSBool ThisFilename(JSContext *cx, unsigned argc, Value *vp) { CallArgs args = CallArgsFromVp(argc, vp); - JSScript *script = NULL; - if (!JS_DescribeScriptedCaller(cx, &script, NULL) || !script->filename) { + RootedScript script (cx); + if (!JS_DescribeScriptedCaller(cx, script.address(), NULL) || !script->filename) { args.rval().setString(cx->runtime->emptyString); return true; } diff --git a/js/src/vm/ForkJoin.h b/js/src/vm/ForkJoin.h index 2d3c74044b20..8cb5c0d837f4 100644 --- a/js/src/vm/ForkJoin.h +++ b/js/src/vm/ForkJoin.h @@ -94,6 +94,7 @@ struct ForkJoinOp; // thread will also execute one slice. ParallelResult ExecuteForkJoinOp(JSContext *cx, ForkJoinOp &op); +class PerThreadData; class ForkJoinShared; class AutoRendezvous; class AutoSetForkJoinSlice; diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index 7e455f1a8ea2..0be3d439cd3b 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -406,7 +406,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx) * |Function.prototype| -- after all initialization, for simplicity. */ RootedScript functionProtoScript(cx, functionProto->nonLazyScript()); - js_CallNewScriptHook(cx, functionProtoScript, functionProto); + CallNewScriptHook(cx, functionProtoScript, functionProto); return functionProto; } diff --git a/js/src/vm/ObjectImpl.cpp b/js/src/vm/ObjectImpl.cpp index 66e4076f6cc9..90e286271361 100644 --- a/js/src/vm/ObjectImpl.cpp +++ b/js/src/vm/ObjectImpl.cpp @@ -260,6 +260,7 @@ MOZ_NEVER_INLINE UnrootedShape js::ObjectImpl::nativeLookup(JSContext *cx, jsid idArg) { + AssertCanGC(); MOZ_ASSERT(isNative()); Shape **spp; RootedId id(cx, idArg); diff --git a/js/src/vm/SPSProfiler.cpp b/js/src/vm/SPSProfiler.cpp index 6db2a8493b97..5e5a766e12b8 100644 --- a/js/src/vm/SPSProfiler.cpp +++ b/js/src/vm/SPSProfiler.cpp @@ -371,7 +371,7 @@ SPSProfiler::discardMJITCode(mjit::JITScript *jscr, } void -SPSProfiler::unregisterScript(JSScript *script, mjit::JITChunk *chunk) +SPSProfiler::unregisterScript(UnrootedScript script, mjit::JITChunk *chunk) { JITInfoMap::Ptr ptr = jminfo.lookup(script); if (!ptr) diff --git a/js/src/vm/SPSProfiler.h b/js/src/vm/SPSProfiler.h index d003ea0ea67a..5aeb97d5c7d7 100644 --- a/js/src/vm/SPSProfiler.h +++ b/js/src/vm/SPSProfiler.h @@ -238,7 +238,7 @@ class SPSProfiler JMChunkInfo *registerScript(mjit::JSActiveFrame *frame, mjit::PCLengthEntry *lenths, mjit::JITChunk *chunk); - void unregisterScript(JSScript *script, mjit::JITChunk *chunk); + void unregisterScript(UnrootedScript script, mjit::JITChunk *chunk); public: #else jsbytecode *ipToPC(JSScript *script, size_t ip) { return NULL; } diff --git a/js/src/vm/ScopeObject.cpp b/js/src/vm/ScopeObject.cpp index c2fbd4cf5dd8..8dd1908f489a 100644 --- a/js/src/vm/ScopeObject.cpp +++ b/js/src/vm/ScopeObject.cpp @@ -158,7 +158,7 @@ CallObject::create(JSContext *cx, HandleShape shape, HandleTypeObject type, Heap * callee) or used as a template for jit compilation. */ CallObject * -CallObject::createTemplateObject(JSContext *cx, JSScript *script) +CallObject::createTemplateObject(JSContext *cx, HandleScript script) { RootedShape shape(cx, script->bindings.callObjShape()); diff --git a/js/src/vm/ScopeObject.h b/js/src/vm/ScopeObject.h index b76174f6fb11..46c26578f8f4 100644 --- a/js/src/vm/ScopeObject.h +++ b/js/src/vm/ScopeObject.h @@ -189,7 +189,7 @@ class CallObject : public ScopeObject create(JSContext *cx, HandleShape shape, HandleTypeObject type, HeapSlot *slots); static CallObject * - createTemplateObject(JSContext *cx, JSScript *script); + createTemplateObject(JSContext *cx, HandleScript script); static const uint32_t RESERVED_SLOTS = 2; diff --git a/js/src/vm/Stack-inl.h b/js/src/vm/Stack-inl.h index 992c569b5293..1cd4707260af 100644 --- a/js/src/vm/Stack-inl.h +++ b/js/src/vm/Stack-inl.h @@ -132,9 +132,8 @@ StackFrame::resetInlinePrev(StackFrame *prevfp, jsbytecode *prevpc) inline void StackFrame::initCallFrame(JSContext *cx, JSFunction &callee, - JSScript *script, uint32_t nactual, StackFrame::Flags flagsArg) + UnrootedScript script, uint32_t nactual, StackFrame::Flags flagsArg) { - AutoAssertNoGC nogc; JS_ASSERT((flagsArg & ~(CONSTRUCTING | LOWERED_CALL_APPLY | OVERFLOW_ARGS | @@ -415,7 +414,7 @@ StackSpace::getStackLimit(JSContext *cx, MaybeReportError report) JS_ALWAYS_INLINE StackFrame * ContextStack::getCallFrame(JSContext *cx, MaybeReportError report, const CallArgs &args, - JSFunction *fun, JSScript *script, StackFrame::Flags *flags) const + JSFunction *fun, HandleScript script, StackFrame::Flags *flags) const { mozilla::Maybe maybeNoGC; if (report) @@ -461,7 +460,7 @@ ContextStack::getCallFrame(JSContext *cx, MaybeReportError report, const CallArg JS_ALWAYS_INLINE bool ContextStack::pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &args, - JSFunction &callee, JSScript *script, + JSFunction &callee, HandleScript script, InitialFrameFlags initial, MaybeReportError report) { mozilla::Maybe maybeNoGC; @@ -493,7 +492,7 @@ ContextStack::pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &ar JS_ALWAYS_INLINE bool ContextStack::pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &args, - JSFunction &callee, JSScript *script, + JSFunction &callee, HandleScript script, InitialFrameFlags initial, Value **stackLimit) { AssertCanGC(); @@ -505,7 +504,7 @@ ContextStack::pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &ar JS_ALWAYS_INLINE StackFrame * ContextStack::getFixupFrame(JSContext *cx, MaybeReportError report, - const CallArgs &args, JSFunction *fun, JSScript *script, + const CallArgs &args, JSFunction *fun, HandleScript script, void *ncode, InitialFrameFlags initial, Value **stackLimit) { AssertCanGC(); @@ -548,7 +547,7 @@ ContextStack::popFrameAfterOverflow() regs.popFrame(fp->actuals() + fp->numActualArgs()); } -inline JSScript * +inline UnrootedScript ContextStack::currentScript(jsbytecode **ppc, MaybeAllowCrossCompartment allowCrossCompartment) const { @@ -568,7 +567,7 @@ ContextStack::currentScript(jsbytecode **ppc, RootedScript script(cx_); ion::GetPcScript(cx_, &script, ppc); if (!allowCrossCompartment && script->compartment() != cx_->compartment) - return NULL; + return UnrootedScript(NULL); return script; } #endif @@ -581,7 +580,7 @@ ContextStack::currentScript(jsbytecode **ppc, mjit::InlineFrame *frame = &chunk->inlineFrames()[inlined->inlineIndex]; UnrootedScript script = frame->fun->nonLazyScript(); if (!allowCrossCompartment && script->compartment() != cx_->compartment) - return NULL; + return UnrootedScript(NULL); if (ppc) *ppc = script->code + inlined->pcOffset; return script; @@ -590,7 +589,7 @@ ContextStack::currentScript(jsbytecode **ppc, UnrootedScript script = fp->script(); if (!allowCrossCompartment && script->compartment() != cx_->compartment) - return NULL; + return UnrootedScript(NULL); if (ppc) *ppc = fp->pcQuadratic(*this); diff --git a/js/src/vm/Stack.cpp b/js/src/vm/Stack.cpp index a7186b0a39f1..42fb986f51a2 100644 --- a/js/src/vm/Stack.cpp +++ b/js/src/vm/Stack.cpp @@ -48,7 +48,7 @@ using mozilla::DebugOnly; /*****************************************************************************/ void -StackFrame::initExecuteFrame(JSScript *script, StackFrame *prev, FrameRegs *regs, +StackFrame::initExecuteFrame(UnrootedScript script, StackFrame *prev, FrameRegs *regs, const Value &thisv, JSObject &scopeChain, ExecuteType type) { /* @@ -72,7 +72,7 @@ StackFrame::initExecuteFrame(JSScript *script, StackFrame *prev, FrameRegs *regs dstvp[0] = NullValue(); exec.script = script; #ifdef DEBUG - u.evalScript = (JSScript *)0xbad; + u.evalScript = (RawScript)0xbad; #endif } @@ -1244,7 +1244,7 @@ void StackIter::poisonRegs() { pc_ = (jsbytecode *)0xbad; - script_ = (JSScript *)0xbad; + script_ = (RawScript)0xbad; } void diff --git a/js/src/vm/Stack.h b/js/src/vm/Stack.h index 3d463e4bbc66..90f45235506f 100644 --- a/js/src/vm/Stack.h +++ b/js/src/vm/Stack.h @@ -282,12 +282,12 @@ class StackFrame private: mutable uint32_t flags_; /* bits described by Flags */ union { /* describes what code is executing in a */ - JSScript *script; /* global frame */ + RawScript script; /* global frame */ JSFunction *fun; /* function frame, pre GetScopeChain */ } exec; union { /* describes the arguments of a function */ unsigned nactual; /* for non-eval frames */ - JSScript *evalScript; /* the script of an eval-in-function */ + RawScript evalScript; /* the script of an eval-in-function */ } u; mutable JSObject *scopeChain_; /* if HAS_SCOPECHAIN, current scope chain */ StackFrame *prev_; /* if HAS_PREVPC, previous cx->regs->fp */ @@ -345,13 +345,13 @@ class StackFrame /* Used for Invoke, Interpret, trace-jit LeaveTree, and method-jit stubs. */ void initCallFrame(JSContext *cx, JSFunction &callee, - JSScript *script, uint32_t nactual, StackFrame::Flags flags); + UnrootedScript script, uint32_t nactual, StackFrame::Flags flags); /* Used for getFixupFrame (for FixupArity). */ void initFixupFrame(StackFrame *prev, StackFrame::Flags flags, void *ncode, unsigned nactual); /* Used for eval. */ - void initExecuteFrame(JSScript *script, StackFrame *prev, FrameRegs *regs, + void initExecuteFrame(UnrootedScript script, StackFrame *prev, FrameRegs *regs, const Value &thisv, JSObject &scopeChain, ExecuteType type); public: @@ -1192,7 +1192,7 @@ class FrameRegs } /* For stubs::CompileFunction, ContextStack: */ - void prepareToRun(StackFrame &fp, JSScript *script) { + void prepareToRun(StackFrame &fp, UnrootedScript script) { pc = script->code; sp = fp.slots() + script->nfixed; fp_ = &fp; @@ -1489,7 +1489,7 @@ class ContextStack inline StackFrame * getCallFrame(JSContext *cx, MaybeReportError report, const CallArgs &args, - JSFunction *fun, JSScript *script, StackFrame::Flags *pflags) const; + JSFunction *fun, HandleScript script, StackFrame::Flags *pflags) const; /* Make pop* functions private since only called by guard classes. */ void popSegment(); @@ -1590,11 +1590,11 @@ class ContextStack * The 'stackLimit' overload updates 'stackLimit' if it changes. */ bool pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &args, - JSFunction &callee, JSScript *script, + JSFunction &callee, HandleScript script, InitialFrameFlags initial, MaybeReportError report = REPORT_ERROR); bool pushInlineFrame(JSContext *cx, FrameRegs ®s, const CallArgs &args, - JSFunction &callee, JSScript *script, + JSFunction &callee, HandleScript script, InitialFrameFlags initial, Value **stackLimit); void popInlineFrame(FrameRegs ®s); @@ -1611,8 +1611,8 @@ class ContextStack DONT_ALLOW_CROSS_COMPARTMENT = false, ALLOW_CROSS_COMPARTMENT = true }; - inline JSScript *currentScript(jsbytecode **pc = NULL, - MaybeAllowCrossCompartment = DONT_ALLOW_CROSS_COMPARTMENT) const; + inline UnrootedScript currentScript(jsbytecode **pc = NULL, + MaybeAllowCrossCompartment = DONT_ALLOW_CROSS_COMPARTMENT) const; /* Get the scope chain for the topmost scripted call on the stack. */ inline HandleObject currentScriptedScopeChain() const; @@ -1623,7 +1623,7 @@ class ContextStack * FixupArity returns. */ StackFrame *getFixupFrame(JSContext *cx, MaybeReportError report, - const CallArgs &args, JSFunction *fun, JSScript *script, + const CallArgs &args, JSFunction *fun, HandleScript script, void *ncode, InitialFrameFlags initial, Value **stackLimit); bool saveFrameChain(); diff --git a/js/src/vm/Xdr.cpp b/js/src/vm/Xdr.cpp index 4edc242c72a6..4d08d17bf12d 100644 --- a/js/src/vm/Xdr.cpp +++ b/js/src/vm/Xdr.cpp @@ -148,7 +148,7 @@ XDRState::codeScript(MutableHandleScript scriptp) if (mode == XDR_DECODE) { JS_ASSERT(!script->compileAndGo); - js_CallNewScriptHook(cx(), script, NULL); + CallNewScriptHook(cx(), script, NullPtr()); Debugger::onNewScript(cx(), script, NULL); scriptp.set(script); }