Skip to content

Comments

feat(oxc_ast): add RegExpFlags bitflag for storing regex flags#32

Merged
Boshen merged 1 commit intomainfrom
regex-flag
Feb 21, 2023
Merged

feat(oxc_ast): add RegExpFlags bitflag for storing regex flags#32
Boshen merged 1 commit intomainfrom
regex-flag

Conversation

@Boshen
Copy link
Member

@Boshen Boshen commented Feb 21, 2023

This reduces TokenValue from 56 to 40 bytes, Token from 72 to 56 bytes.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 21, 2023

Parser Benchmark Results

group                    main                                   pr
-----                    ----                                   --
parser/babylon.max.js    1.01    147.8±4.31ms    69.9 MB/sec    1.00    146.8±4.79ms    70.4 MB/sec
parser/d3.js             1.00     18.4±0.49ms    29.6 MB/sec    1.00     18.5±0.47ms    29.5 MB/sec
parser/lodash.js         1.00      5.2±0.28ms    98.0 MB/sec    1.00      5.3±0.19ms    97.8 MB/sec
parser/pdf.js            1.02     10.7±0.37ms    37.5 MB/sec    1.00     10.5±0.29ms    38.1 MB/sec
parser/typescript.js     1.00    146.2±2.90ms    65.8 MB/sec    1.00    146.4±3.58ms    65.7 MB/sec

This reduces `TokenValue` from 56 to 40 bytes, `Token` from 72 to 56 bytes.
@Boshen Boshen merged commit f3a7d5a into main Feb 21, 2023
@Boshen Boshen deleted the regex-flag branch February 21, 2023 10:22
@Boshen Boshen mentioned this pull request Jan 3, 2024
Boshen added a commit that referenced this pull request Oct 7, 2025
Replace multi-function calls and multiple enum variant checks with simple range checks, reducing assembly instructions in hot paths.

## Changes

**`is_any_keyword()`**:
- Before: Called 4 separate functions (`is_reserved_keyword()`, `is_contextual_keyword()`, `is_strict_mode_contextual_keyword()`, `is_future_reserved_keyword()`) checking 70+ enum variants with early returns
- After: Single range check `Await..=Yield` since all keywords are contiguous in the enum

**`is_number()`**:
- Before: Matched 11 separate enum variants
- After: Single range check `Decimal..=HexBigInt` since all numeric literals are contiguous

## Assembly Impact

Multi-function approach generated **5 instructions** with complex bitmask setup:
```asm
mov   x8, #992
movk  x8, #992, lsl #16
movk  x8, #240, lsl #32
lsr   x8, x8, x0
and   w0, w8, #0x1
```

Range check generates **4 instructions** with simple arithmetic:
```asm
and   w8, w0, #0xff
sub   w8, w8, #5
cmp   w8, #39
cset  w0, lo
```

## Performance

- `is_any_keyword()` is called from `advance()` on **every single token**
- 20% fewer instructions (5 → 4)
- Simpler logic enables better branch prediction
- Eliminates complex constant loading

Added tests to verify enum layout assumptions remain valid.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Boshen added a commit that referenced this pull request Oct 7, 2025
Replace multi-function calls and multiple enum variant checks with simple range checks, reducing assembly instructions in hot paths.

## Changes

**`is_any_keyword()`**:
- Before: Called 4 separate functions (`is_reserved_keyword()`, `is_contextual_keyword()`, `is_strict_mode_contextual_keyword()`, `is_future_reserved_keyword()`) checking 70+ enum variants with early returns
- After: Single range check `Await..=Yield` since all keywords are contiguous in the enum

**`is_number()`**:
- Before: Matched 11 separate enum variants
- After: Single range check `Decimal..=HexBigInt` since all numeric literals are contiguous

## Assembly Impact

Multi-function approach generated **5 instructions** with complex bitmask setup:
```asm
mov   x8, #992
movk  x8, #992, lsl #16
movk  x8, #240, lsl #32
lsr   x8, x8, x0
and   w0, w8, #0x1
```

Range check generates **4 instructions** with simple arithmetic:
```asm
and   w8, w0, #0xff
sub   w8, w8, #5
cmp   w8, #39
cset  w0, lo
```

## Performance

- `is_any_keyword()` is called from `advance()` on **every single token**
- 20% fewer instructions (5 → 4)
- Simpler logic enables better branch prediction
- Eliminates complex constant loading

