From bdb5e80eab04866604ebb923fe5c683fd97582e9 Mon Sep 17 00:00:00 2001 From: Kannan Vijayan Date: Thu, 7 Mar 2013 11:24:00 -0500 Subject: [PATCH] Bug 848171 - Add optimized TypeOf stubs for primitive types. r=jandem --- js/src/ion/BaselineIC.cpp | 62 ++++++++++++++++++++++++++++++++++++--- js/src/ion/BaselineIC.h | 48 +++++++++++++++++++++++++++++- 2 files changed, 105 insertions(+), 5 deletions(-) diff --git a/js/src/ion/BaselineIC.cpp b/js/src/ion/BaselineIC.cpp index a9ab2cbe85d..c0dc256b239 100644 --- a/js/src/ion/BaselineIC.cpp +++ b/js/src/ion/BaselineIC.cpp @@ -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(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 diff --git a/js/src/ion/BaselineIC.h b/js/src/ion/BaselineIC.h index 2eed231059b..0690f23cddb 100644 --- a/js/src/ion/BaselineIC.h +++ b/js/src/ion/BaselineIC.h @@ -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(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(kind) | (static_cast(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