tor-browser

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

commit c08c3ea0df5664f6e1dae83b7b3d31c8f0176bf4
parent 73e0899365ed7e2fdb05860e1f60fb9c877f020d
Author: Jan de Mooij <jdemooij@mozilla.com>
Date:   Fri,  7 Nov 2025 06:54:20 +0000

Bug 1982378 part 1 - Improve entry point code in BytecodeRangeWithPosition. r=arai

This refactors the entry point code in `BytecodeRangeWithPosition`:
* Use an enum instead of two booleans.
* Move code into `updatePosition` instead of separate functions.
* Add some assertions for prologue bytecode ops.

This simplifies the next patch.

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

Diffstat:
Mjs/src/vm/BytecodeUtil-inl.h | 68++++++++++++++++++++++++++++++++++++++++----------------------------
1 file changed, 40 insertions(+), 28 deletions(-)

diff --git a/js/src/vm/BytecodeUtil-inl.h b/js/src/vm/BytecodeUtil-inl.h @@ -123,45 +123,26 @@ class BytecodeRangeWithPosition : private BytecodeRange { sn(script->notes()), snEnd(script->notesEnd()), snpc(script->code()), - isEntryPoint(false), + mainPC(script->main()), isBreakpoint(false), - seenStepSeparator(false), - wasArtifactEntryPoint(false) { + seenStepSeparator(false) { if (sn < snEnd) { snpc += sn->delta(); } updatePosition(); - while (frontPC() != script->main()) { + while (frontPC() != mainPC) { popFront(); } - - if (frontOpcode() != JSOp::JumpTarget) { - isEntryPoint = true; - } else { - wasArtifactEntryPoint = true; - } + MOZ_ASSERT(entryPointState != EntryPointState::NotEntryPoint); } void popFront() { BytecodeRange::popFront(); if (empty()) { - isEntryPoint = false; + entryPointState = EntryPointState::NotEntryPoint; } else { updatePosition(); } - - // The following conditions are handling artifacts introduced by the - // bytecode emitter, such that we do not add breakpoints on empty - // statements of the source code of the user. - if (wasArtifactEntryPoint) { - wasArtifactEntryPoint = false; - isEntryPoint = true; - } - - if (isEntryPoint && frontOpcode() == JSOp::JumpTarget) { - wasArtifactEntryPoint = isEntryPoint; - isEntryPoint = false; - } } uint32_t frontLineNumber() const { return lineno; } @@ -174,7 +155,9 @@ class BytecodeRangeWithPosition : private BytecodeRange { // implement the idea that the bytecode emitter should tell the // debugger exactly which offsets represent "interesting" (to the // user) places to stop. - bool frontIsEntryPoint() const { return isEntryPoint; } + bool frontIsEntryPoint() const { + return entryPointState == EntryPointState::EntryPoint; + } // Breakable points are explicitly marked by the emitter as locations where // the debugger may want to allow users to pause. @@ -229,7 +212,30 @@ class BytecodeRangeWithPosition : private BytecodeRange { } sn = *iter; - isEntryPoint = lastLinePC == frontPC(); + + // The current bytecode op is an entry point if it's the first op of the + // 'main' bytecode section or if it matches lastLinePC. + // + // If we're at a JSOp::JumpTarget op, we use ArtifactEntryPoint to mark the + // next op as entry point instead. This prevents adding breakpoints for + // empty statements in the JS code. + if (frontPC() == mainPC || frontPC() == lastLinePC || + entryPointState == EntryPointState::ArtifactEntryPoint) { + if (frontOpcode() == JSOp::JumpTarget) { + entryPointState = EntryPointState::ArtifactEntryPoint; + } else { + entryPointState = EntryPointState::EntryPoint; + } + } else { + entryPointState = EntryPointState::NotEntryPoint; + } + + // Ops in the prologue are never entry points or breakable locations. + if (frontPC() < mainPC) { + MOZ_ASSERT(!frontIsEntryPoint()); + MOZ_ASSERT(!frontIsBreakablePoint()); + MOZ_ASSERT(!frontIsBreakableStepPoint()); + } } uint32_t initialLine; @@ -243,10 +249,16 @@ class BytecodeRangeWithPosition : private BytecodeRange { const SrcNote* sn; const SrcNote* snEnd; jsbytecode* snpc; - bool isEntryPoint; + jsbytecode* mainPC; bool isBreakpoint; bool seenStepSeparator; - bool wasArtifactEntryPoint; + + enum class EntryPointState : uint8_t { + NotEntryPoint, + EntryPoint, + ArtifactEntryPoint + }; + EntryPointState entryPointState = EntryPointState::NotEntryPoint; }; } // namespace js