From 90e2941bae952e0228e0cfdc8da6ac1c776ceb4c Mon Sep 17 00:00:00 2001 From: Shu-yu Guo Date: Tue, 21 May 2013 23:52:44 -0700 Subject: [PATCH] Bug 867471 - Part 1: Compile rest parameter in Baseline. (r=djvj) --- js/src/ion/BaselineCompiler.cpp | 18 +++++++++++++++ js/src/ion/BaselineCompiler.h | 1 + js/src/ion/BaselineIC.cpp | 40 +++++++++++++++++++++++++++++++++ js/src/ion/BaselineIC.h | 36 ++++++++++++++++++++++++++++- 4 files changed, 94 insertions(+), 1 deletion(-) diff --git a/js/src/ion/BaselineCompiler.cpp b/js/src/ion/BaselineCompiler.cpp index b084d6bf5bf..db8eaa8572f 100644 --- a/js/src/ion/BaselineCompiler.cpp +++ b/js/src/ion/BaselineCompiler.cpp @@ -2434,3 +2434,21 @@ BaselineCompiler::emit_JSOP_ARGUMENTS() frame.push(R0); return true; } + +bool +BaselineCompiler::emit_JSOP_REST() +{ + frame.syncStack(0); + + RootedTypeObject type(cx, types::TypeScript::InitObject(cx, script, pc, JSProto_Array)); + if (!type) + return false; + masm.movePtr(ImmGCPtr(type), R0.scratchReg()); + + ICRest_Fallback::Compiler stubCompiler(cx); + if (!emitOpIC(stubCompiler.getStub(&stubSpace_))) + return false; + + frame.push(R0); + return true; +} diff --git a/js/src/ion/BaselineCompiler.h b/js/src/ion/BaselineCompiler.h index 718164f82f7..6aa7cd9ed44 100644 --- a/js/src/ion/BaselineCompiler.h +++ b/js/src/ion/BaselineCompiler.h @@ -152,6 +152,7 @@ namespace ion { _(JSOP_EXCEPTION) \ _(JSOP_DEBUGGER) \ _(JSOP_ARGUMENTS) \ + _(JSOP_REST) \ _(JSOP_TOID) \ _(JSOP_TABLESWITCH) \ _(JSOP_ITER) \ diff --git a/js/src/ion/BaselineIC.cpp b/js/src/ion/BaselineIC.cpp index a93a0e31f68..9f47d3374c8 100644 --- a/js/src/ion/BaselineIC.cpp +++ b/js/src/ion/BaselineIC.cpp @@ -7995,6 +7995,46 @@ ICTypeOf_Typed::Compiler::generateStubCode(MacroAssembler &masm) return true; } +// +// Rest_Fallback +// + +static bool +DoCreateRestParameter(JSContext *cx, BaselineFrame *frame, ICRest_Fallback *stub, + HandleTypeObject type, MutableHandleValue res) +{ + FallbackICSpew(cx, stub, "Rest"); + + unsigned numFormals = frame->numFormalArgs() - 1; + unsigned numActuals = frame->numActualArgs(); + unsigned numRest = numActuals > numFormals ? numActuals - numFormals : 0; + + JSObject *obj = NewDenseCopiedArray(cx, numRest, frame->actuals() + numFormals, NULL); + if (!obj) + return false; + obj->setType(type); + + res.setObject(*obj); + return true; +} + +typedef bool(*DoCreateRestParameterFn)(JSContext *cx, BaselineFrame *, ICRest_Fallback *, + HandleTypeObject, MutableHandleValue); +static const VMFunction DoCreateRestParameterInfo = + FunctionInfo(DoCreateRestParameter); + +bool +ICRest_Fallback::Compiler::generateStubCode(MacroAssembler &masm) +{ + EmitRestoreTailCallReg(masm); + + masm.push(R0.scratchReg()); // type + masm.push(BaselineStubReg); // stub + masm.pushBaselineFramePtr(BaselineFrameReg, R0.scratchReg()); // frame pointer + + return tailCallVM(DoCreateRestParameterInfo, masm); +} + ICProfiler_PushFunction::ICProfiler_PushFunction(IonCode *stubCode, const char *str, HandleScript script) : ICStub(ICStub::Profiler_PushFunction, stubCode), diff --git a/js/src/ion/BaselineIC.h b/js/src/ion/BaselineIC.h index 5a8cfff5149..607219a9270 100644 --- a/js/src/ion/BaselineIC.h +++ b/js/src/ion/BaselineIC.h @@ -388,7 +388,9 @@ class ICEntry _(InstanceOf_Fallback) \ \ _(TypeOf_Fallback) \ - _(TypeOf_Typed) + _(TypeOf_Typed) \ + \ + _(Rest_Fallback) #define FORWARD_DECLARE_STUBS(kindName) class IC##kindName; IC_STUB_KIND_LIST(FORWARD_DECLARE_STUBS) @@ -5480,6 +5482,38 @@ class ICTypeOf_Typed : public ICFallbackStub }; }; +// Rest +// JSOP_REST +class ICRest_Fallback : public ICFallbackStub +{ + friend class ICStubSpace; + + ICRest_Fallback(IonCode *stubCode) + : ICFallbackStub(ICStub::Rest_Fallback, stubCode) + { } + + public: + static inline ICRest_Fallback *New(ICStubSpace *space, IonCode *code) { + if (!code) + return NULL; + return space->allocate(code); + } + + class Compiler : public ICStubCompiler { + protected: + bool generateStubCode(MacroAssembler &masm); + + public: + Compiler(JSContext *cx) + : ICStubCompiler(cx, ICStub::Rest_Fallback) + { } + + ICStub *getStub(ICStubSpace *space) { + return ICRest_Fallback::New(space, getStubCode()); + } + }; +}; + } // namespace ion } // namespace js