@@ -206,8 +206,9 @@ const ANCHOR_CALL_UNSUPPORTED_INSTRUCTION: usize = 11;
206
206
const ANCHOR_EXTERNAL_FUNCTION_CALL : usize = 12 ;
207
207
const ANCHOR_INTERNAL_FUNCTION_CALL_PROLOGUE : usize = 13 ;
208
208
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
211
212
212
213
const REGISTER_MAP : [ X86Register ; 11 ] = [
213
214
CALLER_SAVED_REGISTERS [ 0 ] , // RAX
@@ -980,8 +981,10 @@ impl<'a, C: ContextObject> JitCompiler<'a, C> {
980
981
981
982
#[ inline]
982
983
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 ) ) ) ;
985
988
}
986
989
987
990
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> {
1580
1583
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
1581
1584
self . emit_ins ( X86Instruction :: return_near ( ) ) ; // Tail call to host_target_address
1582
1585
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 ) ) ;
1584
1589
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
1585
1605
for ( anchor_base, len) in & [
1586
1606
( 0 , 1i32 ) , ( 0 , 2i32 ) , ( 0 , 4i32 ) , ( 0 , 8i32 ) ,
1587
1607
( 4 , 1i32 ) , ( 4 , 2i32 ) , ( 4 , 4i32 ) , ( 4 , 8i32 ) ,
0 commit comments