Bug 819865 - Make the callee canonical in IonBuilder. r=jandem
authorNicolas B. Pierron <nicolas.b.pierron@mozilla.com>
Tue, 18 Dec 2012 05:57:29 -0800
changeset 125500 aec01763cb6b54241eb96878ee606b247ae215f9
parent 125499 2755715976f098c256bff5efe1ab544cbb8e5c77
child 125501 08e0e08620063d702eb363bd6d9afb943da67afe
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjandem
bugs819865
milestone20.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 819865 - Make the callee canonical in IonBuilder. r=jandem
js/src/ion/IonBuilder.cpp
js/src/ion/IonBuilder.h
js/src/ion/MIR.h
js/src/jit-test/tests/ion/bug819865.js
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -37,17 +37,18 @@ IonBuilder::IonBuilder(JSContext *cx, Te
     cx(cx),
     loopDepth_(loopDepth),
     callerResumePoint_(NULL),
     callerBuilder_(NULL),
     oracle(oracle),
     inliningDepth(inliningDepth),
     failedBoundsCheck_(info->script()->failedBoundsCheck),
     failedShapeGuard_(info->script()->failedShapeGuard),
-    lazyArguments_(NULL)
+    lazyArguments_(NULL),
+    callee_(NULL)
 {
     script_.init(info->script());
     pc = info->startPC();
 }
 
 void
 IonBuilder::clearForBackEnd()
 {
@@ -569,44 +570,50 @@ IonBuilder::initParameters()
     return true;
 }
 
 bool
 IonBuilder::initScopeChain()
 {
     MInstruction *scope = NULL;
 
+    // Add callee, it will be removed if it is not used by neither the scope
+    // chain nor the function body.
+    JSFunction *fun = info().fun();
+    if (fun) {
+        JS_ASSERT(!callee_);
+        callee_ = MCallee::New();
+        current->add(callee_);
+    }
+
     // If the script doesn't use the scopechain, then it's already initialized
     // from earlier.
     if (!script()->analysis()->usesScopeChain())
         return true;
 
     // The scope chain is only tracked in scripts that have NAME opcodes which
     // will try to access the scope. For other scripts, the scope instructions
     // will be held live by resume points and code will still be generated for
     // them, so just use a constant undefined value.
     if (!script()->compileAndGo)
         return abort("non-CNG global scripts are not supported");
 
-    if (JSFunction *fun = info().fun()) {
-        MCallee *callee = MCallee::New();
-        current->add(callee);
-
-        scope = MFunctionEnvironment::New(callee);
+    if (fun) {
+        scope = MFunctionEnvironment::New(callee_);
         current->add(scope);
 
         // This reproduce what is done in CallObject::createForFunction
         if (fun->isHeavyweight()) {
             if (fun->isNamedLambda()) {
-                scope = createDeclEnvObject(callee, scope);
+                scope = createDeclEnvObject(callee_, scope);
                 if (!scope)
                     return false;
             }
 
-            scope = createCallObject(callee, scope);
+            scope = createCallObject(callee_, scope);
             if (!scope)
                 return false;
         }
     } else {
         scope = MConstant::New(ObjectValue(script()->global()));
         current->add(scope);
     }
 
@@ -1029,22 +1036,19 @@ IonBuilder::inspectOpcode(JSOp op)
 
       case JSOP_NOT:
         return jsop_not();
 
       case JSOP_THIS:
         return jsop_this();
 
       case JSOP_CALLEE:
-      {
-        MCallee *callee = MCallee::New();
-        current->add(callee);
-        current->push(callee);
-        return callee;
-      }
+        JS_ASSERT(callee_);
+        current->push(callee_);
+        return true;
 
       case JSOP_GETPROP:
       case JSOP_CALLPROP:
       {
         RootedPropertyName name(cx, info().getAtom(pc)->asPropertyName());
         return jsop_getprop(name);
       }
 
--- a/js/src/ion/IonBuilder.h
+++ b/js/src/ion/IonBuilder.h
@@ -507,18 +507,21 @@ class IonBuilder : public MIRGenerator
     // True if script->failedBoundsCheck is set for the current script or
     // an outer script.
     bool failedBoundsCheck_;
 
     // True if script->failedShapeGuard is set for the current script or
     // an outer script.
     bool failedShapeGuard_;
 
-    // If this script can use a lazy arguments object, it wil be pre-created
+    // If this script can use a lazy arguments object, it will be pre-created
     // here.
     MInstruction *lazyArguments_;
+
+    // If the script use a callee, it will be retrieved in the first basic
+    // block.
+    MCallee *callee_;
 };
 
 } // namespace ion
 } // namespace js
 
 #endif // jsion_bytecode_analyzer_h__
-
--- a/js/src/ion/MIR.h
+++ b/js/src/ion/MIR.h
@@ -681,16 +681,17 @@ class MParameter : public MNullaryInstru
 };
 
 class MCallee : public MNullaryInstruction
 {
   public:
     MCallee()
     {
         setResultType(MIRType_Object);
+        setMovable();
     }
 
   public:
     INSTRUCTION_HEADER(Callee)
 
     bool congruentTo(MDefinition * const &ins) const {
         return congruentIfOperandsEqual(ins);
     }
new file mode 100644
--- /dev/null
+++ b/js/src/jit-test/tests/ion/bug819865.js
@@ -0,0 +1,2 @@
+(function x() (x == x))();
+