src/cpu/aarch64/vm/nativeInst_aarch64.hpp

Print this page

        

@@ -51,10 +51,11 @@
 // The base class for different kinds of native instruction abstractions.
 // Provides the primitive operations to manipulate code relative to this.
 
 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
   friend class Relocation;
+  friend bool is_NativeCallTrampolineStub_at(address);
  public:
   enum { instruction_size = 4 };
   inline bool is_nop();
   bool is_dtrace_trap();
   inline bool is_illegal();

@@ -64,27 +65,30 @@
   inline bool is_cond_jump();
   bool is_safepoint_poll();
   inline bool is_mov_literal64();
   bool is_movz();
   bool is_movk();
+  bool is_sigill_zombie_not_entrant();
 
  protected:
   address addr_at(int offset) const    { return address(this) + offset; }
 
   s_char sbyte_at(int offset) const    { return *(s_char*) addr_at(offset); }
   u_char ubyte_at(int offset) const    { return *(u_char*) addr_at(offset); }
 
   jint int_at(int offset) const         { return *(jint*) addr_at(offset); }
+  juint uint_at(int offset) const      { return *(juint*) addr_at(offset); }
 
-  intptr_t ptr_at(int offset) const    { return *(intptr_t*) addr_at(offset); }
+  address ptr_at(int offset) const     { return *(address*) addr_at(offset); }
 
   oop  oop_at (int offset) const       { return *(oop*) addr_at(offset); }
 
 
   void set_char_at(int offset, char c)        { *addr_at(offset) = (u_char)c; }
   void set_int_at(int offset, jint  i)        { *(jint*)addr_at(offset) = i; }
-  void set_ptr_at (int offset, intptr_t  ptr) { *(intptr_t*) addr_at(offset) = ptr; }
+  void set_uint_at(int offset, jint  i)       { *(juint*)addr_at(offset) = i; }
+  void set_ptr_at (int offset, address  ptr)  { *(address*) addr_at(offset) = ptr; }
   void set_oop_at (int offset, oop  o)        { *(oop*) addr_at(offset) = o; }
 
  public:
 
   // unit test stuff

@@ -128,34 +132,21 @@
   address next_instruction_address() const  { return addr_at(return_address_offset); }
   int   displacement() const                { return (int_at(displacement_offset) << 6) >> 4; }
   address displacement_address() const      { return addr_at(displacement_offset); }
   address return_address() const            { return addr_at(return_address_offset); }
   address destination() const;
+
   void  set_destination(address dest)       {
     int offset = dest - instruction_address();
     unsigned int insn = 0b100101 << 26;
     assert((offset & 3) == 0, "should be");
     offset >>= 2;
     offset &= (1 << 26) - 1; // mask off insn part
     insn |= offset;
     set_int_at(displacement_offset, insn);
-    ICache::invalidate_range(instruction_address(), instruction_size);
   }
 
-  // Similar to replace_mt_safe, but just changes the destination.  The
-  // important thing is that free-running threads are able to execute
-  // this call instruction at all times.  If the call is an immediate BL
-  // instruction we can simply rely on atomicity of 32-bit writes to
-  // make sure other threads will see no intermediate states.
-
-  // We cannot rely on locks here, since the free-running threads must run at
-  // full speed.
-  //
-  // Used in the runtime linkage of calls; see class CompiledIC.
-  // (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.)
-  void  set_destination_mt_safe(address dest) { set_destination(dest); }
-
   void  verify_alignment()                       { ; }
   void  verify();
   void  print();
 
   // Creation

@@ -173,10 +164,27 @@
 
   // MT-safe patching of a call instruction.
   static void insert(address code_pos, address entry);
 
   static void replace_mt_safe(address instr_addr, address code_buffer);
+
+  // Similar to replace_mt_safe, but just changes the destination.  The
+  // important thing is that free-running threads are able to execute
+  // this call instruction at all times.  If the call is an immediate BL
+  // instruction we can simply rely on atomicity of 32-bit writes to
+  // make sure other threads will see no intermediate states.
+
+  // We cannot rely on locks here, since the free-running threads must run at
+  // full speed.
+  //
+  // Used in the runtime linkage of calls; see class CompiledIC.
+  // (Cf. 4506997 and 4479829, where threads witnessed garbage displacements.)
+
+  // The parameter assert_lock disables the assertion during code generation.
+  void set_destination_mt_safe(address dest, bool assert_lock = true);
+
+  address get_trampoline();
 };
 
 inline NativeCall* nativeCall_at(address address) {
   NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset);
 #ifdef ASSERT

@@ -376,14 +384,14 @@
 }
 
 class NativeGeneralJump: public NativeJump {
 public:
   enum AArch64_specific_constants {
-    instruction_size            =    4,
+    instruction_size            =    4 * 4,
     instruction_offset          =    0,
     data_offset                 =    0,
-    next_instruction_offset     =    4
+    next_instruction_offset     =    4 * 4
   };
   static void insert_unconditional(address code_pos, address entry);
   static void replace_mt_safe(address instr_addr, address code_buffer);
   static void verify();
 };

@@ -448,6 +456,36 @@
 
 inline bool NativeInstruction::is_jump_or_nop() {
   return is_nop() || is_jump();
 }
 
+// Call trampoline stubs.
+class NativeCallTrampolineStub : public NativeInstruction {
+ public:
+
+  enum AArch64_specific_constants {
+    instruction_size            =    4 * 4,
+    instruction_offset          =    0,
+    data_offset                 =    2 * 4,
+    next_instruction_offset     =    4 * 4
+  };
+
+  address destination(nmethod *nm = NULL) const;
+  void set_destination(address new_destination);
+  ptrdiff_t destination_offset() const;
+};
+
+inline bool is_NativeCallTrampolineStub_at(address addr) {
+  // Ensure that the stub is exactly
+  //      ldr   xscratch1, L
+  //      br    xscratch1
+  // L:
+  uint32_t *i = (uint32_t *)addr;
+  return i[0] == 0x58000048 && i[1] == 0xd61f0100;
+}
+
+inline NativeCallTrampolineStub* nativeCallTrampolineStub_at(address addr) {
+  assert(is_NativeCallTrampolineStub_at(addr), "no call trampoline found");
+  return (NativeCallTrampolineStub*)addr;
+}
+
 #endif // CPU_AARCH64_VM_NATIVEINST_AARCH64_HPP