diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index 401289610d7..9e5c2b84402 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -2243,7 +2243,7 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx, script = frameScript; } - else if (!JS_GetScriptPrincipals(cx, script)) + else if (!js::IsOriginalScriptFunction(fun)) { // Here, obj is a cloned function object. In this case, the // clone's prototype may have been precompiled from brutally diff --git a/js/src/frontend/BytecodeCompiler.cpp b/js/src/frontend/BytecodeCompiler.cpp index e198f5ef31d..c8750b4586e 100644 --- a/js/src/frontend/BytecodeCompiler.cpp +++ b/js/src/frontend/BytecodeCompiler.cpp @@ -355,7 +355,7 @@ Compiler::defineGlobals(JSContext *cx, GlobalScope &globalScope, JSScript *scrip JSFunction *fun = obj->toFunction(); JS_ASSERT(fun->isInterpreted()); JSScript *inner = fun->script(); - if (outer->isHeavyweightFunction) { + if (outer->function() && outer->function()->isHeavyweight()) { outer->isOuterFunction = true; inner->isInnerFunction = true; } diff --git a/js/src/jsanalyze.cpp b/js/src/jsanalyze.cpp index 8da77037679..aaca0c99ca4 100644 --- a/js/src/jsanalyze.cpp +++ b/js/src/jsanalyze.cpp @@ -279,7 +279,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx) LifoAlloc &tla = cx->typeLifoAlloc(); unsigned length = script->length; - unsigned nargs = script->hasFunction ? script->function()->nargs : 0; + unsigned nargs = script->function() ? script->function()->nargs : 0; numSlots = TotalSlots(script); @@ -342,15 +342,17 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx) if (cx->compartment->debugMode()) usesReturnValue_ = true; + bool heavyweight = script->function() && script->function()->isHeavyweight(); + isInlineable = true; - if (script->nClosedArgs || script->nClosedVars || script->nfixed >= LOCAL_LIMIT || - (script->hasFunction && script->function()->isHeavyweight()) || + if (script->nClosedArgs || script->nClosedVars || + script->nfixed >= LOCAL_LIMIT || heavyweight || script->usesEval || script->usesArguments || cx->compartment->debugMode()) { isInlineable = false; } modifiesArguments_ = false; - if (script->nClosedArgs || (script->hasFunction && script->function()->isHeavyweight())) + if (script->nClosedArgs || heavyweight) modifiesArguments_ = true; canTrackVars = true; diff --git a/js/src/jsanalyze.h b/js/src/jsanalyze.h index f8ec909ca83..e8ba6d31169 100644 --- a/js/src/jsanalyze.h +++ b/js/src/jsanalyze.h @@ -419,7 +419,7 @@ static inline uint32 ArgSlot(uint32 arg) { return 2 + arg; } static inline uint32 LocalSlot(JSScript *script, uint32 local) { - return 2 + (script->hasFunction ? script->function()->nargs : 0) + local; + return 2 + (script->function() ? script->function()->nargs : 0) + local; } static inline uint32 TotalSlots(JSScript *script) { return LocalSlot(script, 0) + script->nfixed; diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index e3bec2086be..5a26450447a 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -201,6 +201,12 @@ js::GetObjectSlotSpan(const JSObject *obj) return obj->slotSpan(); } +JS_FRIEND_API(bool) +js::IsOriginalScriptFunction(JSFunction *fun) +{ + return fun->script()->function() == fun; +} + /* * The below code is for temporary telemetry use. It can be removed when * sufficient data has been harvested. diff --git a/js/src/jsfriendapi.h b/js/src/jsfriendapi.h index 55e7fb5995c..894ff6d8dc2 100644 --- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -273,6 +273,9 @@ GetObjectParentMaybeScope(const JSObject *obj); JS_FRIEND_API(JSObject *) GetObjectGlobal(JSObject *obj); +JS_FRIEND_API(bool) +IsOriginalScriptFunction(JSFunction *fun); + inline JSObject * GetObjectProto(const JSObject *obj) { diff --git a/js/src/jsfun.cpp b/js/src/jsfun.cpp index e45d06c4be6..6ebbcbc7f52 100644 --- a/js/src/jsfun.cpp +++ b/js/src/jsfun.cpp @@ -1012,7 +1012,7 @@ SetCallArg(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp) JSFunction *fun = callobj.getCalleeFunction(); JSScript *script = fun->script(); - if (!script->ensureHasTypes(cx, fun)) + if (!script->ensureHasTypes(cx)) return false; TypeScript::SetArgument(cx, script, i, *vp); @@ -1086,7 +1086,7 @@ SetCallVar(JSContext *cx, JSObject *obj, jsid id, JSBool strict, Value *vp) JSFunction *fun = callobj.getCalleeFunction(); JSScript *script = fun->script(); - if (!script->ensureHasTypes(cx, fun)) + if (!script->ensureHasTypes(cx)) return false; TypeScript::SetLocal(cx, script, i, *vp); diff --git a/js/src/jsgcmark.cpp b/js/src/jsgcmark.cpp index 49d5039b8d6..d52ed4e6622 100644 --- a/js/src/jsgcmark.cpp +++ b/js/src/jsgcmark.cpp @@ -840,6 +840,9 @@ MarkChildren(JSTracer *trc, JSScript *script) MarkValueRange(trc, constarray->length, constarray->vector, "consts"); } + if (script->function_) + MarkObject(trc, *script->function_, "function"); + if (!script->isCachedEval && script->u.object) MarkObject(trc, *script->u.object, "object"); diff --git a/js/src/jsinfer.cpp b/js/src/jsinfer.cpp index b6b56422b6d..aafeca7fe50 100644 --- a/js/src/jsinfer.cpp +++ b/js/src/jsinfer.cpp @@ -1193,7 +1193,7 @@ TypeConstraintCall::newType(JSContext *cx, TypeSet *source, Type type) return; } - if (!callee->script()->ensureHasTypes(cx, callee)) + if (!callee->script()->ensureHasTypes(cx)) return; unsigned nargs = callee->nargs; @@ -1269,7 +1269,7 @@ TypeConstraintPropagateThis::newType(JSContext *cx, TypeSet *source, Type type) return; } - if (!callee->script()->ensureHasTypes(cx, callee)) + if (!callee->script()->ensureHasTypes(cx)) return; TypeSet *thisTypes = TypeScript::ThisTypes(callee->script()); @@ -1647,7 +1647,7 @@ types::MarkArgumentsCreated(JSContext *cx, JSScript *script) mjit::ExpandInlineFrames(cx->compartment); #endif - if (!script->ensureRanAnalysis(cx)) + if (!script->ensureRanAnalysis(cx, NULL)) return; ScriptAnalysis *analysis = script->analysis(); @@ -2228,7 +2228,7 @@ TypeCompartment::monitorBytecode(JSContext *cx, JSScript *script, uint32 offset, cx->compartment->types.addPendingRecompile(cx, script); /* Trigger recompilation of any inline callers. */ - if (script->hasFunction && !script->function()->hasLazyType()) + if (script->function() && !script->function()->hasLazyType()) ObjectStateChange(cx, script->function()->type(), false, true); } @@ -2323,7 +2323,7 @@ ScriptAnalysis::addTypeBarrier(JSContext *cx, const jsbytecode *pc, TypeSet *tar cx->compartment->types.addPendingRecompile(cx, script); /* Trigger recompilation of any inline callers. */ - if (script->hasFunction && !script->function()->hasLazyType()) + if (script->function() && !script->function()->hasLazyType()) ObjectStateChange(cx, script->function()->type(), false, true); } @@ -2356,7 +2356,7 @@ ScriptAnalysis::addSingletonTypeBarrier(JSContext *cx, const jsbytecode *pc, Typ if (!code.typeBarriers) { /* Trigger recompilation as for normal type barriers. */ cx->compartment->types.addPendingRecompile(cx, script); - if (script->hasFunction && !script->function()->hasLazyType()) + if (script->function() && !script->function()->hasLazyType()) ObjectStateChange(cx, script->function()->type(), false, true); } @@ -3213,7 +3213,7 @@ ScriptAnalysis::resolveNameAccess(JSContext *cx, jsid id, bool addDependency) JSAtom *atom = JSID_TO_ATOM(id); JSScript *script = this->script; - while (script->hasFunction && script->nesting()) { + while (script->function() && script->nesting()) { if (!script->ensureRanInference(cx)) return access; @@ -3458,7 +3458,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, case JSOP_STOP: /* If a stop is reachable then the return type may be void. */ - if (script->hasFunction) + if (script->function()) TypeScript::ReturnTypes(script)->addType(cx, Type::UndefinedType()); break; @@ -3741,7 +3741,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, case JSOP_RETURN: case JSOP_SETRVAL: - if (script->hasFunction) + if (script->function()) poppedTypes(pc, 0)->addSubset(cx, TypeScript::ReturnTypes(script)); break; @@ -3995,7 +3995,7 @@ ScriptAnalysis::analyzeTypesBytecode(JSContext *cx, unsigned offset, break; case JSOP_GENERATOR: - if (script->hasFunction) { + if (script->function()) { if (script->hasGlobal()) { JSObject *proto = script->global()->getOrCreateGeneratorPrototype(cx); if (!proto) @@ -4112,7 +4112,7 @@ ScriptAnalysis::analyzeTypes(JSContext *cx) for (unsigned i = 0; i < script->nfixed; i++) TypeScript::LocalTypes(script, i)->addType(cx, Type::UndefinedType()); - TypeScriptNesting *nesting = script->hasFunction ? script->nesting() : NULL; + TypeScriptNesting *nesting = script->function() ? script->nesting() : NULL; if (nesting && nesting->parent) { /* * Check whether NAME accesses can be resolved in parent scopes, and @@ -4799,7 +4799,7 @@ ScriptAnalysis::printTypes(JSContext *cx) #ifdef DEBUG - if (script->hasFunction) + if (script->function()) printf("Function"); else if (script->isCachedEval) printf("Eval"); @@ -4813,7 +4813,7 @@ ScriptAnalysis::printTypes(JSContext *cx) printf("\n this:"); TypeScript::ThisTypes(script)->print(cx); - for (unsigned i = 0; script->hasFunction && i < script->function()->nargs; i++) { + for (unsigned i = 0; script->function() && i < script->function()->nargs; i++) { printf("\n arg%u:", i); TypeScript::ArgTypes(script, i)->print(cx); } @@ -4938,7 +4938,7 @@ MarkIteratorUnknownSlow(JSContext *cx) } /* Trigger recompilation of any inline callers. */ - if (script->hasFunction && !script->function()->hasLazyType()) + if (script->function() && !script->function()->hasLazyType()) ObjectStateChange(cx, script->function()->type(), false, true); } @@ -4983,7 +4983,7 @@ TypeDynamicResult(JSContext *cx, JSScript *script, jsbytecode *pc, Type type) /* Directly update associated type sets for applicable bytecodes. */ if (js_CodeSpec[*pc].format & JOF_TYPESET) { - if (!script->ensureRanAnalysis(cx)) { + if (!script->ensureRanAnalysis(cx, NULL)) { cx->compartment->types.setPendingNukeTypes(cx); return; } @@ -5076,7 +5076,7 @@ TypeDynamicResult(JSContext *cx, JSScript *script, jsbytecode *pc, Type type) } /* Trigger recompilation of any inline callers. */ - if (script->hasFunction && !script->function()->hasLazyType()) + if (script->function() && !script->function()->hasLazyType()) ObjectStateChange(cx, script->function()->type(), false, true); } @@ -5091,7 +5091,7 @@ TypeMonitorResult(JSContext *cx, JSScript *script, jsbytecode *pc, const js::Val AutoEnterTypeInference enter(cx); - if (!script->ensureRanAnalysis(cx)) { + if (!script->ensureRanAnalysis(cx, NULL)) { cx->compartment->types.setPendingNukeTypes(cx); return; } @@ -5111,9 +5111,8 @@ TypeScript::SetScope(JSContext *cx, JSScript *script, JSObject *scope) { JS_ASSERT(script->types && !script->types->hasScope()); - JSFunction *fun = script->types->function; + JSFunction *fun = script->function(); - JS_ASSERT(script->hasFunction == (fun != NULL)); JS_ASSERT_IF(!fun, !script->isOuterFunction && !script->isInnerFunction); JS_ASSERT_IF(!scope, fun && !script->isInnerFunction); @@ -5191,7 +5190,7 @@ TypeScript::SetScope(JSContext *cx, JSScript *script, JSObject *scope) * the parent's call object as the most recent one, so that it is not * marked as reentrant. */ - if (!parent->ensureHasTypes(cx, parentFun)) + if (!parent->ensureHasTypes(cx)) return false; if (!parent->types->hasScope()) { if (!SetScope(cx, parent, scope->scopeChain())) @@ -5432,23 +5431,21 @@ IgnorePushed(const jsbytecode *pc, unsigned index) } bool -JSScript::makeTypes(JSContext *cx, JSFunction *fun) +JSScript::makeTypes(JSContext *cx) { JS_ASSERT(!types); - JS_ASSERT(hasFunction == (fun != NULL)); if (!cx->typeInferenceEnabled()) { types = (TypeScript *) cx->calloc_(sizeof(TypeScript)); if (!types) return false; - new(types) TypeScript(fun); + new(types) TypeScript(); return true; } AutoEnterTypeInference enter(cx); - /* Open code for NumTypeSets since the types are not filled in yet. */ - unsigned count = 2 + (fun ? fun->nargs : 0) + nfixed + nTypeSets; + unsigned count = TypeScript::NumTypeSets(this); types = (TypeScript *) cx->calloc_(sizeof(TypeScript) + (sizeof(TypeSet) * count)); if (!types) { @@ -5456,7 +5453,7 @@ JSScript::makeTypes(JSContext *cx, JSFunction *fun) return false; } - new(types) TypeScript(fun); + new(types) TypeScript(); #ifdef DEBUG TypeSet *typeArray = types->typeArray(); @@ -5472,7 +5469,7 @@ JSScript::makeTypes(JSContext *cx, JSFunction *fun) InferSpew(ISpewOps, "typeSet: %sT%p%s this #%u", InferSpewColor(thisTypes), thisTypes, InferSpewColorReset(), id()); - unsigned nargs = hasFunction ? function()->nargs : 0; + unsigned nargs = function() ? function()->nargs : 0; for (unsigned i = 0; i < nargs; i++) { TypeSet *types = TypeScript::ArgTypes(this, i); InferSpew(ISpewOps, "typeSet: %sT%p%s arg%u #%u", @@ -5515,9 +5512,7 @@ JSScript::makeAnalysis(JSContext *cx) bool JSScript::typeSetFunction(JSContext *cx, JSFunction *fun, bool singleton) { - hasFunction = true; - if (fun->isHeavyweight()) - isHeavyweightFunction = true; + function_ = fun; if (!cx->typeInferenceEnabled()) return true; diff --git a/js/src/jsinfer.h b/js/src/jsinfer.h index fc4fb3c2b59..58deaa90df9 100644 --- a/js/src/jsinfer.h +++ b/js/src/jsinfer.h @@ -1011,9 +1011,6 @@ class TypeScript /* Analysis information for the script, cleared on each GC. */ analyze::ScriptAnalysis *analysis; - /* Function for the script, if it has one. */ - JSFunction *function; - /* * Information about the scope in which a script executes. This information * is not set until the script has executed at least once and SetScope @@ -1032,8 +1029,7 @@ class TypeScript /* Dynamic types generated at points within this script. */ TypeResult *dynamicList; - TypeScript(JSFunction *fun) { - this->function = fun; + TypeScript() { this->global = (js::GlobalObject *) GLOBAL_MISSING_SCOPE; } @@ -1098,9 +1094,6 @@ class TypeScript static void Sweep(JSContext *cx, JSScript *script); inline void trace(JSTracer *trc); void destroy(); - - /* For JIT access. */ - static inline size_t offsetOfFunction() { return offsetof(TypeScript, function); } }; struct ArrayTableKey; diff --git a/js/src/jsinferinlines.h b/js/src/jsinferinlines.h index 01042b04854..c8fcf2fd523 100644 --- a/js/src/jsinferinlines.h +++ b/js/src/jsinferinlines.h @@ -324,7 +324,7 @@ TypeMonitorCall(JSContext *cx, const js::CallArgs &args, bool constructing) JSFunction *fun = callee->toFunction(); if (fun->isInterpreted()) { JSScript *script = fun->script(); - if (!script->ensureRanAnalysis(cx, fun, fun->callScope())) + if (!script->ensureRanAnalysis(cx, fun->callScope())) return; if (cx->typeInferenceEnabled()) TypeMonitorCallSlow(cx, callee, args, constructing); @@ -688,8 +688,6 @@ TypeScript::SetArgument(JSContext *cx, JSScript *script, unsigned arg, const js: void TypeScript::trace(JSTracer *trc) { - if (function) - gc::MarkObject(trc, *function, "script_fun"); if (hasScope() && global) gc::MarkObject(trc, *global, "script_global"); @@ -1255,15 +1253,15 @@ TypeObject::getGlobal() } } /* namespace js::types */ inline bool -JSScript::ensureHasTypes(JSContext *cx, JSFunction *fun) +JSScript::ensureHasTypes(JSContext *cx) { - return types || makeTypes(cx, fun); + return types || makeTypes(cx); } inline bool -JSScript::ensureRanAnalysis(JSContext *cx, JSFunction *fun, JSObject *scope) +JSScript::ensureRanAnalysis(JSContext *cx, JSObject *scope) { - if (!ensureHasTypes(cx, fun)) + if (!ensureHasTypes(cx)) return false; if (!types->hasScope() && !js::types::TypeScript::SetScope(cx, this, scope)) return false; @@ -1276,7 +1274,7 @@ JSScript::ensureRanAnalysis(JSContext *cx, JSFunction *fun, JSObject *scope) inline bool JSScript::ensureRanInference(JSContext *cx) { - if (!ensureRanAnalysis(cx)) + if (!ensureRanAnalysis(cx, NULL)) return false; if (!analysis()->ranInference()) { js::types::AutoEnterTypeInference enter(cx); diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index 4e50f0b4d96..c3e5143aadf 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -773,7 +773,7 @@ js::ExecuteKernel(JSContext *cx, JSScript *script, JSObject &scopeChain, const V Probes::startExecution(cx, script); - if (!script->ensureRanAnalysis(cx, NULL, &scopeChain)) + if (!script->ensureRanAnalysis(cx, &scopeChain)) return false; TypeScript::SetThis(cx, script, fp->thisValue()); diff --git a/js/src/jsscript.h b/js/src/jsscript.h index d90c98a5a0b..26bfa8bfdf1 100644 --- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -469,11 +469,9 @@ struct JSScript : public js::gc::Cell { undefined properties in this script */ bool hasSingletons:1; /* script has singleton objects */ - bool hasFunction:1; /* script has an associated function */ - bool isHeavyweightFunction:1; /* function is heavyweight */ - bool isOuterFunction:1; /* function is heavyweight, with inner functions */ - bool isInnerFunction:1; /* function is directly nested in a heavyweight - * outer function */ + bool isOuterFunction:1; /* function is heavyweight, with inner functions */ + bool isInnerFunction:1; /* function is directly nested in a heavyweight + * outer function */ bool isActiveEval:1; /* script came from eval(), and is still active */ bool isCachedEval:1; /* script came from eval(), and is in eval cache */ bool usedLazyArgs:1; /* script has used lazy arguments at some point */ @@ -499,10 +497,8 @@ struct JSScript : public js::gc::Cell { * the script with 4 bytes. We use them to store tiny scripts like empty * scripts. */ -#if JS_BITS_PER_WORD == 64 #define JS_SCRIPT_INLINE_DATA_LIMIT 4 uint8 inlineData[JS_SCRIPT_INLINE_DATA_LIMIT]; -#endif const char *filename; /* source filename or null */ JSAtom **atoms; /* maps immediate index to literal struct */ @@ -538,6 +534,11 @@ struct JSScript : public js::gc::Cell { /* array of execution counters for every JSOp in the script, by runmode */ JSPCCounters pcCounters; + /* Function for the script, if it has one. */ + JSFunction *function_; + + JSFunction *function() const { return function_; } + #ifdef JS_CRASH_DIAGNOSTICS JSObject *ownerObject; @@ -563,15 +564,15 @@ struct JSScript : public js::gc::Cell { js::types::TypeScript *types; /* Ensure the script has a TypeScript. */ - inline bool ensureHasTypes(JSContext *cx, JSFunction *fun = NULL); + inline bool ensureHasTypes(JSContext *cx); /* * Ensure the script has scope and bytecode analysis information. * Performed when the script first runs, or first runs after a TypeScript - * GC purge. If fun/scope are NULL then the script must already have types - * with scope information. + * GC purge. If scope is NULL then the script must already have types with + * scope information. */ - inline bool ensureRanAnalysis(JSContext *cx, JSFunction *fun = NULL, JSObject *scope = NULL); + inline bool ensureRanAnalysis(JSContext *cx, JSObject *scope); /* Ensure the script has type inference analysis information. */ inline bool ensureRanInference(JSContext *cx); @@ -589,14 +590,13 @@ struct JSScript : public js::gc::Cell { inline bool hasGlobal() const; inline bool hasClearedGlobal() const; - inline JSFunction *function() const; inline js::GlobalObject *global() const; inline js::types::TypeScriptNesting *nesting() const; inline void clearNesting(); private: - bool makeTypes(JSContext *cx, JSFunction *fun); + bool makeTypes(JSContext *cx); bool makeAnalysis(JSContext *cx); public: diff --git a/js/src/jsscriptinlines.h b/js/src/jsscriptinlines.h index ed8b44d8fc0..6c127c30b27 100644 --- a/js/src/jsscriptinlines.h +++ b/js/src/jsscriptinlines.h @@ -190,17 +190,10 @@ JSScript::hasClearedGlobal() const return obj && obj->isCleared(); } -inline JSFunction * -JSScript::function() const -{ - JS_ASSERT(hasFunction && types); - return types->function; -} - inline js::types::TypeScriptNesting * JSScript::nesting() const { - JS_ASSERT(hasFunction && types && types->hasScope()); + JS_ASSERT(function() && types && types->hasScope()); return types->nesting; } diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index d3a34763c85..487ecaa6cb3 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -177,7 +177,7 @@ mjit::Compiler::compile() : (*jit)->invokeEntry; } else if (status != Compile_Retry) { *checkAddr = JS_UNJITTABLE_SCRIPT; - if (outerScript->hasFunction) { + if (outerScript->function()) { outerScript->uninlineable = true; types::MarkTypeObjectFlags(cx, outerScript->function(), types::OBJECT_FLAG_UNINLINEABLE); @@ -195,7 +195,7 @@ mjit::Compiler::checkAnalysis(JSScript *script) return Compile_Abort; } - if (!script->ensureRanAnalysis(cx)) + if (!script->ensureRanAnalysis(cx, NULL)) return Compile_Error; if (cx->typeInferenceEnabled() && !script->ensureRanInference(cx)) return Compile_Error; @@ -244,8 +244,8 @@ mjit::Compiler::scanInlineCalls(uint32 index, uint32 depth) /* Don't inline from functions which could have a non-global scope object. */ if (!script->hasGlobal() || script->global() != globalObj || - (script->hasFunction && script->function()->getParent() != globalObj) || - (script->hasFunction && script->function()->isHeavyweight()) || + (script->function() && script->function()->getParent() != globalObj) || + (script->function() && script->function()->isHeavyweight()) || script->isActiveEval) { return Compile_Okay; } @@ -443,7 +443,7 @@ mjit::Compiler::pushActiveFrame(JSScript *script, uint32 argc) #ifdef JS_METHODJIT_SPEW if (cx->typeInferenceEnabled() && IsJaegerSpewChannelActive(JSpew_Regalloc)) { - unsigned nargs = script->hasFunction ? script->function()->nargs : 0; + unsigned nargs = script->function() ? script->function()->nargs : 0; for (unsigned i = 0; i < nargs; i++) { uint32 slot = ArgSlot(i); if (!newAnalysis->slotEscapes(slot)) { @@ -679,7 +679,7 @@ mjit::Compiler::generatePrologue() * If there is no function, then this can only be called via JaegerShot(), * which expects an existing frame to be initialized like the interpreter. */ - if (script->hasFunction) { + if (script->function()) { Jump j = masm.jump(); /* @@ -848,7 +848,7 @@ mjit::Compiler::generatePrologue() if (cx->typeInferenceEnabled()) { #ifdef DEBUG - if (script->hasFunction) { + if (script->function()) { prepareStubCall(Uses(0)); INLINE_STUBCALL(stubs::AssertArgumentTypes, REJOIN_NONE); } @@ -885,7 +885,7 @@ void mjit::Compiler::ensureDoubleArguments() { /* Convert integer arguments which were inferred as (int|double) to doubles. */ - for (uint32 i = 0; script->hasFunction && i < script->function()->nargs; i++) { + for (uint32 i = 0; script->function() && i < script->function()->nargs; i++) { uint32 slot = ArgSlot(i); if (a->varTypes[slot].type == JSVAL_TYPE_DOUBLE && analysis->trackSlot(slot)) frame.ensureDouble(frame.getArg(i)); @@ -1001,7 +1001,7 @@ mjit::Compiler::finishThisUp(JITScript **jitp) jit->code = JSC::MacroAssemblerCodeRef(result, execPool, masm.size() + stubcc.size()); jit->invokeEntry = result; jit->singleStepMode = script->stepModeEnabled(); - if (script->hasFunction) { + if (script->function()) { jit->arityCheckEntry = stubCode.locationOf(arityLabel).executableAddress(); jit->argsCheckEntry = stubCode.locationOf(argsCheckLabel).executableAddress(); jit->fastEntry = fullCode.locationOf(invokeLabel).executableAddress(); @@ -1112,7 +1112,7 @@ mjit::Compiler::finishThisUp(JITScript **jitp) #if defined JS_MONOIC JS_INIT_CLIST(&jit->callers); - if (script->hasFunction && cx->typeInferenceEnabled()) { + if (script->function() && cx->typeInferenceEnabled()) { jit->argsCheckStub = stubCode.locationOf(argsCheckStub); jit->argsCheckFallthrough = stubCode.locationOf(argsCheckFallthrough); jit->argsCheckJump = stubCode.locationOf(argsCheckJump); @@ -1436,7 +1436,7 @@ mjit::Compiler::finishThisUp(JITScript **jitp) JSC::ExecutableAllocator::makeExecutable(result, masm.size() + stubcc.size()); JSC::ExecutableAllocator::cacheFlush(result, masm.size() + stubcc.size()); - Probes::registerMJITCode(cx, jit, script, script->hasFunction ? script->function() : NULL, + Probes::registerMJITCode(cx, jit, script, script->function() ? script->function() : NULL, (mjit::Compiler_ActiveFrame**) inlineFrames.begin(), result, masm.size(), result + masm.size(), stubcc.size()); @@ -3137,7 +3137,7 @@ mjit::Compiler::emitInlineReturnValue(FrameEntry *fe) void mjit::Compiler::emitReturn(FrameEntry *fe) { - JS_ASSERT_IF(!script->hasFunction, JSOp(*PC) == JSOP_STOP); + JS_ASSERT_IF(!script->function(), JSOp(*PC) == JSOP_STOP); /* Only the top of the stack can be returned. */ JS_ASSERT_IF(fe, fe == frame.peek(-1)); @@ -3193,7 +3193,7 @@ mjit::Compiler::emitReturn(FrameEntry *fe) * even on the entry frame. To avoid double-putting, EnterMethodJIT clears * out the entry frame's activation objects. */ - if (script->hasFunction) { + if (script->function()) { types::TypeScriptNesting *nesting = script->nesting(); if (script->function()->isHeavyweight() || (nesting && nesting->children)) { prepareStubCall(Uses(fe ? 1 : 0)); @@ -5650,7 +5650,7 @@ mjit::Compiler::jsop_this() * In direct-call eval code, we wrapped 'this' before entering the eval. * In global code, 'this' is always an object. */ - if (script->hasFunction && !script->strictModeCode) { + if (script->function() && !script->strictModeCode) { FrameEntry *thisFe = frame.peek(-1); /* diff --git a/js/src/methodjit/FrameState-inl.h b/js/src/methodjit/FrameState-inl.h index 228376b79b7..44989d951f2 100644 --- a/js/src/methodjit/FrameState-inl.h +++ b/js/src/methodjit/FrameState-inl.h @@ -1036,7 +1036,7 @@ FrameState::frameOffset(const FrameEntry *fe, ActiveFrame *a) const if (fe >= a->args) return StackFrame::offsetOfFormalArg(a->script->function(), uint32(fe - a->args)); if (fe == a->this_) - return StackFrame::offsetOfThis(a->script->hasFunction ? a->script->function() : NULL); + return StackFrame::offsetOfThis(a->script->function()); if (fe == a->callee_) return StackFrame::offsetOfCallee(a->script->function()); JS_NOT_REACHED("Bad fe"); @@ -1219,7 +1219,7 @@ inline FrameEntry * FrameState::getCallee() { // Callee can only be used in function code, and it's always an object. - JS_ASSERT(a->script->hasFunction); + JS_ASSERT(a->script->function()); FrameEntry *fe = a->callee_; if (!fe->isTracked()) { addToTracker(fe); diff --git a/js/src/methodjit/FrameState.h b/js/src/methodjit/FrameState.h index 10c97ae5227..fa84ed72fe5 100644 --- a/js/src/methodjit/FrameState.h +++ b/js/src/methodjit/FrameState.h @@ -1046,7 +1046,7 @@ class FrameState inline bool isConstructorThis(const FrameEntry *fe) const; bool isArg(const FrameEntry *fe) const { - return a->script->hasFunction && fe >= a->args && fe - a->args < a->script->function()->nargs; + return a->script->function() && fe >= a->args && fe - a->args < a->script->function()->nargs; } bool isLocal(const FrameEntry *fe) const { diff --git a/js/src/methodjit/InvokeHelpers.cpp b/js/src/methodjit/InvokeHelpers.cpp index 1d16bb106a9..67a69acc4da 100644 --- a/js/src/methodjit/InvokeHelpers.cpp +++ b/js/src/methodjit/InvokeHelpers.cpp @@ -621,7 +621,7 @@ js_InternalThrow(VMFrame &f) */ cx->compartment->jaegerCompartment()->setLastUnfinished(Jaeger_Unfinished); - if (!script->ensureRanAnalysis(cx)) { + if (!script->ensureRanAnalysis(cx, NULL)) { js_ReportOutOfMemory(cx); return NULL; } @@ -1230,7 +1230,7 @@ js_InternalInterpret(void *returnData, void *returnType, void *returnReg, js::VM JSOp op = JSOp(*pc); const JSCodeSpec *cs = &js_CodeSpec[op]; - if (!script->ensureRanAnalysis(cx)) { + if (!script->ensureRanAnalysis(cx, NULL)) { js_ReportOutOfMemory(cx); return js_InternalThrow(f); } diff --git a/js/src/methodjit/LoopState.cpp b/js/src/methodjit/LoopState.cpp index 33cc997976e..8646b2cb21e 100644 --- a/js/src/methodjit/LoopState.cpp +++ b/js/src/methodjit/LoopState.cpp @@ -168,7 +168,7 @@ LoopState::init(jsbytecode *head, Jump entry, jsbytecode *entryTarget) * Don't hoist bounds checks or loop invariant code in scripts that have * had indirect modification of their arguments. */ - if (outerScript->hasFunction) { + if (outerScript->function()) { if (TypeSet::HasObjectFlags(cx, outerScript->function()->getType(cx), OBJECT_FLAG_UNINLINEABLE)) this->skipAnalysis = true; } diff --git a/js/src/methodjit/PolyIC.cpp b/js/src/methodjit/PolyIC.cpp index 66281baad29..5762f25a927 100644 --- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -624,7 +624,7 @@ class SetPropCompiler : public PICStubCompiler JSFunction *fun = obj->asCall().getCalleeFunction(); JSScript *script = fun->script(); uint16 slot = uint16(shape->shortid()); - if (!script->ensureHasTypes(cx, fun)) + if (!script->ensureHasTypes(cx)) return error(); { types::AutoEnterTypeInference enter(cx); diff --git a/js/src/vm/GlobalObject.cpp b/js/src/vm/GlobalObject.cpp index f027e71a7c5..830b3ceb61e 100644 --- a/js/src/vm/GlobalObject.cpp +++ b/js/src/vm/GlobalObject.cpp @@ -142,7 +142,7 @@ GlobalObject::initFunctionAndObjectClasses(JSContext *cx) script->code[1] = SRC_NULL; functionProto->setScript(script); functionProto->getType(cx)->interpretedFunction = functionProto; - script->hasFunction = true; + script->function_ = functionProto; if (!proto->setSingletonType(cx)) return NULL;