[INFER] Use type sets instead of known pushed types when looking for static overflows, bug 643376.

This commit is contained in:
Brian Hackett 2011-03-22 13:41:56 -07:00
Родитель 774cfb9fbf
Коммит 7b43851941
6 изменённых файлов: 46 добавлений и 67 удалений

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

@ -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