Bug 784291 - Implement JSOP_INTRINSICNAME in IonMonkey. (r=nbp)

This commit is contained in:
Shu-yu Guo 2012-11-06 17:54:49 -08:00
parent 215740ebf7
commit 62512388e8
13 changed files with 108 additions and 3 deletions

View File

@ -775,6 +775,16 @@ CodeGenerator::visitCallDOMNative(LCallDOMNative *call)
return true;
}
bool
CodeGenerator::visitCallGetIntrinsicValue(LCallGetIntrinsicValue *lir)
{
typedef bool (*pf)(JSContext *cx, HandlePropertyName, MutableHandleValue);
static const VMFunction Info = FunctionInfo<pf>(GetIntrinsicValue);
pushArg(ImmGCPtr(lir->mir()->name()));
return callVM(Info, lir);
}
typedef bool (*InvokeFunctionFn)(JSContext *, JSFunction *, uint32, Value *, Value *);
static const VMFunction InvokeFunctionInfo =
FunctionInfo<InvokeFunctionFn>(InvokeFunction);

View File

@ -175,6 +175,7 @@ class CodeGenerator : public CodeGeneratorSpecific
bool visitGetDOMProperty(LGetDOMProperty *lir);
bool visitSetDOMProperty(LSetDOMProperty *lir);
bool visitCallDOMNative(LCallDOMNative *lir);
bool visitCallGetIntrinsicValue(LCallGetIntrinsicValue *lir);
bool visitCheckOverRecursed(LCheckOverRecursed *lir);
bool visitCheckOverRecursedFailure(CheckOverRecursedFailure *ool);

View File

@ -963,6 +963,13 @@ IonBuilder::inspectOpcode(JSOp op)
return jsop_getname(name);
}
case JSOP_INTRINSICNAME:
case JSOP_CALLINTRINSIC:
{
RootedPropertyName name(cx, info().getAtom(pc)->asPropertyName());
return jsop_intrinsicname(name);
}
case JSOP_BINDNAME:
return jsop_bindname(info().getName(pc));
@ -4744,6 +4751,42 @@ IonBuilder::jsop_getname(HandlePropertyName name)
return pushTypeBarrier(ins, types, barrier);
}
bool
IonBuilder::jsop_intrinsicname(HandlePropertyName name)
{
types::StackTypeSet *types = oracle->propertyRead(script_, pc);
JSValueType type = types->getKnownTypeTag();
// If we haven't executed this opcode yet, we need to get the intrinsic
// value and monitor the result.
if (type == JSVAL_TYPE_UNKNOWN) {
MCallGetIntrinsicValue *ins = MCallGetIntrinsicValue::New(name);
current->add(ins);
current->push(ins);
if (!resumeAfter(ins))
return false;
types::StackTypeSet *barrier = oracle->propertyReadBarrier(script_, pc);
monitorResult(ins, barrier, types);
return pushTypeBarrier(ins, types, barrier);
}
// Bake in the intrinsic. Make sure that TI agrees with us on the type.
RootedValue vp(cx, UndefinedValue());
if (!cx->global()->getIntrinsicValue(cx, name, &vp))
return false;
JS_ASSERT(types->hasType(types::GetValueType(cx, vp)));
MConstant *ins = MConstant::New(vp);
current->add(ins);
current->push(ins);
return true;
}
bool
IonBuilder::jsop_bindname(PropertyName *name)
{

View File

@ -324,6 +324,7 @@ class IonBuilder : public MIRGenerator
bool jsop_getgname(HandlePropertyName name);
bool jsop_setgname(HandlePropertyName name);
bool jsop_getname(HandlePropertyName name);
bool jsop_intrinsicname(HandlePropertyName name);
bool jsop_bindname(PropertyName *name);
bool jsop_getelem();
bool jsop_getelem_dense();

View File

@ -2519,6 +2519,17 @@ class LGetNameCache : public LInstructionHelper<BOX_PIECES, 1, 0>
}
};
class LCallGetIntrinsicValue : public LCallInstructionHelper<BOX_PIECES, 0, 0>
{
public:
LIR_HEADER(CallGetIntrinsicValue);
BOX_OUTPUT_ACCESSORS();
const MCallGetIntrinsicValue *mir() const {
return mir_->toCallGetIntrinsicValue();
}
};
// Patchable jump to stubs generated for a GetProperty cache, which loads a
// boxed value.
class LGetPropertyCacheV : public LInstructionHelper<BOX_PIECES, 1, 0>

