< prev index next >

src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp

Print this page
rev 48402 : 8193260: AArch64: JVMCI: Implement trampoline calls
Reviewed-by: adinn


  44 // - - NativeReturn
  45 // - - NativeReturnX (return with argument)
  46 // - - NativePushConst
  47 // - - NativeTstRegMem
  48 
  49 // The base class for different kinds of native instruction abstractions.
  50 // Provides the primitive operations to manipulate code relative to this.
  51 
  52 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
  53   friend class Relocation;
  54   friend bool is_NativeCallTrampolineStub_at(address);
  55  public:
  56   enum {
  57     instruction_size = 4
  58   };
  59 
  60   juint encoding() const {
  61     return uint_at(0);
  62   }
  63 
  64   bool is_blr()                      const { return (encoding() & 0xfffffc1f) == 0xd63f0000; }
  65   bool is_adr_aligned()              const { return (encoding() & 0xff000000) == 0x10000000; } // adr Xn, <label>, where label is aligned to 4 bytes (address of instruction).
  66 
  67   inline bool is_nop();
  68   inline bool is_illegal();
  69   inline bool is_return();
  70   bool is_jump();
  71   bool is_general_jump();
  72   inline bool is_jump_or_nop();
  73   inline bool is_cond_jump();
  74   bool is_safepoint_poll();
  75   bool is_movz();
  76   bool is_movk();
  77   bool is_sigill_zombie_not_entrant();
  78 
  79  protected:
  80   address addr_at(int offset) const    { return address(this) + offset; }
  81 
  82   s_char sbyte_at(int offset) const    { return *(s_char*) addr_at(offset); }
  83   u_char ubyte_at(int offset) const    { return *(u_char*) addr_at(offset); }
  84 


 126     return is_adrp_at(instr) || is_ldr_literal_at(instr);
 127   }
 128 
 129   bool is_Membar() {
 130     unsigned int insn = uint_at(0);
 131     return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
 132       Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
 133   }
 134 };
 135 
 136 inline NativeInstruction* nativeInstruction_at(address address) {
 137   return (NativeInstruction*)address;
 138 }
 139 
 140 // The natural type of an AArch64 instruction is uint32_t
 141 inline NativeInstruction* nativeInstruction_at(uint32_t *address) {
 142   return (NativeInstruction*)address;
 143 }
 144 
 145 inline NativeCall* nativeCall_at(address address);
 146 // The NativeCall is an abstraction for accessing/manipulating native call imm32/rel32off
 147 // instructions (used to manipulate inline caches, primitive & dll calls, etc.).

 148 
 149 class NativeCall: public NativeInstruction {
 150  public:
 151   enum Aarch64_specific_constants {
 152     instruction_size            =    4,
 153     instruction_offset          =    0,
 154     displacement_offset         =    0,
 155     return_address_offset       =    4
 156   };
 157 
 158   enum { cache_line_size = BytesPerWord };  // conservative estimate!
 159   address instruction_address() const       { return addr_at(instruction_offset); }
 160   address next_instruction_address() const  { return addr_at(return_address_offset); }
 161   int   displacement() const                { return (int_at(displacement_offset) << 6) >> 4; }
 162   address displacement_address() const      { return addr_at(displacement_offset); }
 163   address return_address() const            { return addr_at(return_address_offset); }
 164   address destination() const;
 165 
 166   void  set_destination(address dest)       {
 167     int offset = dest - instruction_address();
 168     unsigned int insn = 0b100101 << 26;
 169     assert((offset & 3) == 0, "should be");
 170     offset >>= 2;
 171     offset &= (1 << 26) - 1; // mask off insn part
 172     insn |= offset;
 173     set_int_at(displacement_offset, insn);
 174   }
 175 
 176   void  verify_alignment()                       { ; }
 177   void  verify();
 178   void  print();


 189   static void insert(address code_pos, address entry);
 190 
 191   static void replace_mt_safe(address instr_addr, address code_buffer);
 192 
 193   // Similar to replace_mt_safe, but just changes the destination.  The
 194   // important thing is that free-running threads are able to execute
 195   // this call instruction at all times.  If the call is an immediate BL
 196   // instruction we can simply rely on atomicity of 32-bit writes to
 197   // make sure other threads will see no intermediate states.
 198 
 199   // We cannot rely on locks here, since the free-running threads must run at
 200   // full speed.
 201   //
 202   // Used in the runtime linkage of calls; see class CompiledIC.
 203   // (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.)
 204 
 205   // The parameter assert_lock disables the assertion during code generation.
 206   void set_destination_mt_safe(address dest, bool assert_lock = true);
 207 
 208   address get_trampoline();

 209 };
 210 
 211 inline NativeCall* nativeCall_at(address address) {
 212   NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset);
 213 #ifdef ASSERT
 214   call->verify();
 215 #endif
 216   return call;
 217 }
 218 
 219 inline NativeCall* nativeCall_before(address return_address) {
 220   NativeCall* call = (NativeCall*)(return_address - NativeCall::return_address_offset);
 221 #ifdef ASSERT
 222   call->verify();
 223 #endif
 224   return call;
 225 }
 226 
 227 // An interface for accessing/manipulating native mov reg, imm instructions.
 228 // (used to manipulate inlined 64-bit data calls, etc.)




  44 // - - NativeReturn
  45 // - - NativeReturnX (return with argument)
  46 // - - NativePushConst
  47 // - - NativeTstRegMem
  48 
  49 // The base class for different kinds of native instruction abstractions.
  50 // Provides the primitive operations to manipulate code relative to this.
  51 
  52 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
  53   friend class Relocation;
  54   friend bool is_NativeCallTrampolineStub_at(address);
  55  public:
  56   enum {
  57     instruction_size = 4
  58   };
  59 
  60   juint encoding() const {
  61     return uint_at(0);
  62   }
  63 
  64   bool is_blr()                      const { return (encoding() & 0xff9ffc1f) == 0xd61f0000; } // blr(register) or br(register)
  65   bool is_adr_aligned()              const { return (encoding() & 0xff000000) == 0x10000000; } // adr Xn, <label>, where label is aligned to 4 bytes (address of instruction).
  66 
  67   inline bool is_nop();
  68   inline bool is_illegal();
  69   inline bool is_return();
  70   bool is_jump();
  71   bool is_general_jump();
  72   inline bool is_jump_or_nop();
  73   inline bool is_cond_jump();
  74   bool is_safepoint_poll();
  75   bool is_movz();
  76   bool is_movk();
  77   bool is_sigill_zombie_not_entrant();
  78 
  79  protected:
  80   address addr_at(int offset) const    { return address(this) + offset; }
  81 
  82   s_char sbyte_at(int offset) const    { return *(s_char*) addr_at(offset); }
  83   u_char ubyte_at(int offset) const    { return *(u_char*) addr_at(offset); }
  84 


 126     return is_adrp_at(instr) || is_ldr_literal_at(instr);
 127   }
 128 
 129   bool is_Membar() {
 130     unsigned int insn = uint_at(0);
 131     return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
 132       Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
 133   }
 134 };
 135 
 136 inline NativeInstruction* nativeInstruction_at(address address) {
 137   return (NativeInstruction*)address;
 138 }
 139 
 140 // The natural type of an AArch64 instruction is uint32_t
 141 inline NativeInstruction* nativeInstruction_at(uint32_t *address) {
 142   return (NativeInstruction*)address;
 143 }
 144 
 145 inline NativeCall* nativeCall_at(address address);
 146 // The NativeCall is an abstraction for accessing/manipulating native
 147 // call instructions (used to manipulate inline caches, primitive &
 148 // DSO calls, etc.).
 149 
 150 class NativeCall: public NativeInstruction {
 151  public:
 152   enum Aarch64_specific_constants {
 153     instruction_size            =    4,
 154     instruction_offset          =    0,
 155     displacement_offset         =    0,
 156     return_address_offset       =    4
 157   };
 158 

 159   address instruction_address() const       { return addr_at(instruction_offset); }
 160   address next_instruction_address() const  { return addr_at(return_address_offset); }
 161   int   displacement() const                { return (int_at(displacement_offset) << 6) >> 4; }
 162   address displacement_address() const      { return addr_at(displacement_offset); }
 163   address return_address() const            { return addr_at(return_address_offset); }
 164   address destination() const;
 165 
 166   void  set_destination(address dest)       {
 167     int offset = dest - instruction_address();
 168     unsigned int insn = 0b100101 << 26;
 169     assert((offset & 3) == 0, "should be");
 170     offset >>= 2;
 171     offset &= (1 << 26) - 1; // mask off insn part
 172     insn |= offset;
 173     set_int_at(displacement_offset, insn);
 174   }
 175 
 176   void  verify_alignment()                       { ; }
 177   void  verify();
 178   void  print();


 189   static void insert(address code_pos, address entry);
 190 
 191   static void replace_mt_safe(address instr_addr, address code_buffer);
 192 
 193   // Similar to replace_mt_safe, but just changes the destination.  The
 194   // important thing is that free-running threads are able to execute
 195   // this call instruction at all times.  If the call is an immediate BL
 196   // instruction we can simply rely on atomicity of 32-bit writes to
 197   // make sure other threads will see no intermediate states.
 198 
 199   // We cannot rely on locks here, since the free-running threads must run at
 200   // full speed.
 201   //
 202   // Used in the runtime linkage of calls; see class CompiledIC.
 203   // (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.)
 204 
 205   // The parameter assert_lock disables the assertion during code generation.
 206   void set_destination_mt_safe(address dest, bool assert_lock = true);
 207 
 208   address get_trampoline();
 209   address trampoline_jump(CodeBuffer &cbuf, address dest);
 210 };
 211 
 212 inline NativeCall* nativeCall_at(address address) {
 213   NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset);
 214 #ifdef ASSERT
 215   call->verify();
 216 #endif
 217   return call;
 218 }
 219 
 220 inline NativeCall* nativeCall_before(address return_address) {
 221   NativeCall* call = (NativeCall*)(return_address - NativeCall::return_address_offset);
 222 #ifdef ASSERT
 223   call->verify();
 224 #endif
 225   return call;
 226 }
 227 
 228 // An interface for accessing/manipulating native mov reg, imm instructions.
 229 // (used to manipulate inlined 64-bit data calls, etc.)


< prev index next >