Skip to content

Commit 3126f26

Browse files
committed
Adds ANCHOR_VALIDATE_AND_PROFILE_INSTRUCTION_COUNT
1 parent 4bde884 commit 3126f26

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
@@ -206,8 +206,9 @@ const ANCHOR_CALL_UNSUPPORTED_INSTRUCTION: usize = 11;
206206
const ANCHOR_EXTERNAL_FUNCTION_CALL: usize = 12;
207207
const ANCHOR_INTERNAL_FUNCTION_CALL_PROLOGUE: usize = 13;
208208
const ANCHOR_INTERNAL_FUNCTION_CALL_REG: usize = 14;
209-
const ANCHOR_TRANSLATE_MEMORY_ADDRESS: usize = 21;
210-
const ANCHOR_COUNT: usize = 34; // Update me when adding or removing anchors
209+
const ANCHOR_VALIDATE_AND_PROFILE_INSTRUCTION_COUNT: usize = 21;
210+
const ANCHOR_TRANSLATE_MEMORY_ADDRESS: usize = 22;
211+
const ANCHOR_COUNT: usize = 35; // Update me when adding or removing anchors
211212

212213
const REGISTER_MAP: [X86Register; 11] = [
213214
CALLER_SAVED_REGISTERS[0], // RAX
@@ -980,8 +981,10 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
980981

981982
#[inline]
982983
fn emit_validate_and_profile_instruction_count(&mut self, target_pc: Option<usize>) {
983-
self.emit_validate_instruction_count(Some(self.pc));
984-
self.emit_profile_instruction_count(target_pc);
984+
let target_pc = target_pc.unwrap();
985+
self.last_instruction_meter_validation_pc = self.pc;
986+
self.emit_ins(X86Instruction::load_immediate(REGISTER_SCRATCH, ((target_pc << 32 | self.pc) as i64) ^ self.immediate_value_key));
987+
self.emit_ins(X86Instruction::call_immediate(self.relative_to_anchor(ANCHOR_VALIDATE_AND_PROFILE_INSTRUCTION_COUNT, 5)));
985988
}
986989

987990
fn emit_rust_call(&mut self, target: Value, arguments: &[Argument], result_reg: Option<X86Register>) {
@@ -1580,8 +1583,25 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
15801583
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
15811584
self.emit_ins(X86Instruction::return_near()); // Tail call to host_target_address
15821585

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

0 commit comments

Comments
 (0)