refactor: fuse isMatch bit and literal decode for the hot path
the dominant decode step for literal-heavy payloads is "a plain literal
follows a literal" (state < LIT_STATES). previously this ran as two
RangeDecoder method calls — decodeBit(isMatch) then decodeLiteralSymbol —
each loading this.range/this.code at entry and storing them at exit, so
the range-coder state round-tripped through fields between them.
add decodeIsMatchThenLiteralSymbol, which decodes the isMatch bit and (if
it is a literal) flows straight into the branchless literal loop with
range/code held in locals throughout. decode() takes this fused path only
for state < LIT_STATES and inlines the stateAfterLiteral transition there;
the match-byte literal path (state >= LIT_STATES) and all match/rep
decoding are unchanged.
measured on the manga .7z corpus: aggregate ~21.1 -> ~22.4 MiB/s (+6%),
roughly +27% over the pre-optimization baseline. no new hot-path deopts.