Skip to content

Commit 22e76f1

Browse files
committed
Use a boxed slice for codeobject fields
1 parent cd87f6d commit 22e76f1

File tree

3 files changed

+62
-48
lines changed

3 files changed

+62
-48
lines changed

bytecode/src/bytecode.rs

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ impl ConstantBag for BasicBag {
9393
/// a codeobject. Also a module has a codeobject.
9494
#[derive(Clone, PartialEq, Serialize, Deserialize)]
9595
pub struct CodeObject<C: Constant = ConstantData> {
96-
pub instructions: Vec<Instruction>,
97-
pub locations: Vec<Location>,
96+
pub instructions: Box<[Instruction]>,
97+
pub locations: Box<[Location]>,
9898
pub flags: CodeFlags,
9999
pub posonlyarg_count: usize, // Number of positional-only arguments
100100
pub arg_count: usize,
@@ -103,15 +103,15 @@ pub struct CodeObject<C: Constant = ConstantData> {
103103
pub first_line_number: usize,
104104
pub obj_name: String, // Name of the object that created this code object
105105
pub cell2arg: Option<Box<[isize]>>,
106-
pub constants: Vec<C>,
106+
pub constants: Box<[C]>,
107107
#[serde(bound(
108108
deserialize = "C::Name: serde::Deserialize<'de>",
109109
serialize = "C::Name: serde::Serialize"
110110
))]
111-
pub names: Vec<C::Name>,
112-
pub varnames: Vec<C::Name>,
113-
pub cellvars: Vec<C::Name>,
114-
pub freevars: Vec<C::Name>,
111+
pub names: Box<[C::Name]>,
112+
pub varnames: Box<[C::Name]>,
113+
pub cellvars: Box<[C::Name]>,
114+
pub freevars: Box<[C::Name]>,
115115
}
116116

117117
bitflags! {
@@ -129,12 +129,6 @@ bitflags! {
129129
}
130130
}
131131

