Skip to content

Commit 3068ded

Browse files
committed
perf(napi/parser, linter/plugins): shift before add when calculating positions in raw transfer deserializer (#21141)
Small perf optimization to raw transfer. When calculating a `u32` offset, shift first then add (`(pos >> 2) + 4`) instead of adding first (`(pos + 16) >> 2`). If a function contains multiple `pos >> 2` calculations, V8 may be able to combine them into a single calculation. Previously it couldn't prove that `pos` is a multiple of 4, so couldn't make this optimization.
1 parent eb400b8 commit 3068ded

13 files changed

Lines changed: 334 additions & 302 deletions

File tree

apps/oxlint/src-js/generated/deserialize.js

Lines changed: 28 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,9 +2268,10 @@ function deserializeFunctionType(pos) {
22682268
}
22692269

22702270
function deserializeFormalParameters(pos) {
2271-
let params = deserializeVecFormalParameter(pos + 16);
2272-
if (int32[(pos + 40) >> 2] !== 0 && int32[(pos + 44) >> 2] !== 0) {
2273-
pos = int32[(pos + 40) >> 2];
2271+
let params = deserializeVecFormalParameter(pos + 16),
2272+
restFieldPos32 = (pos >> 2) + 10;
2273+
if (int32[restFieldPos32] !== 0 && int32[restFieldPos32 + 1] !== 0) {
2274+
pos = int32[restFieldPos32];
22742275
let start,
22752276
end,
22762277
previousParent = parent,
@@ -2303,7 +2304,8 @@ function deserializeFormalParameters(pos) {
23032304
function deserializeFormalParameter(pos) {
23042305
let param,
23052306
previousParent = parent,
2306-
hasInitializer = int32[(pos + 64) >> 2] !== 0 && int32[(pos + 68) >> 2] !== 0;
2307+
initializerFieldPos32 = (pos >> 2) + 16,
2308+
hasInitializer = int32[initializerFieldPos32] !== 0 && int32[initializerFieldPos32 + 1] !== 0;
23072309
{
23082310
let accessibility = deserializeOptionTSAccessibility(pos + 13),
23092311
readonly = deserializeBool(pos + 14),
@@ -3180,7 +3182,7 @@ function deserializeNumericLiteral(pos) {
31803182
type: "Literal",
31813183
value: deserializeF64(pos + 32),
31823184
raw:
3183-
int32[(pos + 16) >> 2] === 0 && int32[(pos + 20) >> 2] === 0
3185+
int32[(pos >> 2) + 4] === 0 && int32[(pos >> 2) + 5] === 0
31843186
? null
31853187
: sourceText.slice(start, end),
31863188
start,
@@ -3199,7 +3201,7 @@ function deserializeStringLiteral(pos) {
31993201
type: "Literal",
32003202
value: null,
32013203
raw:
3202-
int32[(pos + 32) >> 2] === 0 && int32[(pos + 36) >> 2] === 0
3204+
int32[(pos >> 2) + 8] === 0 && int32[(pos >> 2) + 9] === 0
32033205
? null
32043206
: sourceText.slice(start, end),
32053207
start,
@@ -3224,7 +3226,7 @@ function deserializeBigIntLiteral(pos) {
32243226
type: "Literal",
32253227
value: BigInt(bigint),
32263228
raw:
3227-
int32[(pos + 32) >> 2] === 0 && int32[(pos + 36) >> 2] === 0
3229+
int32[(pos >> 2) + 8] === 0 && int32[(pos >> 2) + 9] === 0
32283230
? null
32293231
: sourceText.slice(start, end),
32303232
bigint,
@@ -3244,7 +3246,7 @@ function deserializeRegExpLiteral(pos) {
32443246
type: "Literal",
32453247
value: null,
32463248
raw:
3247-
int32[(pos + 48) >> 2] === 0 && int32[(pos + 52) >> 2] === 0
3249+
int32[(pos >> 2) + 12] === 0 && int32[(pos >> 2) + 13] === 0
32483250
? null
32493251
: sourceText.slice(start, end),
32503252
regex: null,
@@ -3760,7 +3762,7 @@ function deserializeJSXText(pos) {
37603762
type: "JSXText",
37613763
value: deserializeStr(pos + 16),
37623764
raw:
3763-
int32[(pos + 32) >> 2] === 0 && int32[(pos + 36) >> 2] === 0
3765+
int32[(pos >> 2) + 8] === 0 && int32[(pos >> 2) + 9] === 0
37643766
? null
37653767
: sourceText.slice(start, end),
37663768
start,
@@ -6075,13 +6077,13 @@ function deserializeBoxTSTypeParameterInstantiation(pos) {
60756077
}
60766078

60776079
function deserializeOptionBoxTSTypeParameterInstantiation(pos) {
6078-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6080+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
60796081
? null
60806082
: deserializeBoxTSTypeParameterInstantiation(pos);
60816083
}
60826084

60836085
function deserializeOptionStr(pos) {
6084-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0 ? null : deserializeStr(pos);
6086+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0 ? null : deserializeStr(pos);
60856087
}
60866088

60876089
function deserializeBoxComputedMemberExpression(pos) {
@@ -6137,7 +6139,7 @@ function deserializeBoxAssignmentTargetRest(pos) {
61376139
}
61386140

61396141
function deserializeOptionBoxAssignmentTargetRest(pos) {
6140-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6142+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
61416143
? null
61426144
: deserializeBoxAssignmentTargetRest(pos);
61436145
}
@@ -6287,7 +6289,7 @@ function deserializeBoxTSTypeAnnotation(pos) {
62876289
}
62886290

62896291
function deserializeOptionBoxTSTypeAnnotation(pos) {
6290-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6292+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
62916293
? null
62926294
: deserializeBoxTSTypeAnnotation(pos);
62936295
}
@@ -6301,7 +6303,7 @@ function deserializeOptionForStatementInit(pos) {
63016303
}
63026304

63036305
function deserializeOptionLabelIdentifier(pos) {
6304-
return int32[(pos + 16) >> 2] === 0 && int32[(pos + 20) >> 2] === 0
6306+
return int32[(pos >> 2) + 4] === 0 && int32[(pos >> 2) + 5] === 0
63056307
? null
63066308
: deserializeLabelIdentifier(pos);
63076309
}
@@ -6323,13 +6325,13 @@ function deserializeBoxCatchClause(pos) {
63236325
}
63246326

63256327
function deserializeOptionBoxCatchClause(pos) {
6326-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6328+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
63276329
? null
63286330
: deserializeBoxCatchClause(pos);
63296331
}
63306332

63316333
function deserializeOptionBoxBlockStatement(pos) {
6332-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6334+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
63336335
? null
63346336
: deserializeBoxBlockStatement(pos);
63356337
}
@@ -6371,7 +6373,7 @@ function deserializeBoxBindingRestElement(pos) {
63716373
}
63726374

63736375
function deserializeOptionBoxBindingRestElement(pos) {
6374-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6376+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
63756377
? null
63766378
: deserializeBoxBindingRestElement(pos);
63776379
}
@@ -6393,7 +6395,7 @@ function deserializeVecOptionBindingPattern(pos) {
63936395
}
63946396

63956397
function deserializeOptionBindingIdentifier(pos) {
6396-
return int32[(pos + 16) >> 2] === 0 && int32[(pos + 20) >> 2] === 0
6398+
return int32[(pos >> 2) + 4] === 0 && int32[(pos >> 2) + 5] === 0
63976399
? null
63986400
: deserializeBindingIdentifier(pos);
63996401
}
@@ -6403,7 +6405,7 @@ function deserializeBoxTSTypeParameterDeclaration(pos) {
64036405
}
64046406

64056407
function deserializeOptionBoxTSTypeParameterDeclaration(pos) {
6406-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6408+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
64076409
? null
64086410
: deserializeBoxTSTypeParameterDeclaration(pos);
64096411
}
@@ -6413,7 +6415,7 @@ function deserializeBoxTSThisParameter(pos) {
64136415
}
64146416

64156417
function deserializeOptionBoxTSThisParameter(pos) {
6416-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6418+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
64176419
? null
64186420
: deserializeBoxTSThisParameter(pos);
64196421
}
@@ -6427,7 +6429,7 @@ function deserializeBoxFunctionBody(pos) {
64276429
}
64286430

64296431
function deserializeOptionBoxFunctionBody(pos) {
6430-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6432+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
64316433
? null
64326434
: deserializeBoxFunctionBody(pos);
64336435
}
@@ -6461,7 +6463,7 @@ function deserializeBoxExpression(pos) {
64616463
}
64626464

64636465
function deserializeOptionBoxExpression(pos) {
6464-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6466+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
64656467
? null
64666468
: deserializeBoxExpression(pos);
64676469
}
@@ -6559,7 +6561,7 @@ function deserializeVecImportDeclarationSpecifier(pos) {
65596561
}
65606562

65616563
function deserializeOptionVecImportDeclarationSpecifier(pos) {
6562-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6564+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
65636565
? null
65646566
: deserializeVecImportDeclarationSpecifier(pos);
65656567
}
@@ -6569,7 +6571,7 @@ function deserializeBoxWithClause(pos) {
65696571
}
65706572

65716573
function deserializeOptionBoxWithClause(pos) {
6572-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6574+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
65736575
? null
65746576
: deserializeBoxWithClause(pos);
65756577
}
@@ -6651,7 +6653,7 @@ function deserializeBoxJSXClosingElement(pos) {
66516653
}
66526654

66536655
function deserializeOptionBoxJSXClosingElement(pos) {
6654-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6656+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
66556657
? null
66566658
: deserializeBoxJSXClosingElement(pos);
66576659
}
@@ -6985,7 +6987,7 @@ function deserializeBoxTSTypeParameter(pos) {
69856987
}
69866988

69876989
function deserializeOptionBoxObjectExpression(pos) {
6988-
return int32[pos >> 2] === 0 && int32[(pos + 4) >> 2] === 0
6990+
return int32[pos >> 2] === 0 && int32[(pos >> 2) + 1] === 0
69896991
? null
69906992
: deserializeBoxObjectExpression(pos);
69916993
}

crates/oxc_ast/src/serialize/js.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,9 @@ impl ESTree for CatchParameterConverter<'_, '_> {
171171
ts_type = "ParamPattern[]",
172172
raw_deser = "
173173
const params = DESER[Vec<FormalParameter>](POS_OFFSET.items);
174-
if (int32[(POS_OFFSET.rest) >> 2] !== 0 && int32[(POS_OFFSET.rest + 4) >> 2] !== 0) {
175-
pos = int32[(POS_OFFSET.rest) >> 2];
174+
const restFieldPos32 = POS_OFFSET.rest >> 2;
175+
if (int32[restFieldPos32] !== 0 && int32[restFieldPos32 + 1] !== 0) {
176+
pos = int32[restFieldPos32];
176177
177178
let start, end;
178179
const previousParent = parent;
@@ -255,7 +256,8 @@ impl ESTree for FormalParameterRest<'_> {
255256
raw_deser = "
256257
let param;
257258
const previousParent = parent;
258-
const hasInitializer = int32[(POS_OFFSET.initializer) >> 2] !== 0 && int32[(POS_OFFSET.initializer + 4) >> 2] !== 0;
259+
const initializerFieldPos32 = POS_OFFSET.initializer >> 2;
260+
const hasInitializer = int32[initializerFieldPos32] !== 0 && int32[initializerFieldPos32 + 1] !== 0;
259261
260262
if (IS_TS) {
261263
const accessibility = DESER[Option<TSAccessibility>](POS_OFFSET.accessibility),

0 commit comments

Comments
 (0)