@@ -10,11 +10,11 @@ use lazy_static::lazy_static;
1010use paste:: paste;
1111use std:: intrinsics:: unlikely;
1212use std:: marker:: ConstParamTy ;
13- use std:: ptr;
13+ use std:: { ptr, slice } ;
1414use CpuType :: { ARM7 , ARM9 } ;
1515
1616const JIT_MEMORY_SIZE : usize = 16 * 1024 * 1024 ;
17- const JIT_LIVE_RANGE_PAGE_SIZE_SHIFT : u32 = 8 ;
17+ pub const JIT_LIVE_RANGE_PAGE_SIZE_SHIFT : u32 = 8 ;
1818const JIT_LIVE_RANGE_PAGE_SIZE : u32 = 1 << JIT_LIVE_RANGE_PAGE_SIZE_SHIFT ;
1919
2020#[ derive( ConstParamTy , Eq , PartialEq ) ]
@@ -93,13 +93,13 @@ create_jit_blocks!(
9393) ;
9494
9595#[ derive( Default ) ]
96- struct JitLiveRanges {
97- itcm : HeapMemU32 < { ( regions:: INSTRUCTION_TCM_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
98- main : HeapMemU32 < { ( regions:: MAIN_MEMORY_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
99- wram : HeapMemU32 < { ( ( regions:: SHARED_WRAM_SIZE + regions:: ARM7_WRAM_SIZE ) / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
100- vram_arm7 : HeapMemU32 < { ( vram:: ARM7_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
101- arm9_bios : HeapMemU32 < { ( regions:: ARM9_BIOS_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
102- arm7_bios : HeapMemU32 < { ( regions:: ARM7_BIOS_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
96+ pub struct JitLiveRanges {
97+ pub itcm : HeapMemU32 < { ( regions:: INSTRUCTION_TCM_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
98+ pub main : HeapMemU32 < { ( regions:: MAIN_MEMORY_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
99+ pub wram : HeapMemU32 < { ( ( regions:: SHARED_WRAM_SIZE + regions:: ARM7_WRAM_SIZE ) / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
100+ pub vram_arm7 : HeapMemU32 < { ( vram:: ARM7_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
101+ pub arm9_bios : HeapMemU32 < { ( regions:: ARM9_BIOS_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
102+ pub arm7_bios : HeapMemU32 < { ( regions:: ARM7_BIOS_SIZE / JIT_LIVE_RANGE_PAGE_SIZE / 32 ) as usize } > ,
103103}
104104
105105#[ cfg( target_os = "linux" ) ]
@@ -118,12 +118,13 @@ pub struct JitMemory {
118118impl JitMemory {
119119 pub fn new ( ) -> Self {
120120 let jit_entries = JitEntries :: new ( ) ;
121- let jit_memory_map = JitMemoryMap :: new ( & jit_entries) ;
121+ let jit_live_ranges = JitLiveRanges :: default ( ) ;
122+ let jit_memory_map = JitMemoryMap :: new ( & jit_entries, & jit_live_ranges) ;
122123 JitMemory {
123124 mem : Mmap :: executable ( "code" , JIT_MEMORY_SIZE ) . unwrap ( ) ,
124125 mem_offset : 0 ,
125126 jit_entries,
126- jit_live_ranges : JitLiveRanges :: default ( ) ,
127+ jit_live_ranges,
127128 jit_memory_map,
128129 }
129130 }
@@ -172,12 +173,14 @@ impl JitMemory {
172173 let entries_index = ( guest_pc >> 1 ) as usize ;
173174 let entries_index = entries_index % $entries. len( ) ;
174175 $entries[ entries_index] = JitEntry ( jit_entry_addr) ;
176+ assert_eq!( ptr:: addr_of!( $entries[ entries_index] ) , self . jit_memory_map. get_jit_entry:: <CPU >( guest_pc) ) ;
175177
176178 // >> 5 for u32 (each bit represents a page)
177179 let live_ranges_index = ( ( guest_pc >> JIT_LIVE_RANGE_PAGE_SIZE_SHIFT ) >> 5 ) as usize ;
178180 let live_ranges_index = live_ranges_index % $live_ranges. len( ) ;
179181 let live_ranges_bit = ( guest_pc >> JIT_LIVE_RANGE_PAGE_SIZE_SHIFT ) & 31 ;
180182 $live_ranges[ live_ranges_index] |= 1 << live_ranges_bit;
183+ assert_eq!( ptr:: addr_of!( $live_ranges[ live_ranges_index] ) , self . jit_memory_map. get_live_range:: <CPU >( guest_pc) ) ;
181184
182185 jit_entry_addr
183186 } } ;
@@ -220,60 +223,46 @@ impl JitMemory {
220223 unsafe { ( * self . jit_memory_map . get_jit_entry :: < CPU > ( guest_pc) ) . 0 }
221224 }
222225
223- pub fn invalidate_block < const REGION : JitRegion > ( & mut self , guest_addr : u32 , size : usize , guest_pc : u32 ) -> bool {
224- let mut should_breakout = false ;
225-
226+ pub fn invalidate_block < const REGION : JitRegion > ( & mut self , guest_addr : u32 , size : usize ) {
226227 macro_rules! invalidate {
227- ( $guest_addr: expr, $live_range: ident, [ $( ( $entries: ident, $default_entry: expr) ) ,+] ) => { {
228- let live_ranges_index = ( ( $guest_addr >> JIT_LIVE_RANGE_PAGE_SIZE_SHIFT ) >> 5 ) as usize ;
229- let live_ranges_index = live_ranges_index % self . jit_live_ranges. $live_range. len( ) ;
228+ ( $guest_addr: expr, $live_range: ident, $cpu: expr, [ $( ( $cpu_entry: expr, $entries: ident) ) ,+] ) => { {
229+ let live_range = unsafe { self . jit_memory_map. get_live_range:: <{ $cpu } >( $guest_addr) . as_mut_unchecked( ) } ;
230230 let live_ranges_bit = ( $guest_addr >> JIT_LIVE_RANGE_PAGE_SIZE_SHIFT ) & 31 ;
231-
232- if unlikely( self . jit_live_ranges. $live_range[ live_ranges_index] & ( 1 << live_ranges_bit) != 0 ) {
233- self . jit_live_ranges. $live_range[ live_ranges_index] &= !( 1 << live_ranges_bit) ;
234-
235- let guest_pc_index = ( ( guest_pc >> JIT_LIVE_RANGE_PAGE_SIZE_SHIFT ) >> 5 ) as usize ;
236- let guest_pc_index = guest_pc_index % self . jit_live_ranges. $live_range. len( ) ;
237- let guest_pc_bit = ( guest_pc >> JIT_LIVE_RANGE_PAGE_SIZE_SHIFT ) & 31 ;
238-
239- should_breakout |= live_ranges_index == guest_pc_index && live_ranges_bit == guest_pc_bit;
231+ if unlikely( * live_range & ( 1 << live_ranges_bit) != 0 ) {
232+ * live_range &= !( 1 << live_ranges_bit) ;
240233
241234 let guest_addr_start = $guest_addr & !( JIT_LIVE_RANGE_PAGE_SIZE - 1 ) ;
242- let guest_addr_end = guest_addr_start + JIT_LIVE_RANGE_PAGE_SIZE ;
243-
244235 $(
245- {
246- let entries_index_start = ( guest_addr_start >> 1 ) as usize ;
247- let entries_index_start = entries_index_start % self . jit_entries . $entries . len ( ) ;
248- let entries_index_end = ( guest_addr_end >> 1 ) as usize ;
249- let entries_index_end = entries_index_end % self . jit_entries . $entries . len ( ) ;
250- self . jit_entries . $entries [ entries_index_start..entries_index_end ] . fill ( $default_entry ) ;
251- }
236+ let jit_entry_start = self . jit_memory_map . get_jit_entry :: < { $cpu_entry } > ( guest_addr_start ) ;
237+ unsafe { slice :: from_raw_parts_mut ( jit_entry_start , JIT_LIVE_RANGE_PAGE_SIZE as usize ) . fill (
238+ match $cpu_entry {
239+ ARM9 => DEFAULT_JIT_ENTRY_ARM9 ,
240+ ARM7 => DEFAULT_JIT_ENTRY_ARM7 ,
241+ }
242+ ) }
252243 ) *
253244 }
254245 } } ;
255246 }
256247
257248 match REGION {
258249 JitRegion :: Itcm => {
259- invalidate ! ( guest_addr, itcm, [ ( itcm , DEFAULT_JIT_ENTRY_ARM9 ) ] ) ;
260- invalidate ! ( guest_addr + size as u32 - 1 , itcm, [ ( itcm , DEFAULT_JIT_ENTRY_ARM9 ) ] ) ;
250+ invalidate ! ( guest_addr, itcm, ARM9 , [ ( ARM9 , itcm ) ] ) ;
251+ invalidate ! ( guest_addr + size as u32 - 1 , itcm, ARM9 , [ ( ARM9 , itcm ) ] ) ;
261252 }
262253 JitRegion :: Main => {
263- invalidate ! ( guest_addr, main, [ ( main_arm9 , DEFAULT_JIT_ENTRY_ARM9 ) , ( main_arm7 , DEFAULT_JIT_ENTRY_ARM7 ) ] ) ;
264- invalidate ! ( guest_addr + size as u32 - 1 , main, [ ( main_arm9 , DEFAULT_JIT_ENTRY_ARM9 ) , ( main_arm7 , DEFAULT_JIT_ENTRY_ARM7 ) ] ) ;
254+ invalidate ! ( guest_addr, main, ARM9 , [ ( ARM9 , main_arm9 ) , ( ARM7 , main_arm7 ) ] ) ;
255+ invalidate ! ( guest_addr + size as u32 - 1 , main, ARM9 , [ ( ARM9 , main_arm9 ) , ( ARM7 , main_arm7 ) ] ) ;
265256 }
266257 JitRegion :: Wram => {
267- invalidate ! ( guest_addr, wram, [ ( wram , DEFAULT_JIT_ENTRY_ARM7 ) ] ) ;
268- invalidate ! ( guest_addr + size as u32 - 1 , wram, [ ( wram , DEFAULT_JIT_ENTRY_ARM7 ) ] ) ;
258+ invalidate ! ( guest_addr, wram, ARM7 , [ ( ARM7 , wram ) ] ) ;
259+ invalidate ! ( guest_addr + size as u32 - 1 , wram, ARM7 , [ ( ARM7 , wram ) ] ) ;
269260 }
270261 JitRegion :: VramArm7 => {
271- invalidate ! ( guest_addr, vram_arm7, [ ( vram_arm7 , DEFAULT_JIT_ENTRY_ARM7 ) ] ) ;
272- invalidate ! ( guest_addr + size as u32 - 1 , vram_arm7, [ ( vram_arm7 , DEFAULT_JIT_ENTRY_ARM7 ) ] ) ;
262+ invalidate ! ( guest_addr, vram_arm7, ARM7 , [ ( ARM7 , vram_arm7 ) ] ) ;
263+ invalidate ! ( guest_addr + size as u32 - 1 , vram_arm7, ARM7 , [ ( ARM7 , vram_arm7 ) ] ) ;
273264 }
274265 }
275-
276- should_breakout
277266 }
278267
279268 pub fn invalidate_wram ( & mut self ) {
0 commit comments