зеркало из https://github.com/mozilla/pjs.git
Add JSScript::function, bug 693754.
This commit is contained in:
Родитель
80f26887d5
Коммит
f295c62542
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче