Bug 853394 follow-up - Ensure original script is compiled too for callsite clones. r=bhackett on IRC
authorJan de Mooij <jdemooij@mozilla.com>
Fri, 22 Mar 2013 14:17:02 +0100
changeset 127437 d4656be592193788b86288abab6fbdf73c4aca3a
parent 127436 d34e3717e819724fcc0f5f2579530e74ab377dde
child 127438 0eaefffce290dd72593e4e6048c1a23b0d0b4774
child 127440 492e87516012a79a258cd6b40c6872510406f1ee
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbhackett
bugs853394
milestone22.0a1
Bug 853394 follow-up - Ensure original script is compiled too for callsite clones. r=bhackett on IRC
js/src/ion/BaselineJIT.cpp
js/src/ion/IonBuilder.cpp
--- a/js/src/ion/BaselineJIT.cpp
+++ b/js/src/ion/BaselineJIT.cpp
@@ -190,17 +190,17 @@ ion::EnterBaselineAtBranch(JSContext *cx
     // for the current op.
     if (cx->compartment->debugMode())
         jitcode += MacroAssembler::ToggledCallSize();
 
     return EnterBaseline(cx, fp, jitcode, /* osr = */true);
 }
 
 static MethodStatus
-BaselineCompile(JSContext *cx, HandleScript script, StackFrame *fp)
+BaselineCompile(JSContext *cx, HandleScript script)
 {
     JS_ASSERT(!script->baseline);
 
     LifoAlloc alloc(BASELINE_LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
 
     TempAllocator *temp = alloc.new_<TempAllocator>(&alloc);
     if (!temp)
         return Method_Error;
@@ -256,17 +256,33 @@ ion::CanEnterBaselineJIT(JSContext *cx, 
     if (script->hasBaselineScript())
         return Method_Compiled;
 
     // Eagerly compile scripts if JSD is enabled, so that we don't have to OSR
     // and don't have to update the frame pointer stored in JSD's frames list.
     if (scriptArg->incUseCount() <= js_IonOptions.baselineUsesBeforeCompile && !IsJSDEnabled(cx))
         return Method_Skipped;
 
-    return BaselineCompile(cx, script, fp);
+    if (script->isCallsiteClone) {
+        // Ensure the original function is compiled too, so that bailouts from
+        // Ion code have a BaselineScript to resume into.
+        RootedScript original(cx, script->originalFunction()->nonLazyScript());
+        JS_ASSERT(original != script);
+
+        if (original->baseline == BASELINE_DISABLED_SCRIPT)
+            return Method_CantCompile;
+
+        if (!original->hasBaselineScript()) {
+            MethodStatus status = BaselineCompile(cx, original);
+            if (status != Method_Compiled)
+                return status;
+        }
+    }
+
+    return BaselineCompile(cx, script);
 }
 
 // Be safe, align IC entry list to 8 in all cases.
 static const unsigned DataAlignment = sizeof(uintptr_t);
 
 BaselineScript *
 BaselineScript::New(JSContext *cx, uint32_t prologueOffset, size_t icEntries,
                     size_t pcMappingIndexEntries, size_t pcMappingSize)
--- a/js/src/ion/IonBuilder.cpp
+++ b/js/src/ion/IonBuilder.cpp
@@ -203,17 +203,20 @@ IonBuilder::canInlineTarget(JSFunction *
     RootedScript inlineScript(cx, target->nonLazyScript());
     ExecutionMode executionMode = info().executionMode();
     if (!CanIonCompile(inlineScript, executionMode)) {
         IonSpew(IonSpew_Inlining, "Cannot inline due to disable Ion compilation");
         return false;
     }
 
     // Don't inline functions which don't have baseline scripts compiled for them.
-    if (executionMode == SequentialExecution && !inlineScript->hasBaselineScript()) {
+    if (executionMode == SequentialExecution &&
+        ion::IsBaselineEnabled(cx) &&
+        !inlineScript->hasBaselineScript())
+    {
         IonSpew(IonSpew_Inlining, "Cannot inline target with no baseline jitcode");
         return false;
     }
 
     // Allow inlining of recursive calls, but only one level deep.
     IonBuilder *builder = callerBuilder_;
     while (builder) {
         if (builder->script() == inlineScript) {