Skip to content

Commit 9e34964

Browse files
committed
Introduce fast_slice to avoid unnecessary memory write
1 parent e5c5faa commit 9e34964

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

crates/swc_common/src/input.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,35 @@ impl<'a> StringInput<'a> {
4444
self.iter.as_str()
4545
}
4646

47+
#[inline(always)]
48+
/// Compared to [StringInput::slice], this function doesn't set
49+
/// `self.last_pos = end` because in most cases this property has been
50+
/// satisfied but the compiler cannot optimize it.
51+
///
52+
/// Caution: This function should only be used internally and will be
53+
/// changed in the future.
54+
///
55+
/// # Safety
56+
/// - start should be less than or equal to end.
57+
/// - start and end should be in the valid range of input.
58+
pub unsafe fn fast_slice(&mut self, start: BytePos, end: BytePos) -> &'a str {
59+
debug_assert!(self.last_pos == end);
60+
61+
debug_assert!(start <= end, "Cannot slice {start:?}..{end:?}");
62+
let s = self.orig;
63+
64+
let start_idx = (start - self.orig_start).0 as usize;
65+
let end_idx = (end - self.orig_start).0 as usize;
66+
67+
debug_assert!(end_idx <= s.len());
68+
69+
let ret = unsafe { s.get_unchecked(start_idx..end_idx) };
70+
71+
self.iter = unsafe { s.get_unchecked(end_idx..) }.chars();
72+
73+
ret
74+
}
75+
4776
#[inline]
4877
pub fn bump_bytes(&mut self, n: usize) {
4978
unsafe {

crates/swc_ecma_parser/src/lexer/mod.rs

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,14 @@ impl<'a> Lexer<'a> {
142142
}
143143

144144
#[inline(always)]
145+
/// This function should be used to replace [Lexer::input_slice_and_move] if
146+
/// the `end` comes from [Lexer::cur_pos] or [Lexer::last_pos]
145147
unsafe fn input_slice(&mut self, start: BytePos, end: BytePos) -> &'a str {
148+
self.input.fast_slice(start, end)
149+
}
150+
151+
#[inline(always)]
152+
unsafe fn input_slice_and_move(&mut self, start: BytePos, end: BytePos) -> &'a str {
146153
self.input.slice(start, end)
147154
}
148155

@@ -638,7 +645,7 @@ impl<'a> Lexer<'a> {
638645
let end = self.input().end_pos();
639646

640647
if self.comments_buffer().is_some() {
641-
let s = unsafe { self.input_slice(slice_start, end) };
648+
let s = unsafe { self.input_slice_and_move(slice_start, end) };
642649
let cmt = swc_common::comments::Comment {
643650
kind: swc_common::comments::CommentKind::Line,
644651
span: Span::new_with_checked(start, end),
@@ -1045,7 +1052,7 @@ impl<'a> Lexer<'a> {
10451052
let lazy_integer = self.read_number_no_dot_as_str::<10>()?;
10461053
let s = unsafe {
10471054
// Safety: We got both start and end position from `self.input`
1048-
self.input_slice(lazy_integer.start, lazy_integer.end)
1055+
self.input_slice_and_move(lazy_integer.start, lazy_integer.end)
10491056
};
10501057

10511058
// legacy octal number is not allowed in bigint.
@@ -1157,7 +1164,7 @@ impl<'a> Lexer<'a> {
11571164
let raw = remove_underscore(raw, has_underscore);
11581165
raw.parse().expect("failed to parse float literal")
11591166
} else {
1160-
let s = unsafe { self.input_slice(lazy_integer.start, lazy_integer.end) };
1167+
let s = unsafe { self.input_slice_and_move(lazy_integer.start, lazy_integer.end) };
11611168
let s = remove_underscore(s, has_underscore);
11621169
parse_integer::<10>(&s)
11631170
};
@@ -1224,7 +1231,7 @@ impl<'a> Lexer<'a> {
12241231

12251232
let s = unsafe {
12261233
// Safety: We got both start and end position from `self.input`
1227-
self.input_slice(lazy_integer.start, lazy_integer.end)
1234+
self.input_slice_and_move(lazy_integer.start, lazy_integer.end)
12281235
};
12291236
if self.eat(b'n') {
12301237
let end = self.cur_pos();
@@ -1873,7 +1880,7 @@ impl<'a> Lexer<'a> {
18731880
let s = unsafe {
18741881
// Safety: start and end are valid position because we got them from
18751882
// `self.input`
1876-
self.input_slice(slice_start, start)
1883+
self.input_slice_and_move(slice_start, start)
18771884
};
18781885
buf.push_str(s);
18791886
unsafe {

0 commit comments

Comments
 (0)