Bug 1505689 part 2 - Check for ION_DISABLED_SCRIPT in Baseline JIT code. r=tcampbell
authorJan de Mooij <jdemooij@mozilla.com>
Thu, 15 Aug 2019 16:12:37 +0000
changeset 488274 c437f2caa6d04b33e445d6defcb49a0b8e882e1b
parent 488273 b66c924e9a1fc5ed5613707b56d13894f0a46518
child 488275 515f936e0df687205b4c99fa0c4c0aba9e1d0dde
push id113906
push userncsoregi@mozilla.com
push dateFri, 16 Aug 2019 04:07:24 +0000
treeherdermozilla-inbound@d887276421d3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstcampbell
bugs1505689, 1324521
milestone70.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 1505689 part 2 - Check for ION_DISABLED_SCRIPT in Baseline JIT code. r=tcampbell This is more consistent with Baseline Interpreter -> Baseline JIT code and avoids calling into C++ repeatedly when we disable Ion compilation for the script after Baseline JIT compilation. The inIon fix prevents an iloop when running jit-test/tests/ion/bug1324521.js Differential Revision: https://phabricator.services.mozilla.com/D41574
js/src/builtin/TestingFunctions.cpp
js/src/jit-test/tests/ion/dce-with-rinstructions.js
js/src/jit/BaselineCodeGen.cpp
js/src/jit/Ion.cpp
--- a/js/src/builtin/TestingFunctions.cpp
+++ b/js/src/builtin/TestingFunctions.cpp
@@ -2846,16 +2846,18 @@ static bool testingFunc_inIon(JSContext*
   FrameIter iter(cx);
   MOZ_ASSERT(!iter.done());
 
   if (iter.hasScript()) {
     // Detect repeated attempts to compile, resetting the counter if inIon
     // succeeds. Note: This script may have be inlined into its caller.
     if (iter.isIon()) {
       iter.script()->resetWarmUpResetCounter();
+    } else if (!iter.script()->canIonCompile()) {
+      return ReturnStringCopy(cx, args, "Unable to Ion-compile this script.");
     } else if (iter.script()->getWarmUpResetCount() >= JitWarmupResetLimit) {
       return ReturnStringCopy(
           cx, args, "Compilation is being repeatedly prevented. Giving up.");
     }
   }
 
   args.rval().setBoolean(iter.isIon());
   return true;
--- a/js/src/jit-test/tests/ion/dce-with-rinstructions.js
+++ b/js/src/jit-test/tests/ion/dce-with-rinstructions.js
@@ -1,13 +1,16 @@
 setJitCompilerOption("baseline.warmup.trigger", 10);
 setJitCompilerOption("ion.warmup.trigger", 20);
 setJitCompilerOption("ion.full.warmup.trigger", 20);
 var i;
 
+// Prevent GC from cancelling/discarding Ion compilations.
+gczeal(0);
+
 var config = getBuildConfiguration();
 var max = 200;
 
 // Check that we are able to remove the operation inside recover test functions (denoted by "rop..."),
 // when we inline the first version of uceFault, and ensure that the bailout is correct
 // when uceFault is replaced (which cause an invalidation bailout)
 
 var uceFault = function (i) {
--- a/js/src/jit/BaselineCodeGen.cpp
+++ b/js/src/jit/BaselineCodeGen.cpp
@@ -1305,19 +1305,23 @@ bool BaselineCompilerCodeGen::emitWarmUp
   Label skipCall;
 
   const OptimizationInfo* info =
       IonOptimizations.get(IonOptimizations.firstLevel());
   uint32_t warmUpThreshold = info->compilerWarmUpThreshold(script, pc);
   masm.branch32(Assembler::LessThan, countReg, Imm32(warmUpThreshold),
                 &skipCall);
 
-  masm.branchPtr(Assembler::Equal,
-                 Address(scriptReg, JSScript::offsetOfIonScript()),
-                 ImmPtr(ION_COMPILING_SCRIPT), &skipCall);
+  // Do nothing if Ion is already compiling this script off-thread or if Ion has
+  // been disabled for this script.
+  masm.loadPtr(Address(scriptReg, JSScript::offsetOfIonScript()), scriptReg);
+  masm.branchPtr(Assembler::Equal, scriptReg, ImmPtr(ION_COMPILING_SCRIPT),
+                 &skipCall);
+  masm.branchPtr(Assembler::Equal, scriptReg, ImmPtr(ION_DISABLED_SCRIPT),
+                 &skipCall);
 
   // Try to compile and/or finish a compilation.
   if (JSOp(*pc) == JSOP_LOOPENTRY) {
     // During the loop entry we can try to OSR into ion.
     // The ic has logic for this.
     if (!emitNextIC()) {
       return false;
     }
--- a/js/src/jit/Ion.cpp
+++ b/js/src/jit/Ion.cpp
@@ -2378,34 +2378,25 @@ static MethodStatus BaselineCanEnterAtBr
     return Method_Skipped;
   }
 
   return Method_Compiled;
 }
 
 bool jit::IonCompileScriptForBaseline(JSContext* cx, BaselineFrame* frame,
                                       jsbytecode* pc) {
-  // A TI OOM will disable TI and Ion.
-  if (!jit::IsIonEnabled()) {
-    return true;
-  }
+  MOZ_ASSERT(IsIonEnabled());
 
   RootedScript script(cx, frame->script());
   bool isLoopEntry = JSOp(*pc) == JSOP_LOOPENTRY;
 
   MOZ_ASSERT(!isLoopEntry || LoopEntryCanIonOsr(pc));
 
-  if (!script->canIonCompile()) {
-    // TODO: ASSERT that ion-compilation-disabled checker stub doesn't exist.
-    // TODO: Clear all optimized stubs.
-    // TODO: Add a ion-compilation-disabled checker IC stub
-    script->resetWarmUpCounterToDelayIonCompilation();
-    return true;
-  }
-
+  // The Baseline JIT code checks for Ion disabled or compiling off-thread.
+  MOZ_ASSERT(script->canIonCompile());
   MOZ_ASSERT(!script->isIonCompilingOffThread());
 
   // If Ion script exists, but PC is not at a loop entry, then Ion will be
   // entered for this script at an appropriate LOOPENTRY or the next time this
   // function is called.
   if (script->hasIonScript() && !isLoopEntry) {
     JitSpew(JitSpew_BaselineOSR, "IonScript exists, but not at loop entry!");
     // TODO: ASSERT that a ion-script-already-exists checker stub doesn't exist.