[JAEGER] Fixed bug where LAMBDA + INITMETHOD did not honor cloning optimizations.
authorDavid Anderson <danderson@mozilla.com>
Tue, 20 Jul 2010 15:43:03 -0700
changeset 53128 b3da5ad5938229d0538c5df358b271f4785f6d25
parent 53127 3f7052b3c1b687465c33c306070853801dfc0083
child 53129 e6d7d1bf7b062267a924d387e154eb92bcd1390a
push id15660
push userrsayre@mozilla.com
push dateSat, 11 Sep 2010 19:16:24 +0000
treeherdermozilla-central@f1bd314e64ac [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
milestone2.0b2pre
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
[JAEGER] Fixed bug where LAMBDA + INITMETHOD did not honor cloning optimizations.
js/src/methodjit/Compiler.cpp
js/src/methodjit/StubCalls.cpp
js/src/methodjit/StubCalls.h
--- a/js/src/methodjit/Compiler.cpp
+++ b/js/src/methodjit/Compiler.cpp
@@ -1082,17 +1082,22 @@ mjit::Compiler::generateMethod()
           }
           END_CASE(JSOP_DEFFUN)
 
           BEGIN_CASE(JSOP_LAMBDA)
           {
             JSFunction *fun = script->getFunction(fullAtomIndex(PC));
             prepareStubCall(Uses(0));
             masm.move(ImmPtr(fun), Registers::ArgReg1);
-            stubCall(stubs::Lambda);
+
+            JSOp next = JSOp(PC[JSOP_LAMBDA_LENGTH]);
+            if (next == JSOP_INITMETHOD)
+                stubCall(stubs::LambdaForInit);
+            else
+                stubCall(stubs::Lambda);
             frame.takeReg(Registers::ReturnReg);
             frame.pushTypedPayload(JSVAL_TYPE_OBJECT, Registers::ReturnReg);
           }
           END_CASE(JSOP_LAMBDA)
 
           BEGIN_CASE(JSOP_TRY)
           END_CASE(JSOP_TRY)
 
--- a/js/src/methodjit/StubCalls.cpp
+++ b/js/src/methodjit/StubCalls.cpp
@@ -1508,16 +1508,40 @@ stubs::RegExp(VMFrame &f, JSObject *rege
     JS_ASSERT(proto);
     JSObject *obj = js_CloneRegExpObject(f.cx, regex, proto);
     if (!obj)
         THROWV(NULL);
     return obj;
 }
 
 JSObject * JS_FASTCALL
+stubs::LambdaForInit(VMFrame &f, JSFunction *fun)
+{
+    JSObject *obj = FUN_OBJECT(fun);
+
+    JSObject *parent;
+    if (FUN_NULL_CLOSURE(fun)) {
+        parent = f.fp->scopeChain;
+
+        if (obj->getParent() == parent)
+            return obj;
+    } else {
+        parent = js_GetScopeChain(f.cx, f.fp);
+        if (!parent)
+            THROWV(NULL);
+    }
+
+    obj = CloneFunctionObject(f.cx, fun, parent);
+    if (!obj)
+        THROWV(NULL);
+
+    return obj;
+}
+
+JSObject * JS_FASTCALL
 stubs::Lambda(VMFrame &f, JSFunction *fun)
 {
     JSObject *obj = FUN_OBJECT(fun);
 
     JSObject *parent;
     if (FUN_NULL_CLOSURE(fun)) {
         parent = f.fp->scopeChain;
     } else {
--- a/js/src/methodjit/StubCalls.h
+++ b/js/src/methodjit/StubCalls.h
@@ -104,16 +104,17 @@ void JS_FASTCALL IncElem(VMFrame &f);
 void JS_FASTCALL DecElem(VMFrame &f);
 void JS_FASTCALL CallProp(VMFrame &f, JSAtom *atom);
 
 void JS_FASTCALL DefFun(VMFrame &f, uint32 index);
 JSObject * JS_FASTCALL DefLocalFun(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL DefLocalFun_FC(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL RegExp(VMFrame &f, JSObject *regex);
 JSObject * JS_FASTCALL Lambda(VMFrame &f, JSFunction *fun);
+JSObject * JS_FASTCALL LambdaForInit(VMFrame &f, JSFunction *fun);
 JSObject * JS_FASTCALL FlatLambda(VMFrame &f, JSFunction *fun);
 void JS_FASTCALL Arguments(VMFrame &f);
 void JS_FASTCALL ArgSub(VMFrame &f, uint32 n);
 void JS_FASTCALL EnterBlock(VMFrame &f, JSObject *obj);
 void JS_FASTCALL LeaveBlock(VMFrame &f);
 
 void JS_FASTCALL VpInc(VMFrame &f, Value *vp);
 void JS_FASTCALL VpDec(VMFrame &f, Value *vp);