luaur_code_gen/functions/
call_barrier_table_fast.rs1use crate::enums::condition_x_64::ConditionX64;
2use crate::enums::size_x_64::SizeX64;
3use crate::records::assembly_builder_x_64::AssemblyBuilderX64;
4use crate::records::ir_call_wrapper_x_64::IrCallWrapperX64;
5use crate::records::ir_op::IrOp;
6use crate::records::ir_reg_alloc_x_64::IrRegAllocX64;
7use crate::records::label::Label;
8use crate::records::native_context::NativeContext;
9use crate::records::operand_x_64::OperandX64;
10use crate::records::register_x_64::RegisterX64;
11use crate::records::scoped_spills::ScopedSpills;
12use luaur_vm::macros::bitmask::bitmask;
13use luaur_vm::macros::blackbit::BLACKBIT;
14use luaur_vm::records::g_cheader::GCheader;
15use luaur_vm::records::lua_table::LuaTable;
16
17const fn r_state() -> RegisterX64 {
18 RegisterX64 {
19 bits: (15u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
20 }
21}
22
23const fn r_native_context() -> RegisterX64 {
24 RegisterX64 {
25 bits: (13u8 << RegisterX64::INDEX_SHIFT) | SizeX64::qword as u8,
26 }
27}
28
29pub fn call_barrier_table_fast(
30 regs: &mut IrRegAllocX64,
31 build: &mut AssemblyBuilderX64,
32 table: RegisterX64,
33 table_op: IrOp,
34) {
35 let mut skip = Label { id: 0, location: 0 };
36
37 build.test(
39 OperandX64::mem(
40 SizeX64::byte,
41 RegisterX64::noreg,
42 1,
43 table,
44 core::mem::offset_of!(GCheader, marked) as i32,
45 ),
46 OperandX64::imm(bitmask(BLACKBIT as i32)),
47 );
48 build.jcc(ConditionX64::Zero, &mut skip);
49
50 {
51 let _spill_guard = {
52 let mut guard = ScopedSpills {
53 owner: regs as *mut _,
54 start_spill_id: 0,
55 };
56 guard.scoped_spills_scoped_spills_ir_reg_alloc_x_64(regs);
57 guard
58 };
59
60 let mut call_wrap = IrCallWrapperX64::ir_call_wrapper_x_64_ir_call_wrapper_x_64(
61 regs,
62 build,
63 regs.curr_inst_idx,
64 );
65
66 call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
67 SizeX64::qword,
68 OperandX64::reg(r_state()),
69 IrOp::ir_op(),
70 );
71 call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
72 SizeX64::qword,
73 OperandX64::reg(table),
74 table_op,
75 );
76 call_wrap.add_argument_size_x_64_operand_x_64_ir_op(
77 SizeX64::qword,
78 OperandX64::mem(
79 SizeX64::none,
80 RegisterX64::noreg,
81 1,
82 table,
83 core::mem::offset_of!(LuaTable, gclist) as i32,
84 ),
85 IrOp::ir_op(),
86 );
87
88 call_wrap.call(&OperandX64::mem(
89 SizeX64::qword,
90 RegisterX64::noreg,
91 1,
92 r_native_context(),
93 core::mem::offset_of!(NativeContext, luaC_barrierback) as i32,
94 ));
95 }
96
97 build.set_label_label(&mut skip);
98}