View File

@ -145,6 +145,7 @@
_(BindNameCache) \
_(CallGetProperty) \
_(GetNameCache) \
_(CallGetIntrinsicValue) \
_(CallGetElement) \
_(CallSetElement) \
_(CallSetProperty) \

View File

@ -1668,6 +1668,15 @@ LIRGenerator::visitGetNameCache(MGetNameCache *ins)
return assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitCallGetIntrinsicValue(MCallGetIntrinsicValue *ins)
{
LCallGetIntrinsicValue *lir = new LCallGetIntrinsicValue();
if (!defineVMReturn(lir, ins))
return false;
return assignSafepoint(lir, ins);
}
bool
LIRGenerator::visitGetPropertyCache(MGetPropertyCache *ins)
{

View File

@ -169,6 +169,7 @@ class LIRGenerator : public LIRGeneratorSpecific
bool visitCallGetProperty(MCallGetProperty *ins);
bool visitDeleteProperty(MDeleteProperty *ins);
bool visitGetNameCache(MGetNameCache *ins);
bool visitCallGetIntrinsicValue(MCallGetIntrinsicValue *ins);
bool visitCallGetElement(MCallGetElement *ins);
bool visitCallSetElement(MCallSetElement *ins);
bool visitSetPropertyCache(MSetPropertyCache *ins);

View File

@ -4755,6 +4755,27 @@ class MGetNameCache
}
};
class MCallGetIntrinsicValue : public MNullaryInstruction
{
CompilerRootPropertyName name_;
MCallGetIntrinsicValue(HandlePropertyName name)
: name_(name)
{
setResultType(MIRType_Value);
}
public:
INSTRUCTION_HEADER(CallGetIntrinsicValue);
static MCallGetIntrinsicValue *New(HandlePropertyName name) {
return new MCallGetIntrinsicValue(name);
}
PropertyName *name() const {
return name_;
}
};
class MSetPropertyInstruction : public MBinaryInstruction
{
CompilerRootPropertyName name_;

View File

@ -116,6 +116,7 @@ namespace ion {
_(StoreFixedSlot) \
_(CallGetProperty) \
_(GetNameCache) \
_(CallGetIntrinsicValue) \
_(CallGetElement) \
_(CallSetElement) \
_(CallSetProperty) \

View File

@ -457,5 +457,10 @@ bool OperatorIn(JSContext *cx, HandleValue key, HandleObject obj, JSBool *out)
return true;
}
bool GetIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue rval)
{
return cx->global()->getIntrinsicValue(cx, name, rval);
}
} // namespace ion
} // namespace js

View File

@ -461,6 +461,8 @@ bool SPSExit(JSContext *cx, HandleScript script);
bool OperatorIn(JSContext *cx, HandleValue key, HandleObject obj, JSBool *out);
bool GetIntrinsicValue(JSContext *cx, HandlePropertyName name, MutableHandleValue rval);
} // namespace ion
} // namespace js

View File

@ -405,9 +405,8 @@ inline bool
IntrinsicNameOperation(JSContext *cx, JSScript *script, jsbytecode *pc, MutableHandleValue vp)
{
JSOp op = JSOp(*pc);
RootedPropertyName name(cx, GetNameFromBytecode(cx, script, pc, op));
cx->global()->getIntrinsicValue(cx, name, vp);
return true;
RootedPropertyName name(cx, GetNameFromBytecode(cx, script, pc, op));
return cx->global()->getIntrinsicValue(cx, name, vp);
}
inline bool