Skip to content

Commit ea8b3e9

Browse files
committed
Adds ANCHOR_VALIDATE_AND_PROFILE_INSTRUCTION_COUNT
1 parent 613bf9b commit ea8b3e9

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

src/jit.rs

+25-5
Original file line numberDiff line numberDiff line change
@@ -216,8 +216,9 @@ const ANCHOR_CALL_UNSUPPORTED_INSTRUCTION: usize = 11;
216216
const ANCHOR_EXTERNAL_FUNCTION_CALL: usize = 12;
217217
const ANCHOR_INTERNAL_FUNCTION_CALL_PROLOGUE: usize = 13;
218218
const ANCHOR_INTERNAL_FUNCTION_CALL_REG: usize = 14;
219-
const ANCHOR_TRANSLATE_MEMORY_ADDRESS: usize = 21;
220-
const ANCHOR_COUNT: usize = 34; // Update me when adding or removing anchors
219+
const ANCHOR_VALIDATE_AND_PROFILE_INSTRUCTION_COUNT: usize = 15;
220+
const ANCHOR_TRANSLATE_MEMORY_ADDRESS: usize = 16;
221+
const ANCHOR_COUNT: usize = 28; // Update me when adding or removing anchors
221222

222223
const REGISTER_MAP: [X86Register; 11] = [
223224
CALLER_SAVED_REGISTERS[0], // RAX
@@ -983,8 +984,10 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
983984

984985
#[inline]
985986
fn emit_validate_and_profile_instruction_count(&mut self, target_pc: Option<usize>) {
986-
self.emit_validate_instruction_count(Some(self.pc));
987-
self.emit_profile_instruction_count(target_pc);
987+
let target_pc = target_pc.unwrap();
988+
self.last_instruction_meter_validation_pc = self.pc;
989+
self.emit_ins(X86Instruction::load_immediate(REGISTER_SCRATCH, (((target_pc << 32) | self.pc) as i64) ^ self.immediate_value_key));
990+
self.emit_ins(X86Instruction::call_immediate(self.relative_to_anchor(ANCHOR_VALIDATE_AND_PROFILE_INSTRUCTION_COUNT, 5)));
988991
}
989992

990993
fn emit_rust_call(&mut self, target: Value, arguments: &[Argument], result_reg: Option<X86Register>) {
@@ -1583,8 +1586,25 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
15831586
self.emit_ins(X86Instruction::xchg(OperandSize::S64, REGISTER_MAP[0], RSP, Some(X86IndirectAccess::OffsetIndexShift(0, RSP, 0)))); // Swap REGISTER_MAP[0] and host_target_address
15841587
self.emit_ins(X86Instruction::return_near()); // Tail call to host_target_address
15851588

1586-
// Translates a vm memory address to a host memory address
1589+
// Routine for emit_validate_and_profile_instruction_count()
1590+
self.set_anchor(ANCHOR_VALIDATE_AND_PROFILE_INSTRUCTION_COUNT);
1591+
self.emit_ins(X86Instruction::mov_mmx(OperandSize::S64, REGISTER_SCRATCH, MM0));
15871592
let lower_key = self.immediate_value_key as i32 as i64;
1593+
self.emit_ins(X86Instruction::alu_immediate(OperandSize::S32, 0x81, 6, REGISTER_SCRATCH, lower_key, None)); // REGISTER_SCRATCH ^= lower_key;
1594+
// If instruction_meter >= pc, throw ExceededMaxInstructions
1595+
self.emit_ins(X86Instruction::cmp(OperandSize::S64, REGISTER_SCRATCH, REGISTER_INSTRUCTION_METER, None));
1596+
self.emit_ins(X86Instruction::conditional_jump_immediate(0x86, self.relative_to_anchor(ANCHOR_THROW_EXCEEDED_MAX_INSTRUCTIONS, 6)));
1597+
// A version of `self.emit_profile_instruction_count(None);` which reads self.pc from REGISTER_SCRATCH
1598+
self.emit_ins(X86Instruction::alu(OperandSize::S64, 0x29, REGISTER_SCRATCH, REGISTER_INSTRUCTION_METER, None)); // instruction_meter -= self.pc;
1599+
self.emit_ins(X86Instruction::alu_immediate(OperandSize::S64, 0x81, 5, REGISTER_INSTRUCTION_METER, 1, None)); // instruction_meter -= 1;
1600+
self.emit_ins(X86Instruction::mov_mmx(OperandSize::S64, MM0, REGISTER_SCRATCH));
1601+
self.emit_ins(X86Instruction::alu_immediate(OperandSize::S64, 0xc1, 5, REGISTER_SCRATCH, 32, None)); // wrapping_shr(32)
1602+
let upper_key = (self.immediate_value_key >> 32) as i32 as i64;
1603+
self.emit_ins(X86Instruction::alu_immediate(OperandSize::S32, 0x81, 6, REGISTER_SCRATCH, upper_key, None)); // REGISTER_SCRATCH ^= upper_key;
1604+
self.emit_ins(X86Instruction::alu(OperandSize::S64, 0x01, REGISTER_SCRATCH, REGISTER_INSTRUCTION_METER, None)); // instruction_meter += target_pc;
1605+
self.emit_ins(X86Instruction::return_near());
1606+
1607+
// Translates a vm memory address to a host memory address
15881608
for (anchor_base, len) in &[
15891609
(0, 1i32), (0, 2i32), (0, 4i32), (0, 8i32),
15901610
(4, 1i32), (4, 2i32), (4, 4i32), (4, 8i32),

0 commit comments

Comments
 (0)