Bug 848171 - Add optimized TypeOf stubs for primitive types. r=jandem

This commit is contained in:
Kannan Vijayan 2013-03-07 11:24:00 -05:00
parent 49c6009009
commit bdb5e80eab
2 changed files with 105 additions and 5 deletions

View File

@ -6163,16 +6163,31 @@ ICInstanceOf_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
//
static bool
DoTypeOfFallback(JSContext *cx, ICTypeOf_Fallback *stub, HandleValue val, MutableHandleValue res)
DoTypeOfFallback(JSContext *cx, BaselineFrame *frame, ICTypeOf_Fallback *stub, HandleValue val,
MutableHandleValue res)
{
FallbackICSpew(cx, stub, "TypeOf");
JSType type = JS_TypeOfValue(cx, val);
RootedString string(cx, TypeName(type, cx));
res.setString(string);
JS_ASSERT(type != JSTYPE_NULL);
if (type != JSTYPE_OBJECT && type != JSTYPE_FUNCTION) {
// Create a new TypeOf stub.
IonSpew(IonSpew_BaselineIC, " Generating TypeOf stub for JSType (%d)", (int) type);
ICTypeOf_Typed::Compiler compiler(cx, type, string);
ICStub *typeOfStub = compiler.getStub(compiler.getStubSpace(frame->script()));
if (!typeOfStub)
return false;
stub->addNewStub(typeOfStub);
}
res.setString(TypeOfOperation(cx, val));
return true;
}
typedef bool (*DoTypeOfFallbackFn)(JSContext *, ICTypeOf_Fallback *, HandleValue,
MutableHandleValue);
typedef bool (*DoTypeOfFallbackFn)(JSContext *, BaselineFrame *frame, ICTypeOf_Fallback *,
HandleValue, MutableHandleValue);
static const VMFunction DoTypeOfFallbackInfo =
FunctionInfo<DoTypeOfFallbackFn>(DoTypeOfFallback);
@ -6183,9 +6198,48 @@ ICTypeOf_Fallback::Compiler::generateStubCode(MacroAssembler &masm)
masm.pushValue(R0);
masm.push(BaselineStubReg);
masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg());
return tailCallVM(DoTypeOfFallbackInfo, masm);
}
bool
ICTypeOf_Typed::Compiler::generateStubCode(MacroAssembler &masm)
{
JS_ASSERT(type_ != JSTYPE_NULL);
JS_ASSERT(type_ != JSTYPE_FUNCTION);
JS_ASSERT(type_ != JSTYPE_OBJECT);
Label failure;
switch(type_) {
case JSTYPE_VOID:
masm.branchTestUndefined(Assembler::NotEqual, R0, &failure);
break;
case JSTYPE_STRING:
masm.branchTestString(Assembler::NotEqual, R0, &failure);
break;
case JSTYPE_NUMBER:
masm.branchTestNumber(Assembler::NotEqual, R0, &failure);
break;
case JSTYPE_BOOLEAN:
masm.branchTestBoolean(Assembler::NotEqual, R0, &failure);
break;
default:
JS_NOT_REACHED("Unexpected type");
}
masm.movePtr(ImmGCPtr(typeString_), R0.scratchReg());
masm.tagValue(JSVAL_TYPE_STRING, R0.scratchReg(), R0);
EmitReturnFromIC(masm);
masm.bind(&failure);
EmitStubGuardFailure(masm);
return true;
}
} // namespace ion
} // namespace js

View File

@ -377,7 +377,8 @@ class ICEntry
\
_(InstanceOf_Fallback) \
\
_(TypeOf_Fallback)
_(TypeOf_Fallback) \
_(TypeOf_Typed)
#define FORWARD_DECLARE_STUBS(kindName) class IC##kindName;
IC_STUB_KIND_LIST(FORWARD_DECLARE_STUBS)
@ -4690,6 +4691,51 @@ class ICTypeOf_Fallback : public ICFallbackStub
};
};
class ICTypeOf_Typed : public ICFallbackStub
{
friend class ICStubSpace;
ICTypeOf_Typed(IonCode *stubCode, JSType type)
: ICFallbackStub(ICStub::TypeOf_Typed, stubCode)
{
extra_ = uint16_t(type);
JS_ASSERT(JSType(extra_) == type);
}
public:
static inline ICTypeOf_Typed *New(ICStubSpace *space, IonCode *code, JSType type) {
if (!code)
return NULL;
return space->allocate<ICTypeOf_Typed>(code, type);
}
JSType type() const {
return JSType(extra_);
}
class Compiler : public ICStubCompiler {
protected:
JSType type_;
RootedString typeString_;
bool generateStubCode(MacroAssembler &masm);
virtual int32_t getKey() const {
return static_cast<int32_t>(kind) | (static_cast<int32_t>(type_) << 16);
}
public:
Compiler(JSContext *cx, JSType type, HandleString string)
: ICStubCompiler(cx, ICStub::TypeOf_Typed),
type_(type),
typeString_(cx, string)
{ }
ICStub *getStub(ICStubSpace *space) {
return ICTypeOf_Typed::New(space, getStubCode(), type_);
}
};
};
} // namespace ion
} // namespace js