Don't compile any part of scripts containing uncompileable opcodes, bug 728342. r=dvander

This commit is contained in:
Brian Hackett 2012-02-22 10:57:00 -08:00
Родитель 8440bcee3d
Коммит f9fe86433d
4 изменённых файлов: 116 добавлений и 14 удалений

Просмотреть файл

@ -197,6 +197,8 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
bool heavyweight = script->function() && script->function()->isHeavyweight();
isCompileable = true;
isInlineable = true;
if (script->nClosedArgs || script->nClosedVars || heavyweight ||
script->usesEval || script->usesArguments || cx->compartment->debugMode()) {
@ -330,13 +332,14 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
isInlineable = false;
break;
case JSOP_QNAMEPART:
case JSOP_QNAMECONST:
isCompileable = false;
case JSOP_NAME:
case JSOP_CALLNAME:
case JSOP_BINDNAME:
case JSOP_SETNAME:
case JSOP_DELNAME:
case JSOP_QNAMEPART:
case JSOP_QNAMECONST:
checkAliasedName(cx, pc);
usesScopeChain_ = true;
isInlineable = false;
@ -358,7 +361,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
case JSOP_ENTERWITH:
addsScopeObjects_ = true;
isInlineable = canTrackVars = false;
isCompileable = isInlineable = canTrackVars = false;
break;
case JSOP_ENTERLET0:
@ -483,7 +486,8 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
case JSOP_DECLOCAL:
case JSOP_LOCALINC:
case JSOP_LOCALDEC:
case JSOP_SETLOCAL: {
case JSOP_SETLOCAL:
case JSOP_SETLOCALPOP: {
uint32_t local = GET_SLOTNO(pc);
if (local >= script->nfixed) {
localsAliasStack_ = true;
@ -517,7 +521,104 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
isInlineable = false;
break;
/* Additional opcodes which can be both compiled both normally and inline. */
case JSOP_NOP:
case JSOP_UNDEFINED:
case JSOP_GOTO:
case JSOP_DEFAULT:
case JSOP_IFEQ:
case JSOP_IFNE:
case JSOP_ITERNEXT:
case JSOP_DUP:
case JSOP_DUP2:
case JSOP_SWAP:
case JSOP_PICK:
case JSOP_BITOR:
case JSOP_BITXOR:
case JSOP_BITAND:
case JSOP_LT:
case JSOP_LE:
case JSOP_GT:
case JSOP_GE:
case JSOP_EQ:
case JSOP_NE:
case JSOP_LSH:
case JSOP_RSH:
case JSOP_URSH:
case JSOP_ADD:
case JSOP_SUB:
case JSOP_MUL:
case JSOP_DIV:
case JSOP_MOD:
case JSOP_NOT:
case JSOP_BITNOT:
case JSOP_NEG:
case JSOP_POS:
case JSOP_DELPROP:
case JSOP_DELELEM:
case JSOP_TYPEOF:
case JSOP_TYPEOFEXPR:
case JSOP_VOID:
case JSOP_GETPROP:
case JSOP_CALLPROP:
case JSOP_LENGTH:
case JSOP_GETELEM:
case JSOP_CALLELEM:
case JSOP_TOID:
case JSOP_SETELEM:
case JSOP_IMPLICITTHIS:
case JSOP_DOUBLE:
case JSOP_STRING:
case JSOP_ZERO:
case JSOP_ONE:
case JSOP_NULL:
case JSOP_FALSE:
case JSOP_TRUE:
case JSOP_OR:
case JSOP_AND:
case JSOP_CASE:
case JSOP_STRICTEQ:
case JSOP_STRICTNE:
case JSOP_ITER:
case JSOP_MOREITER:
case JSOP_ENDITER:
case JSOP_POP:
case JSOP_GETARG:
case JSOP_CALLARG:
case JSOP_BINDGNAME:
case JSOP_UINT16:
case JSOP_NEWINIT:
case JSOP_NEWARRAY:
case JSOP_NEWOBJECT:
case JSOP_ENDINIT:
case JSOP_INITMETHOD:
case JSOP_INITPROP:
case JSOP_INITELEM:
case JSOP_SETPROP:
case JSOP_SETMETHOD:
case JSOP_IN:
case JSOP_INSTANCEOF:
case JSOP_LINENO:
case JSOP_ENUMELEM:
case JSOP_CONDSWITCH:
case JSOP_LABEL:
case JSOP_RETRVAL:
case JSOP_GETGNAME:
case JSOP_CALLGNAME:
case JSOP_SETGNAME:
case JSOP_REGEXP:
case JSOP_OBJECT:
case JSOP_UINT24:
case JSOP_GETXPROP:
case JSOP_INT8:
case JSOP_INT32:
case JSOP_HOLE:
case JSOP_LOOPHEAD:
case JSOP_LOOPENTRY:
break;
default:
isCompileable = isInlineable = false;
break;
}

Просмотреть файл

@ -871,6 +871,7 @@ class ScriptAnalysis
bool addsScopeObjects_:1;
bool localsAliasStack_:1;
bool isInlineable:1;
bool isCompileable:1;
bool canTrackVars:1;
uint32_t numReturnSites_;
@ -905,6 +906,7 @@ class ScriptAnalysis
bool OOM() { return outOfMemory; }
bool failed() { return hadFailure; }
bool inlineable(uint32_t argc) { return isInlineable && argc == script->function()->nargs; }
bool compileable() { return isCompileable; }
/* Whether there are POPV/SETRVAL bytecodes which can write to the frame's rval. */
bool usesReturnValue() const { return usesReturnValue_; }

Просмотреть файл

@ -3324,6 +3324,9 @@ ScriptAnalysis::resolveNameAccess(JSContext *cx, jsid id, bool addDependency)
return access;
}
if (!script->isOuterFunction)
return access;
access.script = script;
access.nesting = script->nesting();
access.slot = (kind == ARGUMENT) ? ArgSlot(index) : LocalSlot(script, index);

Просмотреть файл

@ -177,13 +177,14 @@ mjit::Compiler::checkAnalysis(JSScript *script)
return Compile_Abort;
}
if (JSOp(*script->code) == JSOP_GENERATOR) {
JaegerSpew(JSpew_Abort, "script is a generator\n");
if (!script->ensureRanAnalysis(cx, NULL))
return Compile_Error;
if (!script->analysis()->compileable()) {
JaegerSpew(JSpew_Abort, "script has uncompileable opcodes\n");
return Compile_Abort;
}
if (!script->ensureRanAnalysis(cx, NULL))
return Compile_Error;
if (cx->typeInferenceEnabled() && !script->ensureRanInference(cx))
return Compile_Error;
@ -3258,12 +3259,7 @@ mjit::Compiler::generateMethod()
END_CASE(JSOP_DEBUGGER)
default:
/* Sorry, this opcode isn't implemented yet. */
#ifdef JS_METHODJIT_SPEW
JaegerSpew(JSpew_Abort, "opcode %s not handled yet (%s line %d)\n", OpcodeNames[op],
script->filename, js_PCToLineNumber(cx, script, PC));
#endif
return Compile_Abort;
JS_NOT_REACHED("Opcode not implemented");
}
/**********************