Skip to content

Commit cc7aa5f

Browse files
committed
chore: better vtable fn gen logic
1 parent 22edbb3 commit cc7aa5f

File tree

10 files changed

+59
-201
lines changed

10 files changed

+59
-201
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,4 +52,4 @@ build/build.ninja
5252
Debug
5353
Release
5454
kagari/test_dir
55-
planglib/github.com
55+
planglib/thirdparty

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ dyn-fmt = "0.3.0"
3939
petgraph = "0.6.2"
4040
kagari = { path = "./kagari" }
4141
indicatif = "0.17"
42+
parking_lot = "0.12"
4243

4344
[dependencies.nom]
4445
version = "7"

immix/src/collector.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -311,19 +311,9 @@ impl Collector {
311311
/// it self does not mark the object, but mark the object's fields by calling
312312
/// mark_ptr
313313
unsafe fn mark_complex(&self, ptr: *mut u8) {
314-
// if !self.thread_local_allocator.as_mut().unwrap().in_heap(ptr)
315-
// &&!self.thread_local_allocator.as_mut().unwrap().in_big_heap(ptr) {
316-
// return;
317-
// }
318314
let vtable = *(ptr as *mut VtableFunc);
319-
// let ptr = vtable as *mut u8;
320-
let v = vtable as i64;
321-
// println!("vtable: {:?}, ptr : {:p}", v, ptr);
322-
// let a = *(ptr as *mut *mut u8);
323-
// println!("a: {:p}", a);
324-
// println!("vtable: {:?}, ptr : {:p}", v, ptr);
325-
// 我不知道为什么,vtable为0的情况,这里如果写v == 0,进不去这个if。应该是rust的一个bug
326-
if v < 1 && v > -1 {
315+
let vtable_ptr = vtable as *mut u8;
316+
if vtable_ptr.is_null() {
327317
return;
328318
}
329319
vtable(

src/ast/builder/llvmbuilder.rs

Lines changed: 35 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use inkwell::{
1515
debug_info::*,
1616
module::{FlagBehavior, Linkage, Module},
1717
targets::{InitializationConfig, Target, TargetMachine},
18-
types::{BasicType, BasicTypeEnum, FunctionType, StructType},
18+
types::{BasicType, BasicTypeEnum, FunctionType, PointerType, StructType},
1919
values::{
2020
AnyValue, AnyValueEnum, BasicMetadataValueEnum, BasicValue, BasicValueEnum, CallableValue,
2121
FunctionValue, PointerValue,
@@ -66,6 +66,14 @@ pub struct MemberType<'ctx> {
6666
pub ptr_depth: usize,
6767
}
6868

69+
fn get_nth_mark_fn<'ctx>(f: FunctionValue<'ctx>, n: u32) -> CallableValue<'ctx> {
70+
f.get_nth_param(n)
71+
.unwrap()
72+
.into_pointer_value()
73+
.try_into()
74+
.unwrap()
75+
}
76+
6977
pub fn create_llvm_deps<'ctx>(
7078
context: &'ctx Context,
7179
dir: &str,
@@ -305,18 +313,18 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
305313
nh
306314
}
307315

308-
fn gen_or_get_arr_visit_function(&self, ctx: &mut Ctx<'a>, v: &ARRType) -> FunctionValue<'ctx> {
309-
let currentbb = self.builder.get_insert_block();
310-
self.builder.unset_current_debug_location();
316+
fn visit_f_tp(&self) -> PointerType<'ctx> {
311317
let i8ptrtp = self.context.i8_type().ptr_type(AddressSpace::default());
312-
let visit_ftp = self
313-
.context
318+
self.context
314319
.void_type()
315320
.fn_type(&[i8ptrtp.into(), i8ptrtp.into()], false)
316-
.ptr_type(AddressSpace::default());
317-
let ptrtp = self.arr_type(v, ctx).ptr_type(AddressSpace::default());
318-
let ty = ptrtp.get_element_type().into_struct_type();
319-
let ftp = self.context.void_type().fn_type(
321+
.ptr_type(AddressSpace::default())
322+
}
323+
324+
fn mark_fn_tp(&self, ptrtp: PointerType<'ctx>) -> FunctionType<'ctx> {
325+
let i8ptrtp = self.context.i8_type().ptr_type(AddressSpace::default());
326+
let visit_ftp = self.visit_f_tp();
327+
self.context.void_type().fn_type(
320328
&[
321329
ptrtp.into(),
322330
i8ptrtp.into(),
@@ -325,7 +333,15 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
325333
visit_ftp.into(),
326334
],
327335
false,
328-
);
336+
)
337+
}
338+
339+
fn gen_or_get_arr_visit_function(&self, ctx: &mut Ctx<'a>, v: &ARRType) -> FunctionValue<'ctx> {
340+
let currentbb = self.builder.get_insert_block();
341+
self.builder.unset_current_debug_location();
342+
let ptrtp = self.arr_type(v, ctx).ptr_type(AddressSpace::default());
343+
let ty = ptrtp.get_element_type().into_struct_type();
344+
let ftp = self.mark_fn_tp(ptrtp);
329345
let arr_tp = ty.get_field_type_at_index(1).unwrap().into_array_type();
330346
let fname = &(arr_tp.to_string() + "@" + &ctx.plmod.path);
331347
if let Some(f) = self.module.get_function(fname) {
@@ -366,26 +382,11 @@ impl<'a, 'ctx> LLVMBuilder<'a, 'ctx> {
366382
)
367383
};
368384
let visitor = f.get_nth_param(1).unwrap().into_pointer_value();
369-
let visit_ptr_f: CallableValue = f
370-
.get_nth_param(2)
371-
.unwrap()
372-
.into_pointer_value()
373-
.try_into()
374-
.unwrap();
385+
let visit_ptr_f = get_nth_mark_fn(f, 2);
375386
// complex type needs to provide a visit function by itself
376387
// which is stored in the first field of the struct
377-
let visit_complex_f: CallableValue = f
378-
.get_nth_param(3)
379-
.unwrap()
380-
.into_pointer_value()
381-
.try_into()
382-
.unwrap();
383-
let visit_trait_f: CallableValue = f
384-
.get_nth_param(4)
385-
.unwrap()
386-
.into_pointer_value()
387-
.try_into()
388-
.unwrap();
388+
let visit_complex_f = get_nth_mark_fn(f, 3);
389+
let visit_trait_f = get_nth_mark_fn(f, 4);
389390
match &*v.element_type.borrow() {
390391
PLType::ARR(_) | PLType::STRUCT(_) => {
391392
// call the visit_complex function
@@ -980,90 +981,6 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
980981
self.get_llvm_value_handle(&self.get_or_insert_fn(pltp, ctx).as_any_value_enum())
981982
}
982983

983-
// fn mv2heap(&self, val: ValueHandle, ctx: &mut Ctx<'a>, tp: &PLType) -> ValueHandle {
984-
// if !ctx.usegc {
985-
// return val;
986-
// }
987-
// let val = self.get_llvm_value(val).unwrap();
988-
// let gcmod = ctx.plmod.submods.get("gc").unwrap();
989-
// let f: FNType = gcmod
990-
// .get_type("DioGC__malloc")
991-
// .unwrap()
992-
// .borrow()
993-
// .clone()
994-
// .try_into()
995-
// .unwrap();
996-
// let f = self.get_or_insert_fn(&f, ctx);
997-
// let td = self.targetmachine.get_target_data();
998-
// let loaded = self.builder.build_load(val.into_pointer_value(), "loaded");
999-
// let size = td.get_store_size(&loaded.get_type());
1000-
// let size = self.context.i64_type().const_int(size as u64, false);
1001-
// let tp = self
1002-
// .context
1003-
// .i8_type()
1004-
// .const_int(tp.get_immix_type().int_value() as u64, false);
1005-
// let heapptr = self
1006-
// .builder
1007-
// .build_call(f, &[size.into(), tp.into()], "gc_malloc")
1008-
// .try_as_basic_value()
1009-
// .left()
1010-
// .unwrap();
1011-
// let heapptr = self.builder.build_pointer_cast(
1012-
// heapptr.into_pointer_value(),
1013-
// val.get_type().into_pointer_type(),
1014-
// "heapptr",
1015-
// );
1016-
// self.builder.build_store(heapptr, loaded);
1017-
// self.get_llvm_value_handle(&heapptr.as_any_value_enum())
1018-
// }
1019-
// fn gc_rm_root(&self, stackptr: ValueHandle, ctx: &mut Ctx<'a>) {
1020-
// if !ctx.usegc {
1021-
// return;
1022-
// }
1023-
// self.builder.unset_current_debug_location();
1024-
// let block = self.builder.get_insert_block().unwrap();
1025-
// if let Some(inst) = block.get_first_instruction() {
1026-
// self.builder.position_before(&inst);
1027-
// }
1028-
// self.gc_rm_root_current(stackptr, ctx);
1029-
// }
1030-
// fn gc_rm_root_current(&self, stackptr: ValueHandle, ctx: &mut Ctx<'a>) {
1031-
// if !ctx.usegc {
1032-
// return;
1033-
// }
1034-
// let stackptr = self.get_llvm_value(stackptr).unwrap();
1035-
// let gcmod = ctx.plmod.submods.get("gc").unwrap();
1036-
// let f: FNType = gcmod
1037-
// .get_type("DioGC__rm_root")
1038-
// .unwrap()
1039-
// .borrow()
1040-
// .clone()
1041-
// .try_into()
1042-
// .unwrap();
1043-
// let f = self.get_or_insert_fn(&f, ctx);
1044-
// let stackptr = self.builder.build_pointer_cast(
1045-
// stackptr.into_pointer_value(),
1046-
// self.context.i64_type().ptr_type(AddressSpace::default()),
1047-
// "stackptr",
1048-
// );
1049-
// self.builder.build_call(f, &[stackptr.into()], "rm_root");
1050-
// }
1051-
// fn gc_collect(&self, ctx: &mut Ctx<'a>) {
1052-
// if !ctx.usegc {
1053-
// return;
1054-
// }
1055-
// self.builder.unset_current_debug_location();
1056-
// let gcmod = ctx.plmod.submods.get("gc").unwrap();
1057-
// let f: FNType = gcmod
1058-
// .get_type("DioGC__collect")
1059-
// .unwrap()
1060-
// .borrow()
1061-
// .clone()
1062-
// .try_into()
1063-
// .unwrap();
1064-
// let f = self.get_or_insert_fn(&f, ctx);
1065-
// self.builder.build_call(f, &[], "collect");
1066-
// }
1067984
fn get_or_add_global(
1068985
&self,
1069986
name: &str,
@@ -1711,26 +1628,7 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
17111628
global.set_metadata(exp.as_metadata_value(self.context), 0);
17121629
self.get_llvm_value_handle(&global.as_any_value_enum())
17131630
}
1714-
/// ```ignore
1715-
/// struct A {
1716-
/// a: i32,
1717-
/// b: *i32,
1718-
/// c: *A,
1719-
/// d: B,
1720-
/// e: [i32; 3],
1721-
/// f: [*i32; 3],
1722-
/// g: [A; 3], // TODO 没考虑到
1723-
/// h: Trait,
1724-
/// i: *[*i32; 3],
1725-
/// }
1726-
/// visit_ptr(&a.b);
1727-
/// visit_ptr(&a.c);
1728-
/// a.d.vtable(visitfns..);
1729-
/// a.e.vtable(visitfns..);
1730-
/// a.f.vtable(visitfns..);
1731-
/// visit_trait(&a.h);
1732-
/// visit_ptr(&a.i);
1733-
/// ```
1631+
17341632
fn gen_st_visit_function(
17351633
&self,
17361634
ctx: &mut Ctx<'a>,
@@ -1740,23 +1638,9 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
17401638
let currentbb = ctx.block;
17411639
self.builder.unset_current_debug_location();
17421640
let i8ptrtp = self.context.i8_type().ptr_type(AddressSpace::default());
1743-
let visit_ftp = self
1744-
.context
1745-
.void_type()
1746-
.fn_type(&[i8ptrtp.into(), i8ptrtp.into()], false)
1747-
.ptr_type(AddressSpace::default());
17481641
let ptrtp = self.struct_type(v, ctx).ptr_type(AddressSpace::default());
17491642
let ty = ptrtp.get_element_type().into_struct_type();
1750-
let ftp = self.context.void_type().fn_type(
1751-
&[
1752-
ptrtp.into(),
1753-
i8ptrtp.into(),
1754-
visit_ftp.into(),
1755-
visit_ftp.into(),
1756-
visit_ftp.into(),
1757-
],
1758-
false,
1759-
);
1643+
let ftp = self.mark_fn_tp(ptrtp);
17601644
let f = self.module.add_function(
17611645
&(ty.get_name().unwrap().to_str().unwrap().to_string() + "@"),
17621646
ftp,
@@ -1770,26 +1654,11 @@ impl<'a, 'ctx> IRBuilder<'a, 'ctx> for LLVMBuilder<'a, 'ctx> {
17701654
for i in 1..fieldn {
17711655
let field_pltp = &*field_tps[i as usize - 1].borrow();
17721656
let visitor = f.get_nth_param(1).unwrap().into_pointer_value();
1773-
let visit_ptr_f: CallableValue = f
1774-
.get_nth_param(2)
1775-
.unwrap()
1776-
.into_pointer_value()
1777-
.try_into()
1778-
.unwrap();
1657+
let visit_ptr_f = get_nth_mark_fn(f, 2);
17791658
// complex type needs to provide a visit function by itself
17801659
// which is stored in the first field of the struct
1781-
let visit_complex_f: CallableValue = f
1782-
.get_nth_param(3)
1783-
.unwrap()
1784-
.into_pointer_value()
1785-
.try_into()
1786-
.unwrap();
1787-
let visit_trait_f: CallableValue = f
1788-
.get_nth_param(4)
1789-
.unwrap()
1790-
.into_pointer_value()
1791-
.try_into()
1792-
.unwrap();
1660+
let visit_complex_f = get_nth_mark_fn(f, 3);
1661+
let visit_trait_f = get_nth_mark_fn(f, 4);
17931662
let f = self.builder.build_struct_gep(st, i, "gep").unwrap();
17941663
// 指针类型,递归调用visit函数
17951664
if let PLType::POINTER(_) = field_pltp {

src/ast/builder/mod.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,6 @@ pub trait IRBuilder<'a, 'ctx> {
121121
fn position_at_end_block(&self, block: BlockHandle);
122122
fn add_body_to_struct_type(&self, name: &str, order_fields: &[Field], ctx: &mut Ctx<'a>);
123123
fn get_or_insert_fn_handle(&self, pltp: &FNType, ctx: &mut Ctx<'a>) -> ValueHandle;
124-
// fn mv2heap(&self, val: ValueHandle, ctx: &mut Ctx<'a>, tp: &PLType) -> ValueHandle;
125-
// fn gc_rm_root(&self, stackptr: ValueHandle, ctx: &mut Ctx<'a>);
126-
// fn gc_rm_root_current(&self, stackptr: ValueHandle, ctx: &mut Ctx<'a>);
127-
// fn gc_collect(&self, ctx: &mut Ctx<'a>);
128124
fn get_or_add_global(
129125
&self,
130126
name: &str,

src/ast/compiler.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use crate::{
44
accumulators::{Diagnostics, ModBuffer},
55
builder::llvmbuilder::get_target_machine,
66
node::program::Program,
7-
pass::{COMPILE_PROGRESS, MAP_NAMES},
7+
pass::MAP_NAMES,
88
},
99
lsp::mem_docs::{FileCompileInput, MemDocsInput},
1010
nomparser::parse,
@@ -86,6 +86,12 @@ pub enum ActionType {
8686
SignatureHelp,
8787
}
8888

89+
lazy_static::lazy_static! {
90+
pub static ref COMPILE_PROGRESS: ProgressBar = {
91+
ProgressBar::hidden()
92+
};
93+
}
94+
8995
#[cfg(feature = "jit")]
9096
pub fn run(p: &Path, opt: OptimizationLevel) {
9197
type MainFunc = unsafe extern "C" fn() -> i64;
@@ -198,7 +204,7 @@ lazy_static! {
198204

199205
#[salsa::tracked]
200206
pub fn compile(db: &dyn Db, docs: MemDocsInput, out: String, op: Options) {
201-
MAP_NAMES.inner.borrow_mut().clear();
207+
MAP_NAMES.inner.lock().borrow_mut().clear();
202208
let pb = &COMPILE_PROGRESS;
203209
pb.enable_steady_tick(Duration::from_millis(50));
204210
pb.set_style(PROGRESS_STYLE.clone());

src/ast/node/program.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ use crate::ast::builder::llvmbuilder::LLVMBuilder;
77
use crate::ast::builder::no_op_builder::NoOpBuilder;
88
use crate::ast::builder::BuilderEnum;
99
use crate::ast::builder::IRBuilder;
10+
use crate::ast::compiler::COMPILE_PROGRESS;
1011
use crate::ast::compiler::{compile_dry_file, ActionType};
1112
use crate::ast::ctx::{self, Ctx};
12-
use crate::ast::pass::COMPILE_PROGRESS;
1313
use crate::ast::plmod::LSPDef;
1414
use crate::ast::plmod::Mod;
1515
use crate::flow::display::Dot;

0 commit comments

Comments
 (0)