зеркало из https://github.com/mozilla/gecko-dev.git
[INFER] Use type sets instead of known pushed types when looking for static overflows, bug 643376.
This commit is contained in:
Родитель
774cfb9fbf
Коммит
7b43851941
|
@ -0,0 +1,8 @@
|
|||
SECTION = 0;
|
||||
function TestCase() {}
|
||||
function outer_func(x)
|
||||
{
|
||||
var y = "inner";
|
||||
new TestCase( SECTION, { SECTION: ++y });
|
||||
}
|
||||
outer_func(1111);
|
|
@ -1833,10 +1833,6 @@ TypeCompartment::dynamicPush(JSContext *cx, JSScript *script, uint32 offset, jst
|
|||
case JSOP_DECGNAME:
|
||||
case JSOP_GNAMEINC:
|
||||
case JSOP_GNAMEDEC: {
|
||||
/*
|
||||
* This is only hit in the method JIT, which does not run into the issues
|
||||
* posed by bug 605200.
|
||||
*/
|
||||
jsid id = GetAtomId(cx, script, pc, 0);
|
||||
TypeObject *global = script->getGlobalType();
|
||||
if (!global->unknownProperties) {
|
||||
|
|
|
@ -1436,31 +1436,23 @@ mjit::Compiler::generateMethod()
|
|||
END_CASE(JSOP_URSH)
|
||||
|
||||
BEGIN_CASE(JSOP_ADD)
|
||||
if (!jsop_binary(op, stubs::Add, knownPushedType(0))) {
|
||||
markPushedOverflow();
|
||||
if (!jsop_binary(op, stubs::Add, knownPushedType(0), pushedTypeSet(0)))
|
||||
return Compile_Overflow;
|
||||
}
|
||||
END_CASE(JSOP_ADD)
|
||||
|
||||
BEGIN_CASE(JSOP_SUB)
|
||||
if (!jsop_binary(op, stubs::Sub, knownPushedType(0))) {
|
||||
markPushedOverflow();
|
||||
if (!jsop_binary(op, stubs::Sub, knownPushedType(0), pushedTypeSet(0)))
|
||||
return Compile_Overflow;
|
||||
}
|
||||
END_CASE(JSOP_SUB)
|
||||
|
||||
BEGIN_CASE(JSOP_MUL)
|
||||
if (!jsop_binary(op, stubs::Mul, knownPushedType(0))) {
|
||||
markPushedOverflow();
|
||||
if (!jsop_binary(op, stubs::Mul, knownPushedType(0), pushedTypeSet(0)))
|
||||
return Compile_Overflow;
|
||||
}
|
||||
END_CASE(JSOP_MUL)
|
||||
|
||||
BEGIN_CASE(JSOP_DIV)
|
||||
if (!jsop_binary(op, stubs::Div, knownPushedType(0))) {
|
||||
markPushedOverflow();
|
||||
if (!jsop_binary(op, stubs::Div, knownPushedType(0), pushedTypeSet(0)))
|
||||
return Compile_Overflow;
|
||||
}
|
||||
END_CASE(JSOP_DIV)
|
||||
|
||||
BEGIN_CASE(JSOP_MOD)
|
||||
|
@ -1497,9 +1489,9 @@ mjit::Compiler::generateMethod()
|
|||
Value v = NumberValue(d);
|
||||
|
||||
/* Watch for overflow in constant propagation. */
|
||||
if (!v.isInt32() && knownPushedType(0) == JSVAL_TYPE_INT32) {
|
||||
JaegerSpew(JSpew_Abort, "overflow in negation (%u)\n", PC - script->code);
|
||||
markPushedOverflow();
|
||||
types::TypeSet *pushed = pushedTypeSet(0);
|
||||
if (!v.isInt32() && pushed && !pushed->hasType(types::TYPE_DOUBLE)) {
|
||||
script->typeMonitorResult(cx, PC, types::TYPE_DOUBLE);
|
||||
return Compile_Overflow;
|
||||
}
|
||||
|
||||
|
@ -4360,7 +4352,7 @@ mjit::Compiler::jsop_gnameinc(JSOp op, VoidStubAtom stub, uint32 index)
|
|||
// V 1
|
||||
|
||||
/* Use sub since it calls ValueToNumber instead of string concat. */
|
||||
jsop_binary(JSOP_SUB, stubs::Sub, JSVAL_TYPE_UNKNOWN);
|
||||
jsop_binary(JSOP_SUB, stubs::Sub, JSVAL_TYPE_UNKNOWN, pushedTypeSet(0));
|
||||
// N+1
|
||||
|
||||
jsop_bindgname();
|
||||
|
@ -4395,7 +4387,7 @@ mjit::Compiler::jsop_gnameinc(JSOp op, VoidStubAtom stub, uint32 index)
|
|||
frame.push(Int32Value(-amt));
|
||||
// N N 1
|
||||
|
||||
jsop_binary(JSOP_ADD, stubs::Add, JSVAL_TYPE_UNKNOWN);
|
||||
jsop_binary(JSOP_ADD, stubs::Add, JSVAL_TYPE_UNKNOWN, pushedTypeSet(0));
|
||||
// N N+1
|
||||
|
||||
jsop_bindgname();
|
||||
|
@ -4452,7 +4444,7 @@ mjit::Compiler::jsop_nameinc(JSOp op, VoidStubAtom stub, uint32 index)
|
|||
|
||||
/* Use sub since it calls ValueToNumber instead of string concat. */
|
||||
frame.syncAt(-3);
|
||||
jsop_binary(JSOP_SUB, stubs::Sub, JSVAL_TYPE_UNKNOWN);
|
||||
jsop_binary(JSOP_SUB, stubs::Sub, JSVAL_TYPE_UNKNOWN, pushedTypeSet(0));
|
||||
// OBJ N+1
|
||||
|
||||
if (!jsop_setprop(atom, false))
|
||||
|
@ -4480,7 +4472,7 @@ mjit::Compiler::jsop_nameinc(JSOp op, VoidStubAtom stub, uint32 index)
|
|||
// N OBJ N 1
|
||||
|
||||
frame.syncAt(-3);
|
||||
jsop_binary(JSOP_ADD, stubs::Add, JSVAL_TYPE_UNKNOWN);
|
||||
jsop_binary(JSOP_ADD, stubs::Add, JSVAL_TYPE_UNKNOWN, pushedTypeSet(0));
|
||||
// N OBJ N+1
|
||||
|
||||
if (!jsop_setprop(atom, false))
|
||||
|
@ -4538,7 +4530,7 @@ mjit::Compiler::jsop_propinc(JSOp op, VoidStubAtom stub, uint32 index)
|
|||
|
||||
/* Use sub since it calls ValueToNumber instead of string concat. */
|
||||
frame.syncAt(-4);
|
||||
jsop_binary(JSOP_SUB, stubs::Sub, JSVAL_TYPE_UNKNOWN);
|
||||
jsop_binary(JSOP_SUB, stubs::Sub, JSVAL_TYPE_UNKNOWN, pushedTypeSet(0));
|
||||
// OBJ * V+1
|
||||
|
||||
frame.shimmy(1);
|
||||
|
@ -4570,7 +4562,7 @@ mjit::Compiler::jsop_propinc(JSOp op, VoidStubAtom stub, uint32 index)
|
|||
// OBJ N N 1
|
||||
|
||||
frame.syncAt(-4);
|
||||
jsop_binary(JSOP_ADD, stubs::Add, JSVAL_TYPE_UNKNOWN);
|
||||
jsop_binary(JSOP_ADD, stubs::Add, JSVAL_TYPE_UNKNOWN, pushedTypeSet(0));
|
||||
// OBJ N N+1
|
||||
|
||||
frame.dupAt(-3);
|
||||
|
@ -5912,12 +5904,6 @@ mjit::Compiler::knownArgumentType(uint32 arg)
|
|||
return argumentTypes[arg];
|
||||
}
|
||||
|
||||
void
|
||||
mjit::Compiler::markArgumentOverflow(uint32 arg)
|
||||
{
|
||||
script->typeSetArgument(cx, arg, DoubleValue(0.0));
|
||||
}
|
||||
|
||||
JSValueType
|
||||
mjit::Compiler::knownLocalType(uint32 local)
|
||||
{
|
||||
|
@ -5926,12 +5912,6 @@ mjit::Compiler::knownLocalType(uint32 local)
|
|||
return localTypes[local];
|
||||
}
|
||||
|
||||
void
|
||||
mjit::Compiler::markLocalOverflow(uint32 local)
|
||||
{
|
||||
script->typeSetLocal(cx, local, DoubleValue(0.0));
|
||||
}
|
||||
|
||||
JSValueType
|
||||
mjit::Compiler::knownPushedType(uint32 pushed)
|
||||
{
|
||||
|
@ -5970,6 +5950,14 @@ mjit::Compiler::localTypeSet(uint32 local)
|
|||
return script->localTypes(local);
|
||||
}
|
||||
|
||||
types::TypeSet *
|
||||
mjit::Compiler::pushedTypeSet(uint32 pushed)
|
||||
{
|
||||
if (!cx->typeInferenceEnabled())
|
||||
return NULL;
|
||||
return script->types->pushed(PC - script->code, pushed);
|
||||
}
|
||||
|
||||
bool
|
||||
mjit::Compiler::monitored(jsbytecode *pc)
|
||||
{
|
||||
|
@ -5982,13 +5970,6 @@ mjit::Compiler::pushSyncedEntry(uint32 pushed)
|
|||
frame.pushSynced(knownPushedType(pushed));
|
||||
}
|
||||
|
||||
void
|
||||
mjit::Compiler::markPushedOverflow()
|
||||
{
|
||||
/* OK to ignore failure here, we aren't performing the operation itself. */
|
||||
script->typeMonitorResult(cx, PC, types::TYPE_DOUBLE);
|
||||
}
|
||||
|
||||
JSObject *
|
||||
mjit::Compiler::pushedSingleton(unsigned pushed)
|
||||
{
|
||||
|
|
|
@ -443,10 +443,8 @@ class Compiler : public BaseCompiler
|
|||
bool mayPushUndefined(uint32 pushed);
|
||||
types::TypeSet *argTypeSet(uint32 arg);
|
||||
types::TypeSet *localTypeSet(uint32 local);
|
||||
types::TypeSet *pushedTypeSet(uint32 which);
|
||||
bool monitored(jsbytecode *pc);
|
||||
void markPushedOverflow();
|
||||
void markLocalOverflow(uint32 local);
|
||||
void markArgumentOverflow(uint32 arg);
|
||||
bool testSingletonProperty(JSObject *obj, jsid id);
|
||||
bool testSingletonPropertyTypes(types::TypeSet *types, jsid id);
|
||||
|
||||
|
@ -544,7 +542,7 @@ class Compiler : public BaseCompiler
|
|||
void jsop_forgname(JSAtom *atom);
|
||||
|
||||
/* Fast arithmetic. */
|
||||
bool jsop_binary(JSOp op, VoidStub stub, JSValueType type);
|
||||
bool jsop_binary(JSOp op, VoidStub stub, JSValueType type, types::TypeSet *typeSet);
|
||||
void jsop_binary_full(FrameEntry *lhs, FrameEntry *rhs, JSOp op, VoidStub stub,
|
||||
JSValueType type);
|
||||
void jsop_binary_full_simple(FrameEntry *fe, JSOp op, VoidStub stub,
|
||||
|
|
|
@ -197,16 +197,20 @@ mjit::Compiler::maybeJumpIfNotDouble(Assembler &masm, MaybeJump &mj, FrameEntry
|
|||
}
|
||||
|
||||
bool
|
||||
mjit::Compiler::jsop_binary(JSOp op, VoidStub stub, JSValueType type)
|
||||
mjit::Compiler::jsop_binary(JSOp op, VoidStub stub, JSValueType type, types::TypeSet *typeSet)
|
||||
{
|
||||
FrameEntry *rhs = frame.peek(-1);
|
||||
FrameEntry *lhs = frame.peek(-2);
|
||||
|
||||
Value v;
|
||||
if (tryBinaryConstantFold(cx, frame, op, lhs, rhs, &v)) {
|
||||
if (type == JSVAL_TYPE_INT32 && !v.isInt32()) {
|
||||
/* Caller must mark the right type set as having overflowed. */
|
||||
JaegerSpew(JSpew_Abort, "overflow in binary (%u)\n", PC - script->code);
|
||||
if (!v.isInt32() && typeSet && !typeSet->hasType(types::TYPE_DOUBLE)) {
|
||||
/*
|
||||
* OK to ignore failure here, we aren't performing the operation
|
||||
* itself. Note that typeMonitorResult will propagate the type
|
||||
* as necessary if a *INC operation overflowed.
|
||||
*/
|
||||
script->typeMonitorResult(cx, PC, types::TYPE_DOUBLE);
|
||||
return false;
|
||||
}
|
||||
frame.popn(2);
|
||||
|
@ -906,9 +910,9 @@ mjit::Compiler::jsop_mod()
|
|||
|
||||
Value v;
|
||||
if (tryBinaryConstantFold(cx, frame, JSOP_MOD, lhs, rhs, &v)) {
|
||||
if (type == JSVAL_TYPE_INT32 && !v.isInt32()) {
|
||||
JaegerSpew(JSpew_Abort, "overflow in mod (%u)\n", PC - script->code);
|
||||
markPushedOverflow();
|
||||
types::TypeSet *pushed = pushedTypeSet(0);
|
||||
if (!v.isInt32() && pushed && !pushed->hasType(types::TYPE_DOUBLE)) {
|
||||
script->typeMonitorResult(cx, PC, types::TYPE_DOUBLE);
|
||||
return false;
|
||||
}
|
||||
frame.popn(2);
|
||||
|
|
|
@ -1013,10 +1013,8 @@ mjit::Compiler::jsop_localinc(JSOp op, uint32 slot, bool popped)
|
|||
// Note, SUB will perform integer conversion for us.
|
||||
// Before: V 1
|
||||
// After: N+1
|
||||
if (!jsop_binary(JSOP_SUB, stubs::Sub, type)) {
|
||||
markLocalOverflow(slot);
|
||||
if (!jsop_binary(JSOP_SUB, stubs::Sub, type, localTypeSet(slot)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Before: N+1
|
||||
// After: N+1
|
||||
|
@ -1045,10 +1043,8 @@ mjit::Compiler::jsop_localinc(JSOp op, uint32 slot, bool popped)
|
|||
|
||||
// Before: N N 1
|
||||
// After: N N+1
|
||||
if (!jsop_binary(JSOP_ADD, stubs::Add, type)) {
|
||||
markLocalOverflow(slot);
|
||||
if (!jsop_binary(JSOP_ADD, stubs::Add, type, localTypeSet(slot)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Before: N N+1
|
||||
// After: N N+1
|
||||
|
@ -1081,10 +1077,8 @@ mjit::Compiler::jsop_arginc(JSOp op, uint32 slot, bool popped)
|
|||
// Note, SUB will perform integer conversion for us.
|
||||
// Before: V 1
|
||||
// After: N+1
|
||||
if (!jsop_binary(JSOP_SUB, stubs::Sub, type)) {
|
||||
markArgumentOverflow(slot);
|
||||
if (!jsop_binary(JSOP_SUB, stubs::Sub, type, argTypeSet(slot)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Before: N+1
|
||||
// After: N+1
|
||||
|
@ -1113,10 +1107,8 @@ mjit::Compiler::jsop_arginc(JSOp op, uint32 slot, bool popped)
|
|||
|
||||
// Before: N N 1
|
||||
// After: N N+1
|
||||
if (!jsop_binary(JSOP_ADD, stubs::Add, type)) {
|
||||
markArgumentOverflow(slot);
|
||||
if (!jsop_binary(JSOP_ADD, stubs::Add, type, argTypeSet(slot)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Before: N N+1
|
||||
// After: N N+1
|
||||
|
|
Загрузка…
Ссылка в новой задаче