1331414: Adding javascript.options.jit.full_debug_checks in about:config for people that want to use debug builds for surfing with less slowdown

1331414: Adding javascript.options.jit.full_debug_checks in about:config for people that want to use debug builds for surfing with less slowdown
This commit is contained in:
win7-7 2025-12-27 13:57:27 +02:00 committed by wuggy
commit d0736eaa44
11 changed files with 55 additions and 18 deletions

View file

@ -5291,8 +5291,10 @@ CodeGenerator::generateBody()
extendTrackedOptimizationsEntry(iter->mirRaw()->trackedOptimizations());
#ifdef DEBUG
if (!counts)
emitDebugResultChecks(*iter);
if (!counts) {
if (JitOptions.fullDebugChecks)
emitDebugResultChecks(*iter);
}
#endif
}
if (masm.oom())

View file

@ -1833,6 +1833,7 @@ OptimizeMIR(MIRGenerator* mir)
if (mir->shouldCancel("Make loops contiguous"))
return false;
}
AssertExtendedGraphCoherency(graph, /* underValueNumberer = */ false, /* force = */ true);
// Passes after this point must not move instructions; these analyses
// depend on knowing the final order in which instructions will execute.
@ -1875,6 +1876,8 @@ OptimizeMIR(MIRGenerator* mir)
gs.spewPass("Redundant Bounds Check Elimination");
AssertGraphCoherency(graph);
}
AssertGraphCoherency(graph, /* force = */ true);
DumpMIRExpressions(graph);
@ -1919,8 +1922,10 @@ GenerateLIR(MIRGenerator* mir)
case RegisterAllocator_Backtracking:
case RegisterAllocator_Testbed: {
#ifdef DEBUG
if (!integrity.record())
return nullptr;
if (JitOptions.fullDebugChecks) {
if (!integrity.record())
return nullptr;
}
#endif
BacktrackingAllocator regalloc(mir, &lirgen, *lir,
@ -1929,8 +1934,10 @@ GenerateLIR(MIRGenerator* mir)
return nullptr;
#ifdef DEBUG
if (!integrity.check(false))
return nullptr;
if (JitOptions.fullDebugChecks) {
if (!integrity.check(false))
return nullptr;
}
#endif
gs.spewPass("Allocate Registers [Backtracking]");

View file

@ -2407,9 +2407,12 @@ AssertOperandsBeforeSafeInsertTop(MResumePoint* resume)
#endif // DEBUG
void
jit::AssertBasicGraphCoherency(MIRGraph& graph)
jit::AssertBasicGraphCoherency(MIRGraph& graph, bool force)
{
#ifdef DEBUG
if (!JitOptions.fullDebugChecks && !force)
return;
MOZ_ASSERT(graph.entryBlock()->numPredecessors() == 0);
MOZ_ASSERT(graph.entryBlock()->phisEmpty());
MOZ_ASSERT(!graph.entryBlock()->unreachable());
@ -2592,12 +2595,14 @@ AssertDominatorTree(MIRGraph& graph)
#endif
void
jit::AssertGraphCoherency(MIRGraph& graph)
jit::AssertGraphCoherency(MIRGraph& graph, bool force)
{
#ifdef DEBUG
if (!JitOptions.checkGraphConsistency)
return;
AssertBasicGraphCoherency(graph);
if (!JitOptions.fullDebugChecks && !force)
return;
AssertBasicGraphCoherency(graph, force);
AssertReversePostorder(graph);
#endif
}
@ -2682,7 +2687,7 @@ AssertResumePointDominatedByOperands(MResumePoint* resume)
#endif // DEBUG
void
jit::AssertExtendedGraphCoherency(MIRGraph& graph, bool underValueNumberer)
jit::AssertExtendedGraphCoherency(MIRGraph& graph, bool underValueNumberer, bool force)
{
// Checks the basic GraphCoherency but also other conditions that
// do not hold immediately (such as the fact that critical edges
@ -2691,8 +2696,10 @@ jit::AssertExtendedGraphCoherency(MIRGraph& graph, bool underValueNumberer)
#ifdef DEBUG
if (!JitOptions.checkGraphConsistency)
return;
if (!JitOptions.fullDebugChecks && !force)
return;
AssertGraphCoherency(graph);
AssertGraphCoherency(graph, force);
AssertDominatorTree(graph);

View file

@ -78,13 +78,13 @@ MOZ_MUST_USE bool
BuildPhiReverseMapping(MIRGraph& graph);
void
AssertBasicGraphCoherency(MIRGraph& graph);
AssertBasicGraphCoherency(MIRGraph& graph, bool force = false);
void
AssertGraphCoherency(MIRGraph& graph);
AssertGraphCoherency(MIRGraph& graph, bool force = false);
void
AssertExtendedGraphCoherency(MIRGraph& graph, bool underValueNumberer = false);
AssertExtendedGraphCoherency(MIRGraph& graph, bool underValueNumberer = false, bool force = false);
MOZ_MUST_USE bool
EliminateRedundantChecks(MIRGraph& graph);

View file

@ -160,6 +160,9 @@ DefaultJitOptions::DefaultJitOptions()
// JSScript::hadFrequentBailouts and invalidate.
SET_DEFAULT(frequentBailoutThreshold, 10);
// Whether to run all debug checks in debug builds.
// Disabling might make it more enjoyable to run JS in debug builds.
SET_DEFAULT(fullDebugChecks, true);
// How many actual arguments are accepted on the C stack.
SET_DEFAULT(maxStackArgs, 4096);

View file

@ -66,6 +66,7 @@ struct DefaultJitOptions
bool disableSink;
bool eagerCompilation;
bool forceInlineCaches;
bool fullDebugChecks;
bool limitScriptSize;
bool osr;
bool asmJSAtomicsEnable;

View file

@ -299,7 +299,7 @@ class MNode : public TempObject
protected:
// Need visibility on getUseFor to avoid O(n^2) complexity.
friend void AssertBasicGraphCoherency(MIRGraph& graph);
friend void AssertBasicGraphCoherency(MIRGraph& graph, bool force);
// Gets the MUse corresponding to given operand.
virtual MUse* getUseFor(size_t index) = 0;
@ -11905,7 +11905,7 @@ class MResumePoint final :
private:
friend class MBasicBlock;
friend void AssertBasicGraphCoherency(MIRGraph& graph);
friend void AssertBasicGraphCoherency(MIRGraph& graph, bool force);
// List of stack slots needed to reconstruct the frame corresponding to the
// function which is compiled by IonBuilder.

View file

@ -7119,6 +7119,11 @@ JS_SetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t v
case JSJITCOMPILER_ION_INLINING:
jit::JitOptions.disableInlining = !value;
break;
#ifdef DEBUG
case JSJITCOMPILER_FULL_DEBUG_CHECKS:
jit::JitOptions.fullDebugChecks = !!value;
break;
#endif
default:
break;
}
@ -7166,6 +7171,11 @@ JS_GetGlobalJitCompilerOption(JSContext* cx, JSJitCompilerOption opt, uint32_t*
case JSJITCOMPILER_ION_INTERRUPT_WITHOUT_SIGNAL:
*valueOut = jit::JitOptions.ionInterruptWithoutSignals ? 1 : 0;
break;
#ifdef DEBUG
case JSJITCOMPILER_FULL_DEBUG_CHECKS:
*valueOut = jit::JitOptions.fullDebugChecks ? 1 : 0;
break;
#endif
default:
return false;
}

View file

@ -5316,7 +5316,8 @@ JS_SetOffthreadIonCompilationEnabled(JSContext* cx, bool enabled);
Register(ION_INTERRUPT_WITHOUT_SIGNAL, "ion.interrupt-without-signals") \
Register(ION_CHECK_RANGE_ANALYSIS, "ion.check-range-analysis") \
Register(BASELINE_ENABLE, "baseline.enable") \
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
Register(OFFTHREAD_COMPILATION_ENABLE, "offthread-compilation.enable") \
Register(FULL_DEBUG_CHECKS, "jit.full-debug-checks") \
Register(JUMP_THRESHOLD, "jump-threshold") \
Register(UNBOXED_OBJECTS, "unboxed_objects") \
Register(ASMJS_ATOMICS_ENABLE, "asmjs.atomics.enable") \

View file

@ -1492,7 +1492,10 @@ ReloadPrefsCallback(const char* pref, void* data)
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_BASELINE_WARMUP_TRIGGER,
baselineWarmUpThreshold);
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_WARMUP_TRIGGER,
ionWarmUpThreshold);
useIonEager ? 0 : ionThreshold);
#ifdef DEBUG
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_FULL_DEBUG_CHECKS, fullJitDebugChecks);
#endif
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_UNBOXED_OBJECTS,
unboxedObjects);
JS_SetGlobalJitCompilerOption(cx, JSJITCOMPILER_ION_INLINING,

View file

@ -1285,6 +1285,9 @@ pref("javascript.options.parallel_parsing", true);
pref("javascript.options.asyncstack", false);
pref("javascript.options.throw_on_asmjs_validation_failure", false);
pref("javascript.options.ion.offthread_compilation", true);
#ifdef DEBUG
pref("javascript.options.jit.full_debug_checks", true);
#endif
// This preference instructs the JS engine to discard the
// source of any privileged JS after compilation. This saves
// memory, but makes things like Function.prototype.toSource()