[INFER] Allow analysis/compilation of top level <script>, bug 662704.

This commit is contained in:
Brian Hackett 2011-08-18 08:54:36 -07:00
parent ba9d7b079c
commit b6b88f59e7
8 changed files with 14 additions and 36 deletions

View File

@ -4965,23 +4965,22 @@ EvaluateUCScriptForPrincipalsCommon(JSContext *cx, JSObject *obj,
{
JS_THREADSAFE_ASSERT(cx->compartment != cx->runtime->atomsCompartment);
uint32 flags = TCF_COMPILE_N_GO | TCF_NEED_SCRIPT_OBJECT;
if (!rval)
flags |= TCF_NO_SCRIPT_RVAL;
CHECK_REQUEST(cx);
JSScript *script = Compiler::compileScript(cx, obj, NULL, principals,
!rval
? TCF_COMPILE_N_GO | TCF_NO_SCRIPT_RVAL
: TCF_COMPILE_N_GO,
JSScript *script = Compiler::compileScript(cx, obj, NULL, principals, flags,
chars, length, filename, lineno, compileVersion);
if (!script) {
LAST_FRAME_CHECKS(cx, script);
return false;
}
script->isUncachedEval = true;
JS_ASSERT(script->getVersion() == compileVersion);
bool ok = ExternalExecute(cx, script, *obj, Valueify(rval));
LAST_FRAME_CHECKS(cx, ok);
js_DestroyScript(cx, script, 5);
return ok;
}

View File

@ -3042,7 +3042,7 @@ EmitNameIncDec(JSContext *cx, JSParseNode *pn, JSOp op, JSCodeGenerator *cg)
return false;
}
if (!EmitAtomOp(cx, pn, JSOP_SETPROP, cg)) // N? N+1
if (!EmitAtomOp(cx, pn, global ? JSOP_SETGNAME : JSOP_SETNAME, cg)) // N? N+1
return false;
if (post && js_Emit1(cx, cg, JSOP_POP) < 0) // RESULT
return false;

View File

@ -1853,14 +1853,11 @@ TypeCompartment::newAllocationSiteTypeObject(JSContext *cx, const AllocationSite
jsbytecode *pc = key.script->code + key.offset;
UntrapOpcode untrap(cx, key.script, pc);
if (JSOp(*pc) == JSOP_NEWOBJECT && !key.uncached) {
if (JSOp(*pc) == JSOP_NEWOBJECT) {
/*
* This object is always constructed the same way and will not be
* observed by other code before all properties have been added. Mark
* all the properties as definite properties of the object.
* :XXX: skipping for objects from uncached eval scripts, as entries
* in the allocation site table may be stale and we could potentially
* get a spurious hit. Fix this hack.
*/
JSObject *baseobj = key.script->getObject(GET_SLOTNO(pc));
@ -3842,14 +3839,6 @@ ScriptAnalysis::analyzeTypes(JSContext *cx)
{
JS_ASSERT(!ranInference());
/*
* Types in uncached eval scripts cannot be analyzed. These are manually
* destroyed, rather than destroyed on GC, and we cannot ensure that type
* constraints do not refer to the script after it has been destroyed.are
* referring to
*/
JS_ASSERT(!script->isUncachedEval);
if (OOM()) {
cx->compartment->types.setPendingNukeTypes(cx);
return;
@ -4482,7 +4471,7 @@ ScriptAnalysis::printTypes(JSContext *cx)
if (script->hasFunction)
printf("Function");
else if (script->isCachedEval || script->isUncachedEval)
else if (script->isCachedEval)
printf("Eval");
else
printf("Main");
@ -5470,7 +5459,7 @@ TypeCompartment::sweep(JSContext *cx)
const AllocationSiteKey &key = e.front().key;
TypeObject *object = e.front().value;
if (key.uncached || key.script->isAboutToBeFinalized(cx) || !object->isMarked())
if (key.script->isAboutToBeFinalized(cx) || !object->isMarked())
e.removeFront();
}
}

View File

@ -508,9 +508,8 @@ TypeScript::StandardType(JSContext *cx, JSScript *script, JSProtoKey key)
struct AllocationSiteKey {
JSScript *script;
uint32 offset : 23;
uint32 offset : 24;
JSProtoKey kind : 8;
bool uncached : 1;
static const uint32 OFFSET_LIMIT = (1 << 23);
@ -539,7 +538,6 @@ TypeScript::InitObject(JSContext *cx, JSScript *script, const jsbytecode *pc, JS
AllocationSiteKey key;
key.script = script;
key.offset = offset;
key.uncached = script->isUncachedEval;
key.kind = kind;
if (!cx->compartment->types.allocationSiteTable)
@ -607,7 +605,7 @@ TypeScript::SetThis(JSContext *cx, JSScript *script, Type type)
return;
/* Analyze the script regardless if -a was used. */
bool analyze = cx->hasRunOption(JSOPTION_METHODJIT_ALWAYS) && !script->isUncachedEval;
bool analyze = cx->hasRunOption(JSOPTION_METHODJIT_ALWAYS);
if (!ThisTypes(script)->hasType(type) || analyze) {
AutoEnterTypeInference enter(cx);

View File

@ -1508,7 +1508,7 @@ js_TraceScript(JSTracer *trc, JSScript *script, JSObject *owner)
* separately if, e.g. we are GC'ing while type inference code is active,
* and we need to make sure both the script and the object survive the GC.
*/
if (!script->isCachedEval && !script->isUncachedEval && script->u.object)
if (!script->isCachedEval && script->u.object)
MarkObject(trc, *script->u.object, "object");
if (script->hasFunction)
MarkObject(trc, *script->function(), "script_fun");

View File

@ -508,7 +508,6 @@ struct JSScript {
bool hasFunction:1; /* function is active in 'where' union */
bool isActiveEval:1; /* script came from eval(), and is still active */
bool isCachedEval:1; /* script came from eval(), and is in eval cache */
bool isUncachedEval:1; /* script came from EvaluateScript */
bool usedLazyArgs:1; /* script has used lazy arguments at some point */
bool createdArgs:1; /* script has had arguments objects created */
bool uninlineable:1; /* script is considered uninlineable by analysis */

View File

@ -135,8 +135,6 @@ mjit::Compiler::Compiler(JSContext *cx, JSScript *outerScript, bool isConstructi
applyTricks(NoApplyTricks),
pcLengths(NULL)
{
JS_ASSERT(!outerScript->isUncachedEval);
/* :FIXME: bug 637856 disabling traceJit if inference is enabled */
if (cx->typeInferenceEnabled())
addTraceHints = false;
@ -611,10 +609,6 @@ mjit::TryCompile(JSContext *cx, StackFrame *fp)
if (!ok)
return Compile_Abort;
// Uncached eval scripts are not analyzed or compiled.
if (fp->script()->isUncachedEval)
return Compile_Abort;
// Ensure that constructors have at least one slot.
if (fp->isConstructing() && !fp->script()->nslots)
fp->script()->nslots++;

View File

@ -2666,16 +2666,15 @@ EvaluateInScope(JSContext *cx, JSObject *scobj, StackFrame *fp, const jschar *ch
* variable references made by this frame.
*/
JSScript *script = Compiler::compileScript(cx, scobj, fp, fp->scopeChain().principals(cx),
TCF_COMPILE_N_GO, chars, length,
TCF_COMPILE_N_GO | TCF_NEED_SCRIPT_OBJECT,
chars, length,
filename, lineno, cx->findVersion(),
NULL, UpvarCookie::UPVAR_LEVEL_LIMIT);
if (!script)
return false;
script->isUncachedEval = true;
bool ok = Execute(cx, script, *scobj, fp->thisValue(), EXECUTE_DEBUG, fp, rval);
js_DestroyScript(cx, script, 6);
return ok;
}