@@ -216,8 +216,9 @@ const ANCHOR_CALL_UNSUPPORTED_INSTRUCTION: usize = 11;
216
216
const ANCHOR_EXTERNAL_FUNCTION_CALL : usize = 12 ;
217
217
const ANCHOR_INTERNAL_FUNCTION_CALL_PROLOGUE : usize = 13 ;
218
218
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
221
222
222
223
const REGISTER_MAP : [ X86Register ; 11 ] = [
223
224
CALLER_SAVED_REGISTERS [ 0 ] , // RAX
@@ -983,8 +984,10 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
983
984
984
985
#[ inline]
985
986
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 ) ) ) ;
988
991
}
989
992
990
993
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> {
1583
1586
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
1584
1587
self . emit_ins ( X86Instruction :: return_near ( ) ) ; // Tail call to host_target_address
1585
1588
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 ) ) ;
1587
1592
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
1588
1608
for ( anchor_base, len) in & [
1589
1609
( 0 , 1i32 ) , ( 0 , 2i32 ) , ( 0 , 4i32 ) , ( 0 , 8i32 ) ,
1590
1610
( 4 , 1i32 ) , ( 4 , 2i32 ) , ( 4 , 4i32 ) , ( 4 , 8i32 ) ,
0 commit comments