Added tests to verify enum layout assumptions remain valid.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
Boshen added a commit that referenced this pull request Oct 7, 2025
Replace multi-function calls and multiple enum variant checks with simple range checks, reducing assembly instructions in hot paths.

## Changes

**`is_any_keyword()`**:
- Before: Called 4 separate functions (`is_reserved_keyword()`, `is_contextual_keyword()`, `is_strict_mode_contextual_keyword()`, `is_future_reserved_keyword()`) checking 70+ enum variants with early returns
- After: Single range check `Await..=Yield` since all keywords are contiguous in the enum

**`is_number()`**:
- Before: Matched 11 separate enum variants
- After: Single range check `Decimal..=HexBigInt` since all numeric literals are contiguous

## Assembly Impact

Multi-function approach generated **5 instructions** with complex bitmask setup:
```asm
mov   x8, #992
movk  x8, #992, lsl #16
movk  x8, #240, lsl #32
lsr   x8, x8, x0
and   w0, w8, #0x1
```

Range check generates **4 instructions** with simple arithmetic:
```asm
and   w8, w0, #0xff
sub   w8, w8, #5
cmp   w8, #39
cset  w0, lo
```

## Performance

- `is_any_keyword()` is called from `advance()` on **every single token**
- 20% fewer instructions (5 → 4)
- Simpler logic enables better branch prediction
- Eliminates complex constant loading

Added tests to verify enum layout assumptions remain valid.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
graphite-app bot pushed a commit that referenced this pull request Oct 7, 2025
…14410)

## Summary

Replace multi-function calls and multiple enum variant checks with simple range checks, reducing assembly instructions in hot paths.

## Changes

### `is_any_keyword()`
**Before**: Called 4 separate functions checking 70+ enum variants:
- `is_reserved_keyword()` - 38 variants
- `is_contextual_keyword()` - 39 variants
- `is_strict_mode_contextual_keyword()` - 8 variants
- `is_future_reserved_keyword()` - 7 variants

**After**: Single range check `Await..=Yield` since all keywords are contiguous in the enum

### `is_number()`
**Before**: Matched 11 separate enum variants
**After**: Single range check `Decimal..=HexBigInt` since numeric literals are contiguous

## Assembly Analysis

### Before (with scattered checks)
```asm
mov   x8, #992              ; Load bitmask constant
movk  x8, #992, lsl #16     ; More bitmask setup
movk  x8, #240, lsl #32     ; Even more bitmask setup
lsr   x8, x8, x0            ; Shift by kind value
and   w0, w8, #0x1          ; Extract result bit
```
**5 instructions** with complex constant loading

### After (with range check)
```asm
and   w8, w0, #0xff         ; Extract byte
sub   w8, w8, #5            ; Subtract range start
cmp   w8, #39               ; Compare to range size
cset  w0, lo                ; Set result
```
**4 instructions** with simple arithmetic

## Performance Impact

- **20% fewer instructions** (5 → 4)
- **Simpler logic** = better CPU pipeline utilization
- **No complex constants** = smaller code size
- **Better branch prediction** with single comparison

This is particularly important because:
- `is_any_keyword()` is called from `advance()` on **every single token**
- This is one of the hottest code paths in the entire parser

## Testing

Added unit tests to verify that:
- All keywords remain contiguous in the enum (`Await..=Yield`)
- All numeric literals remain contiguous (`Decimal..=HexBigInt`)

These tests will catch any future enum reordering that would break the optimization.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Boshen added a commit that referenced this pull request Jan 18, 2026
Cache `ptr` and `chunk_start` fields directly in `Bump` struct to eliminate
pointer indirection through `ChunkFooter` in the allocation fast path.

Before (2 dependent loads):
```asm
ldr x9, [x0, #16]        ; Load footer ptr from Bump
ldr x8, [x9, #32]        ; Load ptr from footer (WAITS for x9!)
```

After (2 independent loads):
```asm
ldr x8, [x0]             ; Load ptr directly (offset 0)
ldr x9, [x0, #8]         ; Load chunk_start directly - PARALLEL!
```

This removes the data dependency between loads, allowing ARM to issue
both loads in parallel via out-of-order execution.

Changes:
- Add `ptr` and `chunk_start` cached fields to `Bump` struct
- Add `#[repr(C)]` to ensure field ordering for optimal cache access
- Update `try_alloc_layout_fast` to use direct field access
- Sync cached fields on slow path (new chunk allocation) and iteration
- Update helper methods to use cached ptr

Size impact: `Bump` grows from 24 to 40 bytes - acceptable tradeoff
for the hot path optimization.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant