Bug 867471 - Part 1: Compile rest parameter in Baseline. (r=djvj)
authorShu-yu Guo <shu@rfrn.org>
Tue, 21 May 2013 23:52:44 -0700
changeset 132586 ddd20f8bcb1c4f0ae3cb8b9e8e7405c7a5c7890c
parent 132585 fbc3ef777ded5ba90f8fe6fe9f2dc66adf68046f
child 132587 b2216a10f95b8a5ed121be06182961f1bfce3acd
push id28350
push usershu@rfrn.org
push dateWed, 22 May 2013 06:53:07 +0000
treeherdermozilla-inbound@2f7967db9d25 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdjvj
bugs867471
milestone24.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 867471 - Part 1: Compile rest parameter in Baseline. (r=djvj)
js/src/ion/BaselineCompiler.cpp
js/src/ion/BaselineCompiler.h
js/src/ion/BaselineIC.cpp
js/src/ion/BaselineIC.h
--- a/js/src/ion/BaselineCompiler.cpp
+++ b/js/src/ion/BaselineCompiler.cpp
@@ -2429,8 +2429,26 @@ BaselineCompiler::emit_JSOP_ARGUMENTS()
 
     if (!callVM(NewArgumentsObjectInfo))
         return false;
 
     masm.bind(&done);
     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;
+}
--- a/js/src/ion/BaselineCompiler.h
+++ b/js/src/ion/BaselineCompiler.h
@@ -147,16 +147,17 @@ namespace ion {
     _(JSOP_TRY)                \
     _(JSOP_ENTERBLOCK)         \
     _(JSOP_ENTERLET0)          \
     _(JSOP_ENTERLET1)          \
     _(JSOP_LEAVEBLOCK)         \
     _(JSOP_EXCEPTION)          \
     _(JSOP_DEBUGGER)           \
     _(JSOP_ARGUMENTS)          \
+    _(JSOP_REST)               \
     _(JSOP_TOID)               \
     _(JSOP_TABLESWITCH)        \
     _(JSOP_ITER)               \
     _(JSOP_MOREITER)           \
     _(JSOP_ITERNEXT)           \
     _(JSOP_ENDITER)            \
     _(JSOP_POPV)               \
     _(JSOP_SETRVAL)            \
--- a/js/src/ion/BaselineIC.cpp
+++ b/js/src/ion/BaselineIC.cpp
@@ -7990,16 +7990,56 @@ ICTypeOf_Typed::Compiler::generateStubCo
     masm.tagValue(JSVAL_TYPE_STRING, R0.scratchReg(), R0);
     EmitReturnFromIC(masm);
 
     masm.bind(&failure);
     EmitStubGuardFailure(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<DoCreateRestParameterFn>(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),
     str_(str),
     script_(script)
 { }
 
 ICTypeMonitor_SingleObject::ICTypeMonitor_SingleObject(IonCode *stubCode, HandleObject obj)
--- a/js/src/ion/BaselineIC.h
+++ b/js/src/ion/BaselineIC.h
@@ -383,17 +383,19 @@ class ICEntry
     _(IteratorMore_Native)      \
     _(IteratorNext_Fallback)    \
     _(IteratorNext_Native)      \
     _(IteratorClose_Fallback)   \
                                 \
     _(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)
 #undef FORWARD_DECLARE_STUBS
 
 class ICMonitoredStub;
 class ICMonitoredFallbackStub;
 class ICUpdatedStub;
@@ -5475,12 +5477,44 @@ class ICTypeOf_Typed : public ICFallback
         { }
 
         ICStub *getStub(ICStubSpace *space) {
             return ICTypeOf_Typed::New(space, getStubCode(), type_);
         }
     };
 };
 
+// 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<ICRest_Fallback>(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
 
 #endif