tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 7ae3c69ced08d60bc8664603a33c03c6ca126ba4
parent 23b0c4c449768f62d52310e79f7a977cb3c24364
Author: Hannes Verschore <hv1989@gmail.com>
Date:   Thu, 18 Dec 2025 16:07:13 +0000

Bug 1999828: Part 2 - Add additional stubfolding spew information. r=iain

Add Stubfolding-details logs to have more information about the folding.

Differential Revision: https://phabricator.services.mozilla.com/D274202

Diffstat:
Mjs/src/jit/JitSpewer.cpp | 5+++++
Mjs/src/jit/JitSpewer.h | 200++++++++++++++++++++++++++++++++++++++++---------------------------------------
Mjs/src/jit/StubFolding.cpp | 37+++++++++++++++++++++++++++++++++++++
3 files changed, 143 insertions(+), 99 deletions(-)

diff --git a/js/src/jit/JitSpewer.cpp b/js/src/jit/JitSpewer.cpp @@ -338,6 +338,8 @@ static void PrintHelpAndExit(int status = 0) { " gcbarriers Redundant GC barrier elimination\n" " loadkeys Loads used as property keys\n" " stubfolding CacheIR stub folding\n" + " stubfolding-details Same as stubfolding, but with spewing of stub " + "content.\n" " logs JSON visualization logging\n" " logs-sync Same as logs, but flushes between each pass (sync. " "compiled functions only).\n" @@ -446,6 +448,9 @@ void jit::CheckLogging() { EnableChannel(JitSpew_MarkLoadsUsedAsPropertyKeys); } else if (IsFlag(found, "stubfolding")) { EnableChannel(JitSpew_StubFolding); + } else if (IsFlag(found, "stubfolding-details")) { + EnableChannel(JitSpew_StubFolding); + EnableChannel(JitSpew_StubFoldingDetails); } else if (IsFlag(found, "logs")) { EnableIonDebugAsyncLogging(); } else if (IsFlag(found, "logs-sync")) { diff --git a/js/src/jit/JitSpewer.h b/js/src/jit/JitSpewer.h @@ -24,105 +24,107 @@ namespace js { namespace jit { // New channels may be added below. -#define JITSPEW_CHANNEL_LIST(_) \ - /* Information during sinking */ \ - _(Prune) \ - /* Information during escape analysis */ \ - _(Escape) \ - /* Information during alias analysis */ \ - _(Alias) \ - /* Information during alias analysis */ \ - _(AliasSummaries) \ - /* Information during GVN */ \ - _(GVN) \ - /* Information during sinking */ \ - _(Sink) \ - /* Information during Range analysis */ \ - _(Range) \ - /* Information during LICM */ \ - _(LICM) \ - /* Information during Branch Hinting */ \ - _(BranchHint) \ - /* Info about fold linear constants */ \ - _(FLAC) \ - /* Effective address analysis info */ \ - _(EAA) \ - /* Wasm Bounds Check Elimination */ \ - _(WasmBCE) \ - /* Information during regalloc */ \ - _(RegAlloc) \ - /* Information during inlining */ \ - _(Inlining) \ - /* Information during codegen */ \ - _(Codegen) \ - /* Debug info about safepoints */ \ - _(Safepoints) \ - /* Debug info about Pools*/ \ - _(Pools) \ - /* Profiling-related information */ \ - _(Profiling) \ - /* Debug info about the I$ */ \ - _(CacheFlush) \ - /* Info about redundant shape guards */ \ - _(RedundantShapeGuards) \ - /* Info about redundant GC barriers */ \ - _(RedundantGCBarriers) \ - /* Info about loads used as keys */ \ - _(MarkLoadsUsedAsPropertyKeys) \ - /* Output a list of MIR expressions */ \ - _(MIRExpressions) \ - /* Summary info about loop unrolling */ \ - _(Unroll) \ - /* Detailed info about loop unrolling */ \ - _(UnrollDetails) \ - /* Information about stub folding */ \ - _(StubFolding) \ - \ - /* BASELINE COMPILER SPEW */ \ - \ - /* Aborting Script Compilation. */ \ - _(BaselineAbort) \ - /* Script Compilation. */ \ - _(BaselineScripts) \ - /* Detailed op-specific spew. */ \ - _(BaselineOp) \ - /* Inline caches. */ \ - _(BaselineIC) \ - /* Inline cache fallbacks. */ \ - _(BaselineICFallback) \ - /* OSR from Baseline => Ion. */ \ - _(BaselineOSR) \ - /* Bailouts. */ \ - _(BaselineBailouts) \ - /* Debug Mode On Stack Recompile . */ \ - _(BaselineDebugModeOSR) \ - \ - /* ION COMPILER SPEW */ \ - \ - /* Used to abort SSA construction */ \ - _(IonAbort) \ - /* Information about compiled scripts */ \ - _(IonScripts) \ - /* Info about failing to log script */ \ - _(IonSyncLogs) \ - /* Information during MIR building */ \ - _(IonMIR) \ - /* Information during bailouts */ \ - _(IonBailouts) \ - /* Information during OSI */ \ - _(IonInvalidate) \ - /* Debug info about snapshots */ \ - _(IonSnapshots) \ - /* Generated inline cache stubs */ \ - _(IonIC) \ - \ - /* WARP SPEW */ \ - \ - /* Generated WarpSnapshots */ \ - _(WarpSnapshots) \ - /* CacheIR transpiler logging */ \ - _(WarpTranspiler) \ - /* Trial inlining for Warp */ \ +#define JITSPEW_CHANNEL_LIST(_) \ + /* Information during sinking */ \ + _(Prune) \ + /* Information during escape analysis */ \ + _(Escape) \ + /* Information during alias analysis */ \ + _(Alias) \ + /* Information during alias analysis */ \ + _(AliasSummaries) \ + /* Information during GVN */ \ + _(GVN) \ + /* Information during sinking */ \ + _(Sink) \ + /* Information during Range analysis */ \ + _(Range) \ + /* Information during LICM */ \ + _(LICM) \ + /* Information during Branch Hinting */ \ + _(BranchHint) \ + /* Info about fold linear constants */ \ + _(FLAC) \ + /* Effective address analysis info */ \ + _(EAA) \ + /* Wasm Bounds Check Elimination */ \ + _(WasmBCE) \ + /* Information during regalloc */ \ + _(RegAlloc) \ + /* Information during inlining */ \ + _(Inlining) \ + /* Information during codegen */ \ + _(Codegen) \ + /* Debug info about safepoints */ \ + _(Safepoints) \ + /* Debug info about Pools*/ \ + _(Pools) \ + /* Profiling-related information */ \ + _(Profiling) \ + /* Debug info about the I$ */ \ + _(CacheFlush) \ + /* Info about redundant shape guards */ \ + _(RedundantShapeGuards) \ + /* Info about redundant GC barriers */ \ + _(RedundantGCBarriers) \ + /* Info about loads used as keys */ \ + _(MarkLoadsUsedAsPropertyKeys) \ + /* Output a list of MIR expressions */ \ + _(MIRExpressions) \ + /* Summary info about loop unrolling */ \ + _(Unroll) \ + /* Detailed info about loop unrolling */ \ + _(UnrollDetails) \ + /* Information about stub folding */ \ + _(StubFolding) \ + /* Additional information about stub folding */ \ + _(StubFoldingDetails) \ + \ + /* BASELINE COMPILER SPEW */ \ + \ + /* Aborting Script Compilation. */ \ + _(BaselineAbort) \ + /* Script Compilation. */ \ + _(BaselineScripts) \ + /* Detailed op-specific spew. */ \ + _(BaselineOp) \ + /* Inline caches. */ \ + _(BaselineIC) \ + /* Inline cache fallbacks. */ \ + _(BaselineICFallback) \ + /* OSR from Baseline => Ion. */ \ + _(BaselineOSR) \ + /* Bailouts. */ \ + _(BaselineBailouts) \ + /* Debug Mode On Stack Recompile . */ \ + _(BaselineDebugModeOSR) \ + \ + /* ION COMPILER SPEW */ \ + \ + /* Used to abort SSA construction */ \ + _(IonAbort) \ + /* Information about compiled scripts */ \ + _(IonScripts) \ + /* Info about failing to log script */ \ + _(IonSyncLogs) \ + /* Information during MIR building */ \ + _(IonMIR) \ + /* Information during bailouts */ \ + _(IonBailouts) \ + /* Information during OSI */ \ + _(IonInvalidate) \ + /* Debug info about snapshots */ \ + _(IonSnapshots) \ + /* Generated inline cache stubs */ \ + _(IonIC) \ + \ + /* WARP SPEW */ \ + \ + /* Generated WarpSnapshots */ \ + _(WarpSnapshots) \ + /* CacheIR transpiler logging */ \ + _(WarpTranspiler) \ + /* Trial inlining for Warp */ \ _(WarpTrialInlining) enum JitSpewChannel { diff --git a/js/src/jit/StubFolding.cpp b/js/src/jit/StubFolding.cpp @@ -76,6 +76,25 @@ static bool TryFoldingGuardShapes(JSContext* cx, ICFallbackStub* fallback, return true; }; +#ifdef JS_JITSPEW + JitSpew(JitSpew_StubFolding, "Trying to fold stubs at offset %u @ %s:%u:%u", + fallback->pcOffset(), script->filename(), script->lineno(), + script->column().oneOriginValue()); + + if (JitSpewEnabled(JitSpew_StubFoldingDetails)) { + Fprinter& printer(JitSpewPrinter()); + uint32_t i = 0; + for (ICCacheIRStub* stub = firstStub; stub; stub = stub->nextCacheIR()) { + printer.printf("- stub %d (enteredCount: %d)\n", i, stub->enteredCount()); + ICCacheIRStub* cache_stub = stub->toCacheIRStub(); + + CacheIRReader reader(cache_stub->stubInfo()); + SpewCacheIROps(printer, " ", cache_stub->stubInfo()); + i++; + } + } +#endif + // Find the offset of the first Shape that differs. for (ICCacheIRStub* other = firstStub->nextCacheIR(); other; other = other->nextCacheIR()) { @@ -236,6 +255,12 @@ static bool TryFoldingGuardShapes(JSContext* cx, ICFallbackStub* fallback, if (!shapeSuccess) { // If the shape field that differed was not part of a GuardShape, // we can't fold these stubs together. + JitSpew(JitSpew_StubFolding, + "Foldable shape field at offset %u was not a GuardShape " + "(icScript: %p) with %zu shapes (%s:%u:%u)", + fallback->pcOffset(), icScript, shapeList.length(), + script->filename(), script->lineno(), + script->column().oneOriginValue()); return true; } @@ -256,6 +281,18 @@ static bool TryFoldingGuardShapes(JSContext* cx, ICFallbackStub* fallback, script->filename(), script->lineno(), script->column().oneOriginValue()); +#ifdef JS_JITSPEW + if (JitSpewEnabled(JitSpew_StubFoldingDetails)) { + ICStub* newEntryStub = icEntry->firstStub(); + ICCacheIRStub* newStub = newEntryStub->toCacheIRStub(); + + Fprinter& printer(JitSpewPrinter()); + printer.printf("- stub 0 (enteredCount: %d)\n", newStub->enteredCount()); + CacheIRReader reader(newStub->stubInfo()); + SpewCacheIROps(printer, " ", newStub->stubInfo()); + } +#endif + fallback->setMayHaveFoldedStub(); return true;