132-
impl Default for CodeFlags {
133-
fn default() -> Self {
134-
Self::NEW_LOCALS
135-
}
136-
}
137-
138132
impl CodeFlags {
139133
pub const NAME_MAPPING: &'static [(&'static str, CodeFlags)] = &[
140134
("GENERATOR", CodeFlags::IS_GENERATOR),
@@ -542,8 +536,8 @@ impl<C: Constant> CodeObject<C> {
542536
obj_name: String,
543537
) -> Self {
544538
CodeObject {
545-
instructions: Vec::new(),
546-
locations: Vec::new(),
539+
instructions: Box::new([]),
540+
locations: Box::new([]),
547541
flags,
548542
posonlyarg_count,
549543
arg_count,
@@ -552,11 +546,11 @@ impl<C: Constant> CodeObject<C> {
552546
first_line_number,
553547
obj_name,
554548
cell2arg: None,
555-
constants: Vec::new(),
556-
names: Vec::new(),
557-
varnames: Vec::new(),
558-
cellvars: Vec::new(),
559-
freevars: Vec::new(),
549+
constants: Box::new([]),
550+
names: Box::new([]),
551+
varnames: Box::new([]),
552+
cellvars: Box::new([]),
553+
freevars: Box::new([]),
560554
}
561555
}
562556

@@ -593,7 +587,7 @@ impl<C: Constant> CodeObject<C> {
593587

594588
pub fn label_targets(&self) -> BTreeSet<Label> {
595589
let mut label_targets = BTreeSet::new();
596-
for instruction in &self.instructions {
590+
for instruction in &*self.instructions {
597591
match instruction {
598592
Jump { target: l }
599593
| JumpIfTrue { target: l }
@@ -675,15 +669,17 @@ impl<C: Constant> CodeObject<C> {
675669
}
676670

677671
pub fn map_bag<Bag: ConstantBag>(self, bag: &Bag) -> CodeObject<Bag::Constant> {
678-
let map_names = |names: Vec<C::Name>| {
672+
let map_names = |names: Box<[C::Name]>| {
679673
names
674+
.into_vec()
680675
.into_iter()
681676
.map(|x| bag.make_name_ref(x.as_ref()))
682-
.collect::<Vec<_>>()
677+
.collect::<Box<[_]>>()
683678
};
684679
CodeObject {
685680
constants: self
686681
.constants
682+
.into_vec()
687683
.into_iter()
688684
.map(|x| x.map_constant(bag))
689685
.collect(),
@@ -758,7 +754,7 @@ impl CodeObject<ConstantData> {
758754
impl<C: Constant> fmt::Display for CodeObject<C> {
759755
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
760756
self.display_inner(f, false, 1)?;
761-
for constant in &self.constants {
757+
for constant in &*self.constants {
762758
if let BorrowedConstant::Code { code } = constant.borrow_constant() {
763759
write!(f, "\nDisassembly of {:?}\n", code)?;
764760
code.fmt(f)?;
@@ -769,6 +765,7 @@ impl<C: Constant> fmt::Display for CodeObject<C> {
769765
}
770766

771767
impl Instruction {
768+
#[allow(clippy::too_many_arguments)]
772769
fn fmt_dis<C: Constant>(
773770
&self,
774771
f: &mut fmt::Formatter,

compiler/src/compile.rs

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ type CompileResult<T> = Result<T, CompileError>;
1818

1919
struct CodeInfo {
2020
code: CodeObject,
21+
instructions: Vec<Instruction>,
22+
locations: Vec<bytecode::Location>,
23+
constants: Vec<bytecode::ConstantData>,
2124
name_cache: IndexSet<String>,
2225
varname_cache: IndexSet<String>,
2326
cellvar_cache: IndexSet<String>,
@@ -28,17 +31,23 @@ impl CodeInfo {
2831
fn finalize_code(self) -> CodeObject {
2932
let CodeInfo {
3033
mut code,
34+
instructions,
35+
locations,
36+
constants,
3137
name_cache,
3238
varname_cache,
3339
cellvar_cache,
3440
freevar_cache,
3541
label_map,
3642
} = self;
3743

38-
code.names.extend(name_cache);
39-
code.varnames.extend(varname_cache);
40-
code.cellvars.extend(cellvar_cache);
41-
code.freevars.extend(freevar_cache);
44+
code.instructions = instructions.into();
45+
code.locations = locations.into();
46+
code.constants = constants.into();
47+
code.names = name_cache.into_iter().collect();
48+
code.varnames = varname_cache.into_iter().collect();
49+
code.cellvars = cellvar_cache.into_iter().collect();
50+
code.freevars = freevar_cache.into_iter().collect();
4251

4352
if !code.cellvars.is_empty() {
4453
let total_args = code.arg_count
@@ -65,7 +74,7 @@ impl CodeInfo {
6574
}
6675
}
6776

68-
for instruction in &mut code.instructions {
77+
for instruction in &mut *code.instructions {
6978
use Instruction::*;
7079
// this is a little bit hacky, as until now the data stored inside Labels in
7180
// Instructions is just bookkeeping, but I think it's the best way to do this
@@ -221,14 +230,17 @@ impl Compiler {
221230
fn new(opts: CompileOpts, source_path: String, code_name: String) -> Self {
222231
let module_code = CodeInfo {
223232
code: CodeObject::new(
224-
Default::default(),
233+
bytecode::CodeFlags::NEW_LOCALS,
225234
0,
226235
0,
227236
0,
228237
source_path.clone(),
229238
0,
230239
code_name,
231240
),
241+
instructions: Vec::new(),
242+
locations: Vec::new(),
243+
constants: Vec::new(),
232244
name_cache: IndexSet::new(),
233245
varname_cache: IndexSet::new(),
234246
cellvar_cache: IndexSet::new(),
@@ -287,6 +299,9 @@ impl Compiler {
287299

288300
let info = CodeInfo {
289301
code,
302+
instructions: Vec::new(),
303+
locations: Vec::new(),
304+
constants: Vec::new(),
290305
name_cache: IndexSet::new(),
291306
varname_cache: IndexSet::new(),
292307
cellvar_cache,
@@ -315,7 +330,7 @@ impl Compiler {
315330
name: &str,
316331
cache: impl FnOnce(&mut CodeInfo) -> &mut IndexSet<String>,
317332
) -> bytecode::NameIdx {
318-
let cache = cache(self.code_stack.last_mut().expect("nothing on stack"));
333+
let cache = cache(self.current_codeinfo());
319334
cache
320335
.get_index_of(name)
321336
.unwrap_or_else(|| cache.insert_full(name.to_owned()).0)
@@ -1160,7 +1175,7 @@ impl Compiler {
11601175

11611176
fn build_closure(&mut self, code: &CodeObject) {
11621177
if !code.freevars.is_empty() {
1163-
for var in &code.freevars {
1178+
for var in &*code.freevars {
11641179
let table = self.symbol_table_stack.last().unwrap();
11651180
let symbol = table.lookup(var).unwrap();
11661181
let parent_code = self.code_stack.last().unwrap();
@@ -2423,29 +2438,29 @@ impl Compiler {
24232438
fn emit(&mut self, instruction: Instruction) {
24242439
let location = compile_location(&self.current_source_location);
24252440
// TODO: insert source filename
2426-
let code = self.current_code();
2427-
code.instructions.push(instruction);
2428-
code.locations.push(location);
2441+
let info = self.current_codeinfo();
2442+
info.instructions.push(instruction);
2443+
info.locations.push(location);
24292444
}
24302445

24312446
fn emit_constant(&mut self, constant: bytecode::ConstantData) {
2432-
let code = self.current_code();
2433-
let idx = code.constants.len();
2434-
code.constants.push(constant);
2447+
let info = self.current_codeinfo();
2448+
let idx = info.constants.len();
2449+
info.constants.push(constant);
24352450
self.emit(Instruction::LoadConst { idx })
24362451
}
24372452

24382453
fn current_code(&mut self) -> &mut CodeObject {
2439-
&mut self
2440-
.code_stack
2441-
.last_mut()
2442-
.expect("No OutputStream on stack")
2443-
.code
2454+
&mut self.current_codeinfo().code
2455+
}
2456+
2457+
fn current_codeinfo(&mut self) -> &mut CodeInfo {
2458+
self.code_stack.last_mut().expect("no code on stack")
24442459
}
24452460

24462461
// Generate a new label
24472462
fn new_label(&mut self) -> Label {
2448-
let label_map = &mut self.code_stack.last_mut().unwrap().label_map;
2463+
let label_map = &mut self.current_codeinfo().label_map;
24492464
let label = Label(label_map.len());
24502465
label_map.push(None);
24512466
label
@@ -2454,9 +2469,11 @@ impl Compiler {
24542469
// Assign current position the given label
24552470
fn set_label(&mut self, label: Label) {
24562471
let CodeInfo {
2457-
code, label_map, ..
2458-
} = self.code_stack.last_mut().unwrap();
2459-
let actual_label = Label(code.instructions.len());
2472+
instructions,
2473+
label_map,
2474+
..
2475+
} = self.current_codeinfo();
2476+
let actual_label = Label(instructions.len());
24602477
let prev_val = std::mem::replace(&mut label_map[label.0], Some(actual_label));
24612478
debug_assert!(
24622479
prev_val.map_or(true, |x| x == actual_label),

vm/src/builtins/function.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ impl PyFunction {
204204
// Check if kw only arguments are all present:
205205
for (slot, kwarg) in fastlocals
206206
.iter_mut()
207-
.zip(&code.varnames)
207+
.zip(&*code.varnames)
208208
.skip(code.arg_count)
209209
.take(code.kwonlyarg_count)
210210
{

0 commit comments

Comments
 (0)