Bug 798665 - Inline TestCompile into IonCompile (r=dvander)
authorLuke Wagner <luke@mozilla.com>
Fri, 05 Oct 2012 22:15:33 -0700
changeset 109688 a030cb827aa09b5a4ace4bea73ab2630d2367a55
parent 109687 65ab678f3ea20bab3e5e1edfe180718323c68f8c
child 109689 055d18bfa16906a6a801e79f35f3b12a4462b4b6
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersdvander
bugs798665
milestone18.0a1
Bug 798665 - Inline TestCompile into IonCompile (r=dvander)
js/src/ion/Ion.cpp
--- a/js/src/ion/Ion.cpp
+++ b/js/src/ion/Ion.cpp
@@ -901,53 +901,16 @@ class AutoDestroyAllocator
 
     ~AutoDestroyAllocator()
     {
         if (alloc)
             js_delete(alloc);
     }
 };
 
-bool
-TestCompiler(IonBuilder *builder, MIRGraph *graph, AutoDestroyAllocator &autoDestroy)
-{
-    JS_ASSERT(!builder->script()->ion);
-    JSContext *cx = GetIonContext()->cx;
-
-    IonSpewNewFunction(graph, builder->script());
-
-    if (!builder->build())
-        return false;
-    builder->clearForBackEnd();
-
-    if (js_IonOptions.parallelCompilation) {
-        builder->script()->ion = ION_COMPILING_SCRIPT;
-
-        if (!StartOffThreadIonCompile(cx, builder))
-            return false;
-
-        // The allocator and associated data will be destroyed after being
-        // processed in the finishedOffThreadCompilations list.
-        autoDestroy.cancel();
-
-        return true;
-    }
-
-    if (!CompileBackEnd(builder))
-        return false;
-
-    CodeGenerator codegen(builder, *builder->lir);
-    if (!codegen.generate())
-        return false;
-
-    IonSpewEndFunction();
-
-    return true;
-}
-
 void
 AttachFinishedCompilations(JSContext *cx)
 {
     IonCompartment *ion = cx->compartment->ionCompartment();
     if (!ion)
         return;
 
     AutoLockWorkerThreadState lock(cx->runtime);
@@ -990,17 +953,16 @@ AttachFinishedCompilations(JSContext *cx
         FinishOffThreadBuilder(builder);
     }
 
     compilations.clear();
 }
 
 static const size_t BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
 
