diff --git a/Makefile b/Makefile index b2d27934..e558da46 100644 --- a/Makefile +++ b/Makefile @@ -69,7 +69,7 @@ CARGO_FLAGS_SAFE=\ --target wasm32-unknown-unknown \ -- \ -C linker=tools/rust-lld-wrapper \ - -C link-args="--import-table --global-base=262144 $(STRIP_DEBUG_FLAG)" \ + -C link-args="--import-table --global-base=4096 $(STRIP_DEBUG_FLAG)" \ -C link-args="build/softfloat.o" \ -C link-args="build/zstddeclib.o" \ --verbose diff --git a/src/rust/codegen.rs b/src/rust/codegen.rs index 2334896a..b461b720 100644 --- a/src/rust/codegen.rs +++ b/src/rust/codegen.rs @@ -2252,7 +2252,7 @@ pub fn gen_profiler_stat_increment(builder: &mut WasmBuilder, stat: profiler::st return; } let addr = unsafe { profiler::stat_array.as_mut_ptr().offset(stat as isize) } as u32; - builder.increment_fixed_i32(addr, 1) + builder.increment_fixed_i64(addr, 1) } pub fn gen_debug_track_jit_exit(builder: &mut WasmBuilder, address: u32) { diff --git a/src/rust/cpu/cpu.rs b/src/rust/cpu/cpu.rs index 15bb5629..77541da4 100644 --- a/src/rust/cpu/cpu.rs +++ b/src/rust/cpu/cpu.rs @@ -3784,6 +3784,7 @@ pub unsafe fn vm86_mode() -> bool { return *flags & FLAG_VM == FLAG_VM; } pub unsafe fn getiopl() -> i32 { return *flags >> 12 & 3; } #[no_mangle] +#[cfg(feature = "profiler")] pub unsafe fn get_opstats_buffer( compiled: bool, jit_exit: bool, @@ -3793,25 +3794,34 @@ pub unsafe fn get_opstats_buffer( is_0f: bool, is_mem: bool, fixed_g: u8, -) -> u32 { - let index = (is_0f as u32) << 12 | (opcode as u32) << 4 | (is_mem as u32) << 3 | fixed_g as u32; - if compiled { - *opstats_compiled_buffer.offset(index as isize) - } - else if jit_exit { - *opstats_jit_exit_buffer.offset(index as isize) - } - else if unguarded_register { - *opstats_unguarded_register_buffer.offset(index as isize) - } - else if wasm_size { - *opstats_wasm_size.offset(index as isize) - } - else { - *opstats_buffer.offset(index as isize) +) -> f64 { + { + let index = (is_0f as usize) << 12 + | (opcode as usize) << 4 + | (is_mem as usize) << 3 + | fixed_g as usize; + (if compiled { + ::opstats::opstats_compiled_buffer[index] + } + else if jit_exit { + ::opstats::opstats_jit_exit_buffer[index] + } + else if unguarded_register { + ::opstats::opstats_unguarded_register_buffer[index] + } + else if wasm_size { + ::opstats::opstats_wasm_size[index] + } + else { + ::opstats::opstats_buffer[index] + }) as f64 } } +#[no_mangle] +#[cfg(not(feature = "profiler"))] +pub unsafe fn get_opstats_buffer() -> f64 { 0.0 } + pub unsafe fn invlpg(addr: i32) { let page = (addr as u32 >> 12) as i32; // Note: Doesn't remove this page from valid_tlb_entries: This isn't diff --git a/src/rust/cpu/global_pointers.rs b/src/rust/cpu/global_pointers.rs index 9ae885cf..a4d39106 100644 --- a/src/rust/cpu/global_pointers.rs +++ b/src/rust/cpu/global_pointers.rs @@ -67,12 +67,6 @@ pub const sse_scratch_register: *mut reg128 = 1136 as *mut reg128; pub const fpu_st: *mut F80 = 1152 as *mut F80; -pub const opstats_buffer: *mut u32 = 0x08000 as *mut u32; -pub const opstats_compiled_buffer: *mut u32 = 0x10000 as *mut u32; -pub const opstats_jit_exit_buffer: *mut u32 = 0x18000 as *mut u32; -pub const opstats_unguarded_register_buffer: *mut u32 = 0x20000 as *mut u32; -pub const opstats_wasm_size: *mut u32 = 0x28000 as *mut u32; - pub fn get_reg32_offset(r: u32) -> u32 { dbg_assert!(r < 8); (unsafe { reg32.offset(r as isize) }) as u32 diff --git a/src/rust/jit.rs b/src/rust/jit.rs index 60ba135d..4fa752ca 100644 --- a/src/rust/jit.rs +++ b/src/rust/jit.rs @@ -1856,7 +1856,7 @@ fn jit_generate_basic_block(ctx: &mut JitContext, block: &BasicBlock) { let was_block_boundary = instruction_flags & JIT_INSTR_BLOCK_BOUNDARY_FLAG != 0; let wasm_length = ctx.builder.instruction_body_length() - wasm_length_before; - opstats::record_opstat_size_wasm(instruction, wasm_length as u32); + opstats::record_opstat_size_wasm(instruction, wasm_length as u64); dbg_assert!((end_eip == stop_addr) == (start_eip == last_instruction_addr)); dbg_assert!(instruction_length < MAX_INSTRUCTION_LENGTH); diff --git a/src/rust/opstats.rs b/src/rust/opstats.rs index c4a9b469..3b091e98 100644 --- a/src/rust/opstats.rs +++ b/src/rust/opstats.rs @@ -1,7 +1,18 @@ -use cpu; -use cpu::global_pointers; use wasmgen::wasm_builder::WasmBuilder; +const SIZE: usize = if cfg!(feature = "profiler") { 8192 } else { 0 }; + +#[allow(non_upper_case_globals)] +pub static mut opstats_buffer: [u64; SIZE] = [0; SIZE]; +#[allow(non_upper_case_globals)] +pub static mut opstats_compiled_buffer: [u64; SIZE] = [0; SIZE]; +#[allow(non_upper_case_globals)] +pub static mut opstats_jit_exit_buffer: [u64; SIZE] = [0; SIZE]; +#[allow(non_upper_case_globals)] +pub static mut opstats_unguarded_register_buffer: [u64; SIZE] = [0; SIZE]; +#[allow(non_upper_case_globals)] +pub static mut opstats_wasm_size: [u64; SIZE] = [0; SIZE]; + pub struct Instruction { pub prefixes: Vec, pub opcode: u8, @@ -134,7 +145,10 @@ pub fn gen_opstats(builder: &mut WasmBuilder, opcode: u32) { for prefix in instruction.prefixes { let index = (prefix as u32) << 4; - builder.increment_fixed_i32(global_pointers::opstats_buffer as u32 + 4 * index, 1); + builder.increment_fixed_i64( + unsafe { &mut opstats_buffer[index as usize] as *mut _ } as u32, + 1, + ); } let index = (instruction.is_0f as u32) << 12 @@ -142,7 +156,10 @@ pub fn gen_opstats(builder: &mut WasmBuilder, opcode: u32) { | (instruction.is_mem as u32) << 3 | instruction.fixed_g as u32; - builder.increment_fixed_i32(global_pointers::opstats_buffer as u32 + 4 * index, 1); + builder.increment_fixed_i64( + unsafe { &mut opstats_buffer[index as usize] as *mut _ } as u32, + 1, + ); } pub fn record_opstat_compiled(opcode: u32) { @@ -154,7 +171,7 @@ pub fn record_opstat_compiled(opcode: u32) { for prefix in instruction.prefixes { let index = (prefix as u32) << 4; - unsafe { *cpu::global_pointers::opstats_compiled_buffer.offset(index as isize) += 1 } + unsafe { opstats_compiled_buffer[index as usize] += 1 } } let index = (instruction.is_0f as u32) << 12 @@ -162,7 +179,7 @@ pub fn record_opstat_compiled(opcode: u32) { | (instruction.is_mem as u32) << 3 | instruction.fixed_g as u32; - unsafe { *cpu::global_pointers::opstats_compiled_buffer.offset(index as isize) += 1 } + unsafe { opstats_compiled_buffer[index as usize] += 1 } } pub fn record_opstat_jit_exit(opcode: u32) { @@ -174,7 +191,7 @@ pub fn record_opstat_jit_exit(opcode: u32) { for prefix in instruction.prefixes { let index = (prefix as u32) << 4; - unsafe { *cpu::global_pointers::opstats_jit_exit_buffer.offset(index as isize) += 1 } + unsafe { opstats_jit_exit_buffer[index as usize] += 1 } } let index = (instruction.is_0f as u32) << 12 @@ -182,7 +199,7 @@ pub fn record_opstat_jit_exit(opcode: u32) { | (instruction.is_mem as u32) << 3 | instruction.fixed_g as u32; - unsafe { *cpu::global_pointers::opstats_jit_exit_buffer.offset(index as isize) += 1 } + unsafe { opstats_jit_exit_buffer[index as usize] += 1 } } pub fn gen_opstat_unguarded_register(builder: &mut WasmBuilder, opcode: u32) { @@ -194,8 +211,8 @@ pub fn gen_opstat_unguarded_register(builder: &mut WasmBuilder, opcode: u32) { for prefix in instruction.prefixes { let index = (prefix as u32) << 4; - builder.increment_fixed_i32( - global_pointers::opstats_unguarded_register_buffer as u32 + 4 * index, + builder.increment_fixed_i64( + unsafe { &mut opstats_unguarded_register_buffer[index as usize] as *mut _ } as u32, 1, ); } @@ -205,13 +222,13 @@ pub fn gen_opstat_unguarded_register(builder: &mut WasmBuilder, opcode: u32) { | (instruction.is_mem as u32) << 3 | instruction.fixed_g as u32; - builder.increment_fixed_i32( - global_pointers::opstats_unguarded_register_buffer as u32 + 4 * index, + builder.increment_fixed_i64( + unsafe { &mut opstats_unguarded_register_buffer[index as usize] as *mut _ } as u32, 1, ); } -pub fn record_opstat_size_wasm(opcode: u32, size: u32) { +pub fn record_opstat_size_wasm(opcode: u32, size: u64) { if !cfg!(feature = "profiler") { return; } @@ -220,7 +237,7 @@ pub fn record_opstat_size_wasm(opcode: u32, size: u32) { for prefix in instruction.prefixes { let index = (prefix as u32) << 4; - unsafe { *cpu::global_pointers::opstats_wasm_size.offset(index as isize) += size } + unsafe { opstats_wasm_size[index as usize] += size } } let index = (instruction.is_0f as u32) << 12 @@ -228,5 +245,5 @@ pub fn record_opstat_size_wasm(opcode: u32, size: u32) { | (instruction.is_mem as u32) << 3 | instruction.fixed_g as u32; - unsafe { *cpu::global_pointers::opstats_wasm_size.offset(index as isize) += size } + unsafe { opstats_wasm_size[index as usize] += size } } diff --git a/src/rust/profiler.rs b/src/rust/profiler.rs index 54153665..a48ad200 100644 --- a/src/rust/profiler.rs +++ b/src/rust/profiler.rs @@ -112,7 +112,7 @@ pub enum stat { SEG_OFFSET_NOT_OPTIMISED, } -#[no_mangle] +#[allow(non_upper_case_globals)] pub static mut stat_array: [u64; 500] = [0; 500]; pub fn stat_increment(stat: stat) { stat_increment_by(stat, 1); } diff --git a/src/rust/wasmgen/wasm_builder.rs b/src/rust/wasmgen/wasm_builder.rs index 4725c82a..2abcd97b 100644 --- a/src/rust/wasmgen/wasm_builder.rs +++ b/src/rust/wasmgen/wasm_builder.rs @@ -761,15 +761,16 @@ impl WasmBuilder { write_leb_u32(&mut self.instruction_body, byte_offset); } - pub fn increment_fixed_i32(&mut self, byte_offset: u32, n: i32) { + pub fn increment_fixed_i64(&mut self, byte_offset: u32, n: i64) { self.const_i32(byte_offset as i32); - self.load_fixed_i32(byte_offset); - self.const_i32(n); - self.add_i32(); - self.store_aligned_i32(0); + self.load_fixed_i64(byte_offset); + self.const_i64(n); + self.add_i64(); + self.store_aligned_i64(0); } pub fn add_i32(&mut self) { self.instruction_body.push(op::OP_I32ADD); } + pub fn add_i64(&mut self) { self.instruction_body.push(op::OP_I64ADD); } pub fn sub_i32(&mut self) { self.instruction_body.push(op::OP_I32SUB); } pub fn and_i32(&mut self) { self.instruction_body.push(op::OP_I32AND); } pub fn or_i32(&mut self) { self.instruction_body.push(op::OP_I32OR); }