< prev index next >

src/cpu/aarch64/vm/nativeInst_aarch64.hpp

Print this page
rev 9228 : 8143072: Port JVMCI to AArch64
Summary: AArch64-specific code for JVMCI
Reviewed-by: duke


  45 // - - NativeReturn
  46 // - - NativeReturnX (return with argument)
  47 // - - NativePushConst
  48 // - - NativeTstRegMem
  49 
  50 // The base class for different kinds of native instruction abstractions.
  51 // Provides the primitive operations to manipulate code relative to this.
  52 
  53 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
  54   friend class Relocation;
  55   friend bool is_NativeCallTrampolineStub_at(address);
  56  public:
  57   enum { instruction_size = 4 };
  58   inline bool is_nop();
  59   inline bool is_illegal();
  60   inline bool is_return();
  61   bool is_jump();
  62   inline bool is_jump_or_nop();
  63   inline bool is_cond_jump();
  64   bool is_safepoint_poll();
  65   inline bool is_mov_literal64();
  66   bool is_movz();
  67   bool is_movk();
  68   bool is_sigill_zombie_not_entrant();
  69 
  70  protected:
  71   address addr_at(int offset) const    { return address(this) + offset; }
  72 
  73   s_char sbyte_at(int offset) const    { return *(s_char*) addr_at(offset); }
  74   u_char ubyte_at(int offset) const    { return *(u_char*) addr_at(offset); }
  75 
  76   jint int_at(int offset) const        { return *(jint*) addr_at(offset); }
  77   juint uint_at(int offset) const      { return *(juint*) addr_at(offset); }
  78 
  79   address ptr_at(int offset) const     { return *(address*) addr_at(offset); }
  80 
  81   oop  oop_at (int offset) const       { return *(oop*) addr_at(offset); }
  82 
  83 
  84   void set_char_at(int offset, char c)        { *addr_at(offset) = (u_char)c; }
  85   void set_int_at(int offset, jint  i)        { *(jint*)addr_at(offset) = i; }
  86   void set_uint_at(int offset, jint  i)       { *(juint*)addr_at(offset) = i; }
  87   void set_ptr_at (int offset, address  ptr)  { *(address*) addr_at(offset) = ptr; }
  88   void set_oop_at (int offset, oop  o)        { *(oop*) addr_at(offset) = o; }
  89 
  90  public:
  91 
  92   // unit test stuff
  93   static void test() {}                 // override for testing
  94 
  95   inline friend NativeInstruction* nativeInstruction_at(address address);
  96 
  97   static bool is_adrp_at(address instr);
  98   static bool is_ldr_literal_at(address instr);
  99   static bool is_ldrw_to_zr(address instr);
 100 








 101   static bool maybe_cpool_ref(address instr) {
 102     return is_adrp_at(instr) || is_ldr_literal_at(instr);
 103   }
 104 
 105   bool is_Membar() {
 106     unsigned int insn = uint_at(0);
 107     return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
 108       Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
 109   }
 110 };
 111 
 112 inline NativeInstruction* nativeInstruction_at(address address) {
 113   return (NativeInstruction*)address;
 114 }
 115 
 116 // The natural type of an AArch64 instruction is uint32_t
 117 inline NativeInstruction* nativeInstruction_at(uint32_t *address) {
 118   return (NativeInstruction*)address;
 119 }
 120 


 139   address return_address() const            { return addr_at(return_address_offset); }
 140   address destination() const;
 141 
 142   void  set_destination(address dest)       {
 143     int offset = dest - instruction_address();
 144     unsigned int insn = 0b100101 << 26;
 145     assert((offset & 3) == 0, "should be");
 146     offset >>= 2;
 147     offset &= (1 << 26) - 1; // mask off insn part
 148     insn |= offset;
 149     set_int_at(displacement_offset, insn);
 150   }
 151 
 152   void  verify_alignment()                       { ; }
 153   void  verify();
 154   void  print();
 155 
 156   // Creation
 157   inline friend NativeCall* nativeCall_at(address address);
 158   inline friend NativeCall* nativeCall_before(address return_address);
 159 
 160   static bool is_call_at(address instr) {
 161     const uint32_t insn = (*(uint32_t*)instr);
 162     return (insn >> 26) == 0b100101;
 163   }
 164 
 165   static bool is_call_before(address return_address) {
 166     return is_call_at(return_address - NativeCall::return_address_offset);
 167   }
 168 
 169   // MT-safe patching of a call instruction.
 170   static void insert(address code_pos, address entry);
 171 
 172   static void replace_mt_safe(address instr_addr, address code_buffer);
 173 
 174   // Similar to replace_mt_safe, but just changes the destination.  The
 175   // important thing is that free-running threads are able to execute
 176   // this call instruction at all times.  If the call is an immediate BL
 177   // instruction we can simply rely on atomicity of 32-bit writes to
 178   // make sure other threads will see no intermediate states.
 179 
 180   // We cannot rely on locks here, since the free-running threads must run at
 181   // full speed.
 182   //
 183   // Used in the runtime linkage of calls; see class CompiledIC.




  45 // - - NativeReturn
  46 // - - NativeReturnX (return with argument)
  47 // - - NativePushConst
  48 // - - NativeTstRegMem
  49 
  50 // The base class for different kinds of native instruction abstractions.
  51 // Provides the primitive operations to manipulate code relative to this.
  52 
  53 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
  54   friend class Relocation;
  55   friend bool is_NativeCallTrampolineStub_at(address);
  56  public:
  57   enum { instruction_size = 4 };
  58   inline bool is_nop();
  59   inline bool is_illegal();
  60   inline bool is_return();
  61   bool is_jump();
  62   inline bool is_jump_or_nop();
  63   inline bool is_cond_jump();
  64   bool is_safepoint_poll();

  65   bool is_movz();
  66   bool is_movk();
  67   bool is_sigill_zombie_not_entrant();
  68 
  69  protected:
  70   address addr_at(int offset) const    { return address(this) + offset; }
  71 
  72   s_char sbyte_at(int offset) const    { return *(s_char*) addr_at(offset); }
  73   u_char ubyte_at(int offset) const    { return *(u_char*) addr_at(offset); }
  74 
  75   jint int_at(int offset) const        { return *(jint*) addr_at(offset); }
  76   juint uint_at(int offset) const      { return *(juint*) addr_at(offset); }
  77 
  78   address ptr_at(int offset) const     { return *(address*) addr_at(offset); }
  79 
  80   oop  oop_at (int offset) const       { return *(oop*) addr_at(offset); }
  81 
  82 
  83   void set_char_at(int offset, char c)        { *addr_at(offset) = (u_char)c; }
  84   void set_int_at(int offset, jint  i)        { *(jint*)addr_at(offset) = i; }
  85   void set_uint_at(int offset, jint  i)       { *(juint*)addr_at(offset) = i; }
  86   void set_ptr_at (int offset, address  ptr)  { *(address*) addr_at(offset) = ptr; }
  87   void set_oop_at (int offset, oop  o)        { *(oop*) addr_at(offset) = o; }
  88 
  89  public:
  90 
  91   // unit test stuff
  92   static void test() {}                 // override for testing
  93 
  94   inline friend NativeInstruction* nativeInstruction_at(address address);
  95 
  96   static bool is_adrp_at(address instr);
  97   static bool is_ldr_literal_at(address instr);
  98   static bool is_ldrw_to_zr(address instr);
  99 
 100   static bool is_call_at(address instr) {
 101     const uint32_t insn = (*(uint32_t*)instr);
 102     return (insn >> 26) == 0b100101;
 103   }
 104   bool is_call() {
 105     return is_call_at(addr_at(0));
 106   }
 107 
 108   static bool maybe_cpool_ref(address instr) {
 109     return is_adrp_at(instr) || is_ldr_literal_at(instr);
 110   }
 111 
 112   bool is_Membar() {
 113     unsigned int insn = uint_at(0);
 114     return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
 115       Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
 116   }
 117 };
 118 
 119 inline NativeInstruction* nativeInstruction_at(address address) {
 120   return (NativeInstruction*)address;
 121 }
 122 
 123 // The natural type of an AArch64 instruction is uint32_t
 124 inline NativeInstruction* nativeInstruction_at(uint32_t *address) {
 125   return (NativeInstruction*)address;
 126 }
 127 


 146   address return_address() const            { return addr_at(return_address_offset); }
 147   address destination() const;
 148 
 149   void  set_destination(address dest)       {
 150     int offset = dest - instruction_address();
 151     unsigned int insn = 0b100101 << 26;
 152     assert((offset & 3) == 0, "should be");
 153     offset >>= 2;
 154     offset &= (1 << 26) - 1; // mask off insn part
 155     insn |= offset;
 156     set_int_at(displacement_offset, insn);
 157   }
 158 
 159   void  verify_alignment()                       { ; }
 160   void  verify();
 161   void  print();
 162 
 163   // Creation
 164   inline friend NativeCall* nativeCall_at(address address);
 165   inline friend NativeCall* nativeCall_before(address return_address);





 166 
 167   static bool is_call_before(address return_address) {
 168     return is_call_at(return_address - NativeCall::return_address_offset);
 169   }
 170 
 171   // MT-safe patching of a call instruction.
 172   static void insert(address code_pos, address entry);
 173 
 174   static void replace_mt_safe(address instr_addr, address code_buffer);
 175 
 176   // Similar to replace_mt_safe, but just changes the destination.  The
 177   // important thing is that free-running threads are able to execute
 178   // this call instruction at all times.  If the call is an immediate BL
 179   // instruction we can simply rely on atomicity of 32-bit writes to
 180   // make sure other threads will see no intermediate states.
 181 
 182   // We cannot rely on locks here, since the free-running threads must run at
 183   // full speed.
 184   //
 185   // Used in the runtime linkage of calls; see class CompiledIC.


< prev index next >