-template <bool Compiler(IonBuilder *, MIRGraph *, AutoDestroyAllocator &)>
 static bool
 IonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing)
 {
 #if JS_TRACE_LOGGING
     AutoTraceLog logger(TraceLogging::defaultLogger(),
                         TraceLogging::ION_COMPILE_START,
                         TraceLogging::ION_COMPILE_STOP,
                         script);
@@ -1035,28 +997,61 @@ IonCompile(JSContext *cx, JSScript *scri
     AutoFlushCache afc("IonCompile");
 
     types::AutoEnterCompilation enterCompiler(cx, types::AutoEnterCompilation::Ion);
     enterCompiler.init(script, false, 0);
 
     AutoTempAllocatorRooter root(cx, temp);
 
     IonBuilder *builder = alloc->new_<IonBuilder>(cx, temp, graph, &oracle, info);
-    if (!Compiler(builder, graph, autoDestroy)) {
-        IonSpew(IonSpew_Abort, "IM Compilation failed.");
+    JS_ASSERT(!builder->script()->ion);
+
+    IonSpewNewFunction(graph, builder->script());
+
+    if (!builder->build()) {
+        IonSpew(IonSpew_Abort, "Builder failed to build.");
         return false;
     }
+    builder->clearForBackEnd();
+
+    if (js_IonOptions.parallelCompilation) {
+        builder->script()->ion = ION_COMPILING_SCRIPT;
+
+        if (!StartOffThreadIonCompile(cx, builder)) {
+            IonSpew(IonSpew_Abort, "Unable to start off-thread ion compilation.");
+            return false;
+        }
+
+        // The allocator and associated data will be destroyed after being
+        // processed in the finishedOffThreadCompilations list.
+        autoDestroy.cancel();
+
+        return true;
+    }
+
+    if (!CompileBackEnd(builder)) {
+        IonSpew(IonSpew_Abort, "Failed during back-end compilation.");
+        return false;
+    }
+
+    CodeGenerator codegen(builder, *builder->lir);
+    if (!codegen.generate()) {
+        IonSpew(IonSpew_Abort, "Failed during code generation.");
+        return false;
+    }
+
+    IonSpewEndFunction();
 
     return true;
 }
 
 bool
 TestIonCompile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing)
 {
-    if (!IonCompile<TestCompiler>(cx, script, fun, osrPc, constructing)) {
+    if (!IonCompile(cx, script, fun, osrPc, constructing)) {
         if (!cx->isExceptionPending())
             ForbidCompilation(cx, script);
         return false;
     }
     return true;
 }
 
 static bool
@@ -1134,17 +1129,16 @@ CheckScriptSize(JSScript *script)
     if (numLocalsAndArgs > MAX_LOCALS_AND_ARGS) {
         IonSpew(IonSpew_Abort, "Too many locals and arguments (%u)", numLocalsAndArgs);
         return false;
     }
 
     return true;
 }
 
-template <bool Compiler(IonBuilder *, MIRGraph *, AutoDestroyAllocator &)>
 static MethodStatus
 Compile(JSContext *cx, JSScript *script, JSFunction *fun, jsbytecode *osrPc, bool constructing)
 {
     JS_ASSERT(ion::IsEnabled(cx));
     JS_ASSERT_IF(osrPc != NULL, (JSOp)*osrPc == JSOP_LOOPENTRY);
 
     if (cx->compartment->debugMode()) {
         IonSpew(IonSpew_Abort, "debugging");
@@ -1167,17 +1161,17 @@ Compile(JSContext *cx, JSScript *script,
         // bumping the use count twice.
         if (script->getUseCount() < js_IonOptions.usesBeforeCompile)
             return Method_Skipped;
     } else {
         if (script->incUseCount() < js_IonOptions.usesBeforeCompileNoJaeger)
             return Method_Skipped;
     }
 
-    if (!IonCompile<Compiler>(cx, script, fun, osrPc, constructing))
+    if (!IonCompile(cx, script, fun, osrPc, constructing))
         return Method_CantCompile;
 
     // Compilation succeeded, but we invalidated right away.
     return script->hasIonScript() ? Method_Compiled : Method_Skipped;
 }
 
 } // namespace ion
 } // namespace js
@@ -1209,17 +1203,17 @@ ion::CanEnterAtBranch(JSContext *cx, Han
     // Mark as forbidden if frame can't be handled.
     if (!CheckFrame(fp)) {
         ForbidCompilation(cx, script);
         return Method_CantCompile;
     }
 
     // Attempt compilation. Returns Method_Compiled if already compiled.
     JSFunction *fun = fp->isFunctionFrame() ? fp->fun() : NULL;
-    MethodStatus status = Compile<TestCompiler>(cx, script, fun, pc, false);
+    MethodStatus status = Compile(cx, script, fun, pc, false);
     if (status != Method_Compiled) {
         if (status == Method_CantCompile)
             ForbidCompilation(cx, script);
         return status;
     }
 
     if (script->ion->osrPc() != pc)
         return Method_Skipped;
@@ -1265,17 +1259,17 @@ ion::CanEnter(JSContext *cx, HandleScrip
     // Mark as forbidden if frame can't be handled.
     if (!CheckFrame(fp)) {
         ForbidCompilation(cx, script);
         return Method_CantCompile;
     }
 
     // Attempt compilation. Returns Method_Compiled if already compiled.
     JSFunction *fun = fp->isFunctionFrame() ? fp->fun() : NULL;
-    MethodStatus status = Compile<TestCompiler>(cx, script, fun, NULL, fp->isConstructing());
+    MethodStatus status = Compile(cx, script, fun, NULL, fp->isConstructing());
     if (status != Method_Compiled) {
         if (status == Method_CantCompile)
             ForbidCompilation(cx, script);
         return status;
     }
 
     // This can GC, so afterward, script->ion is not guaranteed to be valid.
     if (!cx->compartment->ionCompartment()->enterJIT(cx))