mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-28 21:28:55 +00:00
Bug 799818 part 3 - Guard for strings when inlining known constants. r=jandem
This commit is contained in:
parent
a243dbcb81
commit
009e82fae0
@ -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()) {
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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).
|
||||
|
@ -63,6 +63,7 @@ namespace ion {
|
||||
_(Box) \
|
||||
_(Unbox) \
|
||||
_(GuardObject) \
|
||||
_(GuardString) \
|
||||
_(ToDouble) \
|
||||
_(ToInt32) \
|
||||
_(TruncateToInt32) \
|
||||
|
Loading…
x
Reference in New Issue
Block a user