Register allocation

This commit is contained in:
Pekka Enberg
2023-09-02 08:52:30 +03:00
parent fa51955b43
commit 6e748a066e
2 changed files with 37 additions and 15 deletions

View File

@@ -50,8 +50,9 @@ impl Connection {
if let Some(cmd) = cmd {
match cmd {
Cmd::Stmt(stmt) => {
let mut program = vdbe::translate(&self.schema, stmt)?;
let mut state = vdbe::ProgramState::new(self.pager.clone());
let program = vdbe::translate(&self.schema, stmt)?;
let mut state =
vdbe::ProgramState::new(self.pager.clone(), program.max_registers);
loop {
let result = program.step(&mut state)?;
match result {
@@ -67,7 +68,7 @@ impl Connection {
}
}
}
Cmd::Explain(stmt) => {
Cmd::Explain(_stmt) => {
todo!();
}
Cmd::ExplainQueryPlan(_stmt) => todo!(),
@@ -89,7 +90,8 @@ impl Connection {
Cmd::ExplainQueryPlan(_stmt) => todo!(),
Cmd::Stmt(stmt) => {
let program = vdbe::translate(&self.schema, stmt)?;
let mut state = vdbe::ProgramState::new(self.pager.clone());
let mut state =
vdbe::ProgramState::new(self.pager.clone(), program.max_registers);
program.step(&mut state)?;
}
}

View File

@@ -83,12 +83,22 @@ pub enum Insn {
}
pub struct ProgramBuilder {
pub insns: Vec<Insn>,
next_free_register: usize,
insns: Vec<Insn>,
}
impl ProgramBuilder {
pub fn new() -> Self {
Self { insns: Vec::new() }
Self {
next_free_register: 0,
insns: Vec::new(),
}
}
pub fn alloc_register(&mut self) -> usize {
let reg = self.next_free_register;
self.next_free_register += 1;
reg
}
pub fn emit_placeholder(&mut self) -> usize {
@@ -110,7 +120,10 @@ impl ProgramBuilder {
}
pub fn build(self) -> Program {
Program { insns: self.insns }
Program {
max_registers: self.next_free_register,
insns: self.insns,
}
}
}
@@ -129,15 +142,24 @@ pub struct ProgramState {
}
impl ProgramState {
pub fn new(pager: Arc<Pager>) -> Self {
pub fn new(pager: Arc<Pager>, max_registers: usize) -> Self {
let cursors = HashMap::new();
let mut registers = Vec::new();
registers.resize(max_registers, None);
Self {
pc: 0,
cursors: HashMap::new(),
registers: Vec::new(),
cursors,
registers,
pager,
}
}
pub fn alloc_register(&mut self) -> usize {
let reg = self.registers.len();
self.registers.push(None);
reg
}
pub fn column_count(&self) -> usize {
self.registers.len()
}
@@ -148,6 +170,7 @@ impl ProgramState {
}
pub struct Program {
pub max_registers: usize,
pub insns: Vec<Insn>,
}
@@ -202,7 +225,6 @@ impl Program {
} => {
let cursor = state.cursors.get_mut(cursor_id).unwrap();
if let Some(ref record) = *cursor.record()? {
state.registers.resize(*column + 1, None);
state.registers[*dest] = Some(record.values[*column].clone());
} else {
todo!();
@@ -241,7 +263,6 @@ impl Program {
state.pc = *target_pc;
}
Insn::Integer { value, dest } => {
state.registers.resize(*dest + 1, None);
state.registers[*dest] = Some(Value::Integer(*value));
state.pc += 1;
}
@@ -347,7 +368,6 @@ fn translate_columns(
table: Option<&crate::schema::Table>,
columns: Vec<sqlite3_parser::ast::ResultColumn>,
) {
let mut dest = 0;
for col in columns {
match col {
sqlite3_parser::ast::ResultColumn::Expr(expr, _) => match expr {
@@ -393,11 +413,11 @@ fn translate_columns(
} => todo!(),
sqlite3_parser::ast::Expr::Literal(lit) => match lit {
sqlite3_parser::ast::Literal::Numeric(val) => {
let dest = program.alloc_register();
program.emit_insn(Insn::Integer {
value: val.parse().unwrap(),
dest,
});
dest += 1;
}
sqlite3_parser::ast::Literal::String(_) => todo!(),
sqlite3_parser::ast::Literal::Blob(_) => todo!(),
@@ -418,12 +438,12 @@ fn translate_columns(
},
sqlite3_parser::ast::ResultColumn::Star => {
for i in 0..table.unwrap().columns.len() {
let dest = program.alloc_register();
program.emit_insn(Insn::Column {
column: i,
dest,
cursor_id: cursor_id.unwrap(),
});
dest += 1;
}
}
sqlite3_parser::ast::ResultColumn::TableStar(_) => todo!(),