Skip to content

Commit 8bd4f89

Browse files
committed
Premap jit live ranges
1 parent 5b3a95c commit 8bd4f89

File tree

5 files changed

+95
-58
lines changed

5 files changed

+95
-58
lines changed

src/core/memory/mem.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::core::cp15::TcmState;
2-
use crate::core::emu::{get_cp15, get_regs, Emu};
2+
use crate::core::emu::{get_cp15, Emu};
33
use crate::core::memory::bios::{BiosArm7, BiosArm9};
44
use crate::core::memory::io_arm7::IoArm7;
55
use crate::core::memory::io_arm9::IoArm9;
@@ -205,7 +205,7 @@ impl Memory {
205205
if aligned_addr < cp15.itcm_size && cp15.itcm_state != TcmState::Disabled {
206206
self.tcm.write_itcm(aligned_addr, value);
207207
debug_println!("{:?} itcm write at {:x} with value {:x}", CPU, aligned_addr, value.into(),);
208-
self.breakout_imm = self.jit.invalidate_block::<{ JitRegion::Itcm }>(aligned_addr, size_of::<T>(), get_regs!(emu, CPU).pc);
208+
self.jit.invalidate_block::<{ JitRegion::Itcm }>(aligned_addr, size_of::<T>());
209209
}
210210
}
211211
}
@@ -216,12 +216,12 @@ impl Memory {
216216
},
217217
regions::MAIN_MEMORY_OFFSET => {
218218
self.main.write(addr_offset, value);
219-
self.breakout_imm = self.jit.invalidate_block::<{ JitRegion::Main }>(aligned_addr, size_of::<T>(), get_regs!(emu, CPU).pc);
219+
self.jit.invalidate_block::<{ JitRegion::Main }>(aligned_addr, size_of::<T>());
220220
}
221221
regions::SHARED_WRAM_OFFSET => {
222222
self.wram.write::<CPU, _>(addr_offset, value);
223223
if CPU == ARM7 {
224-
self.breakout_imm = self.jit.invalidate_block::<{ JitRegion::Wram }>(aligned_addr, size_of::<T>(), get_regs!(emu, CPU).pc);
224+
self.jit.invalidate_block::<{ JitRegion::Wram }>(aligned_addr, size_of::<T>());
225225
}
226226
}
227227
regions::IO_PORTS_OFFSET => match CPU {
@@ -243,7 +243,7 @@ impl Memory {
243243
regions::VRAM_OFFSET => {
244244
self.vram.write::<CPU, _>(addr_offset, value);
245245
if CPU == ARM7 {
246-
self.breakout_imm = self.jit.invalidate_block::<{ JitRegion::VramArm7 }>(aligned_addr, size_of::<T>(), get_regs!(emu, CPU).pc);
246+
self.jit.invalidate_block::<{ JitRegion::VramArm7 }>(aligned_addr, size_of::<T>());
247247
}
248248
}
249249
regions::OAM_OFFSET => self.oam.write(addr_offset, value),

src/jit/jit_memory.rs

Lines changed: 34 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@ use lazy_static::lazy_static;
1010
use paste::paste;
1111
use std::intrinsics::unlikely;
1212
use std::marker::ConstParamTy;
13-
use std::ptr;
13+
use std::{ptr, slice};
1414
use CpuType::{ARM7, ARM9};
1515

1616
const 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;
1818
const 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 {
118118
impl 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) {

src/jit/jit_memory_map.rs

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,27 @@
11
use crate::core::memory::regions;
22
use crate::core::CpuType;
3-
use crate::jit::jit_memory::{JitEntries, JitEntry};
3+
use crate::jit::jit_memory::{JitEntries, JitEntry, JitLiveRanges, JIT_LIVE_RANGE_PAGE_SIZE_SHIFT};
44
use crate::utils::HeapMemU32;
55

66
const BLOCK_SHIFT: usize = 13;
77
const BLOCK_SIZE: usize = 1 << BLOCK_SHIFT;
88
const SIZE: usize = (1 << 31) / BLOCK_SIZE;
9+
const LIVE_RANGES_SIZE: usize = 1 << (32 - JIT_LIVE_RANGE_PAGE_SIZE_SHIFT - 5);
910

1011
pub struct JitMemoryMap {
1112
map_arm9: HeapMemU32<SIZE>,
1213
map_arm7: HeapMemU32<SIZE>,
14+
live_ranges_map_arm9: HeapMemU32<LIVE_RANGES_SIZE>,
15+
live_ranges_map_arm7: HeapMemU32<LIVE_RANGES_SIZE>,
1316
}
1417

1518
impl JitMemoryMap {
16-
pub fn new(entries: &JitEntries) -> Self {
19+
pub fn new(entries: &JitEntries, live_ranges: &JitLiveRanges) -> Self {
1720
let mut instance = JitMemoryMap {
1821
map_arm9: HeapMemU32::new(),
1922
map_arm7: HeapMemU32::new(),
23+
live_ranges_map_arm9: HeapMemU32::new(),
24+
live_ranges_map_arm7: HeapMemU32::new(),
2025
};
2126

2227
for i in 0..SIZE {
@@ -47,19 +52,54 @@ impl JitMemoryMap {
4752
}
4853
}
4954

55+
for i in 0..LIVE_RANGES_SIZE {
56+
let addr = i << (JIT_LIVE_RANGE_PAGE_SIZE_SHIFT + 5);
57+
let arm9_ptr = &mut instance.live_ranges_map_arm9[i];
58+
let arm7_ptr = &mut instance.live_ranges_map_arm7[i];
59+
60+
macro_rules! get_ptr {
61+
($live_ranges:expr) => {{
62+
(unsafe { $live_ranges.as_ptr().add(i % $live_ranges.len()) } as u32)
63+
}};
64+
}
65+
66+
match (addr as u32) & 0xFF000000 {
67+
0 => {
68+
*arm9_ptr = get_ptr!(live_ranges.itcm);
69+
*arm7_ptr = get_ptr!(live_ranges.arm7_bios);
70+
}
71+
regions::INSTRUCTION_TCM_MIRROR_OFFSET => *arm9_ptr = get_ptr!(live_ranges.itcm),
72+
regions::MAIN_MEMORY_OFFSET => {
73+
*arm9_ptr = get_ptr!(live_ranges.main);
74+
*arm7_ptr = get_ptr!(live_ranges.main);
75+
}
76+
regions::SHARED_WRAM_OFFSET => *arm7_ptr = get_ptr!(live_ranges.wram),
77+
regions::VRAM_OFFSET => *arm7_ptr = get_ptr!(live_ranges.vram_arm7),
78+
0xFF000000 => *arm9_ptr = get_ptr!(live_ranges.arm9_bios),
79+
_ => {}
80+
}
81+
}
82+
5083
instance
5184
}
5285

53-
pub fn get_jit_entry<const CPU: CpuType>(&self, addr: u32) -> *const JitEntry {
86+
pub fn get_jit_entry<const CPU: CpuType>(&self, addr: u32) -> *mut JitEntry {
5487
let addr = addr >> 1;
5588
macro_rules! get_jit_entry {
5689
($map:expr) => {{
57-
unsafe { ($map[(addr >> BLOCK_SHIFT) as usize] as *const JitEntry).add((addr as usize) & (BLOCK_SIZE - 1)) }
90+
unsafe { ($map[(addr >> BLOCK_SHIFT) as usize] as *mut JitEntry).add((addr as usize) & (BLOCK_SIZE - 1)) }
5891
}};
5992
}
6093
match CPU {
6194
CpuType::ARM9 => get_jit_entry!(self.map_arm9),
6295
CpuType::ARM7 => get_jit_entry!(self.map_arm7),
6396
}
6497
}
98+
99+
pub fn get_live_range<const CPU: CpuType>(&self, addr: u32) -> *mut u32 {
100+
match CPU {
101+
CpuType::ARM9 => self.live_ranges_map_arm9[(addr >> (JIT_LIVE_RANGE_PAGE_SIZE_SHIFT + 5)) as usize] as _,
102+
CpuType::ARM7 => self.live_ranges_map_arm7[(addr >> (JIT_LIVE_RANGE_PAGE_SIZE_SHIFT + 5)) as usize] as _,
103+
}
104+
}
65105
}

src/main.rs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
#![feature(isqrt)]
1111
#![feature(naked_functions)]
1212
#![feature(new_zeroed_alloc)]
13+
#![feature(ptr_as_ref_unchecked)]
1314
#![feature(seek_stream_len)]
1415
#![feature(stmt_expr_attributes)]
1516

@@ -255,7 +256,9 @@ pub fn main() {
255256
// #[export_name = "sceUserMainThreadStackSize"]
256257
// pub static SCE_USER_MAIN_THREAD_STACK_SIZE: u32 = 4 * 1024 * 1024;
257258
// Instead just create a new thread with stack size set
258-
set_thread_prio_affinity(ThreadPriority::Low, ThreadAffinity::Core1);
259+
if cfg!(target_os = "vita") {
260+
set_thread_prio_affinity(ThreadPriority::Low, ThreadAffinity::Core0);
261+
}
259262
thread::Builder::new()
260263
.name("actual_main".to_string())
261264
.stack_size(4 * 1024 * 1024) // We reserve 2MB for jit registers
@@ -267,7 +270,9 @@ pub fn main() {
267270

268271
// Must be pub for vita
269272
pub fn actual_main() {
270-
set_thread_prio_affinity(ThreadPriority::High, ThreadAffinity::Core0);
273+
if cfg!(target_os = "vita") {
274+
set_thread_prio_affinity(ThreadPriority::High, ThreadAffinity::Core1);
275+
}
271276

272277
if DEBUG_LOG {
273278
std::env::set_var("RUST_BACKTRACE", "full");
@@ -295,7 +300,7 @@ pub fn actual_main() {
295300
thread::Builder::new()
296301
.name("audio".to_owned())
297302
.spawn(move || {
298-
set_thread_prio_affinity(ThreadPriority::Default, ThreadAffinity::Core1);
303+
set_thread_prio_affinity(ThreadPriority::Default, ThreadAffinity::Core0);
299304
let mut audio_buffer = HeapMemU32::<{ PRESENTER_AUDIO_BUF_SIZE }>::new();
300305
loop {
301306
sound_sampler.consume(audio_buffer.deref_mut());

src/utils.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ pub enum ThreadPriority {
188188
High,
189189
}
190190

191+
#[derive(Copy, Clone)]
191192
#[repr(u8)]
192193
pub enum ThreadAffinity {
193194
Core0 = 0,
@@ -197,7 +198,9 @@ pub enum ThreadAffinity {
197198

198199
#[cfg(target_os = "linux")]
199200
pub fn set_thread_prio_affinity(_: ThreadPriority, affinity: ThreadAffinity) {
200-
affinity::set_thread_affinity(&[affinity as usize]).unwrap();
201+
if (affinity as usize) < affinity::get_core_num() {
202+
affinity::set_thread_affinity(&[affinity as usize]).unwrap();
203+
}
201204
}
202205

203206
#[cfg(target_os = "vita")]

0 commit comments

Comments
 (0)