Fix 32-bit wrap-around for profiler and opstats
This commit is contained in:
parent
1b06e7bd34
commit
199b1ceb49
2
Makefile
2
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
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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<u8>,
|
||||
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 }
|
||||
}
|
||||
|
|
|
@ -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); }
|
||||
|
|
|
@ -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); }
|
||||
|
|
Loading…
Reference in a new issue