Bug 799818 part 3 - Guard for strings when inlining known constants. r=jandem

This commit is contained in:
Nicolas B. Pierron 2012-10-19 14:30:38 -07:00
parent a243dbcb81
commit 009e82fae0
5 changed files with 60 additions and 3 deletions

View File

@ -4418,7 +4418,8 @@ TestSingletonProperty(JSContext *cx, HandleObject obj, HandleId id, bool *isKnow
static inline bool
TestSingletonPropertyTypes(JSContext *cx, types::StackTypeSet *types,
HandleObject globalObj, HandleId id,
bool *isKnownConstant, bool *testObject)
bool *isKnownConstant, bool *testObject,
bool *testString)
{
// As for TestSingletonProperty, but the input is any value in a type set
// rather than a specific object. If testObject is set then the constant
@ -4426,6 +4427,7 @@ TestSingletonPropertyTypes(JSContext *cx, types::StackTypeSet *types,
*isKnownConstant = false;
*testObject = false;
*testString = false;
if (!types || types->unknownObject())
return true;
@ -4455,6 +4457,15 @@ TestSingletonPropertyTypes(JSContext *cx, types::StackTypeSet *types,
case JSVAL_TYPE_OBJECT:
case JSVAL_TYPE_UNKNOWN: {
if (types->hasType(types::Type::StringType())) {
// Do not optimize if the object is either a String or an Object.
if (types->maybeObject())
return true;
key = JSProto_String;
*testString = true;
break;
}
// For property accesses which may be on many objects, we just need to
// find a prototype common to all the objects; if that prototype
// has the singleton property, the access will not be on a missing property.
@ -5884,8 +5895,9 @@ IonBuilder::getPropTryConstant(bool *emitted, HandleId id, types::StackTypeSet *
RootedObject global(cx, &script_->global());
bool isConstant, testObject;
if (!TestSingletonPropertyTypes(cx, unaryTypes.inTypes, global, id, &isConstant, &testObject))
bool isConstant, testObject, testString;
if (!TestSingletonPropertyTypes(cx, unaryTypes.inTypes, global, id,
&isConstant, &testObject, &testString))
return false;
if (!isConstant)
@ -5894,8 +5906,11 @@ IonBuilder::getPropTryConstant(bool *emitted, HandleId id, types::StackTypeSet *
MDefinition *obj = current->pop();
// Property access is a known constant -- safe to emit.
JS_ASSERT(!testString || !testObject);
if (testObject)
current->add(MGuardObject::New(obj));
else if (testString)
current->add(MGuardString::New(obj));
MConstant *known = MConstant::New(ObjectValue(*singleton));
if (singleton->isFunction()) {

View File

@ -1718,6 +1718,15 @@ LIRGenerator::visitGuardObject(MGuardObject *ins)
return redefine(ins, ins->input());
}
bool
LIRGenerator::visitGuardString(MGuardString *ins)
{
// The type policy does all the work, so at this point the input
// is guaranteed to be a string.
JS_ASSERT(ins->input()->type() == MIRType_String);
return redefine(ins, ins->input());
}
bool
LIRGenerator::visitCallGetProperty(MCallGetProperty *ins)
{

View File

@ -165,6 +165,7 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitBindNameCache(MBindNameCache *ins);
bool visitGuardClass(MGuardClass *ins);
bool visitGuardObject(MGuardObject *ins);
bool visitGuardString(MGuardString *ins);
bool visitCallGetProperty(MCallGetProperty *ins);
bool visitDeleteProperty(MDeleteProperty *ins);
bool visitGetNameCache(MGetNameCache *ins);

View File

@ -1501,6 +1501,37 @@ class MGuardObject : public MUnaryInstruction, public SingleObjectPolicy
}
};
class MGuardString
: public MUnaryInstruction,
public StringPolicy
{
MGuardString(MDefinition *ins)
: MUnaryInstruction(ins)
{
setGuard();
setMovable();
setResultType(MIRType_String);
}
public:
INSTRUCTION_HEADER(GuardString);
static MGuardString *New(MDefinition *ins) {
return new MGuardString(ins);
}
MDefinition *input() const {
return getOperand(0);
}
TypePolicy *typePolicy() {
return this;
}
AliasSet getAliasSet() const {
return AliasSet::None();
}
};
// Caller-side allocation of |this| for |new|:
// Given a prototype operand, construct |this| for JSOP_NEW.
// For native constructors, returns MagicValue(JS_IS_CONSTRUCTING).

View File

@ -63,6 +63,7 @@ namespace ion {
_(Box) \
_(Unbox) \
_(GuardObject) \
_(GuardString) \
_(ToDouble) \
_(ToInt32) \
_(TruncateToInt32) \