src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp
changeset 50104 4ea7917929b9
parent 49621 5ef28d560b6f
child 50411 0191ac1da300
--- a/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp	Mon May 14 15:43:00 2018 +0200
+++ b/src/hotspot/cpu/aarch64/nativeInst_aarch64.hpp	Mon May 14 12:03:59 2018 +0100
@@ -1,6 +1,6 @@
 /*
  * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
- * Copyright (c) 2014, Red Hat Inc. All rights reserved.
+ * Copyright (c) 2014, 2108, Red Hat Inc. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -95,6 +95,8 @@
   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; }
 
+  void wrote(int offset);
+
  public:
 
   // unit test stuff
@@ -148,6 +150,46 @@
   return (NativeInstruction*)address;
 }
 
+class NativePltCall: public NativeInstruction {
+public:
+  enum Arm_specific_constants {
+    instruction_size           =    4,
+    instruction_offset         =    0,
+    displacement_offset        =    1,
+    return_address_offset      =    4
+  };
+  address instruction_address() const { return addr_at(instruction_offset); }
+  address next_instruction_address() const { return addr_at(return_address_offset); }
+  address displacement_address() const { return addr_at(displacement_offset); }
+  int displacement() const { return (jint) int_at(displacement_offset); }
+  address return_address() const { return addr_at(return_address_offset); }
+  address destination() const;
+  address plt_entry() const;
+  address plt_jump() const;
+  address plt_load_got() const;
+  address plt_resolve_call() const;
+  address plt_c2i_stub() const;
+  void set_stub_to_clean();
+
+  void  reset_to_plt_resolve_call();
+  void  set_destination_mt_safe(address dest);
+
+  void verify() const;
+};
+
+inline NativePltCall* nativePltCall_at(address address) {
+  NativePltCall* call = (NativePltCall*) address;
+#ifdef ASSERT
+  call->verify();
+#endif
+  return call;
+}
+
+inline NativePltCall* nativePltCall_before(address addr) {
+  address at = addr - NativePltCall::instruction_size;
+  return nativePltCall_at(at);
+}
+
 inline NativeCall* nativeCall_at(address address);
 // The NativeCall is an abstraction for accessing/manipulating native
 // call instructions (used to manipulate inline caches, primitive &
@@ -169,7 +211,7 @@
   address return_address() const            { return addr_at(return_address_offset); }
   address destination() const;
 
-  void  set_destination(address dest)       {
+  void set_destination(address dest)        {
     int offset = dest - instruction_address();
     unsigned int insn = 0b100101 << 26;
     assert((offset & 3) == 0, "should be");
@@ -191,6 +233,12 @@
     return is_call_at(return_address - NativeCall::return_address_offset);
   }
 
+#if INCLUDE_AOT
+  static bool is_far_call(address instr, address target) {
+    return !Assembler::reachable_from_branch_at(instr, target);
+  }
+#endif
+
   // MT-safe patching of a call instruction.
   static void insert(address code_pos, address entry);
 
@@ -381,6 +429,39 @@
   static void test() {}
 };
 
+//   adrp    x16, #page
+//   add     x16, x16, #offset
+//   ldr     x16, [x16]
+class NativeLoadGot: public NativeInstruction {
+public:
+  enum AArch64_specific_constants {
+    instruction_length = 4 * NativeInstruction::instruction_size,
+    offset_offset = 0,
+  };
+
+  address instruction_address() const { return addr_at(0); }
+  address return_address() const { return addr_at(instruction_length); }
+  address got_address() const;
+  address next_instruction_address() const { return return_address(); }
+  intptr_t data() const;
+  void set_data(intptr_t data) {
+    intptr_t *addr = (intptr_t *) got_address();
+    *addr = data;
+  }
+
+  void verify() const;
+private:
+  void report_and_fail() const;
+};
+
+inline NativeLoadGot* nativeLoadGot_at(address addr) {
+  NativeLoadGot* load = (NativeLoadGot*) addr;
+#ifdef ASSERT
+  load->verify();
+#endif
+  return load;
+}
+
 class NativeJump: public NativeInstruction {
  public:
   enum AArch64_specific_constants {
@@ -441,6 +522,31 @@
   return jump;
 }
 
+class NativeGotJump: public NativeInstruction {
+public:
+  enum AArch64_specific_constants {
+    instruction_size = 4 * NativeInstruction::instruction_size,
+  };
+
+  void verify() const;
+  address instruction_address() const { return addr_at(0); }
+  address destination() const;
+  address return_address() const { return addr_at(instruction_size); }
+  address got_address() const;
+  address next_instruction_address() const { return addr_at(instruction_size); }
+  bool is_GotJump() const;
+
+  void set_jump_destination(address dest)  {
+    address* got = (address *)got_address();
+    *got = dest;
+  }
+};
+
+inline NativeGotJump* nativeGotJump_at(address addr) {
+  NativeGotJump* jump = (NativeGotJump*)(addr);
+  return jump;
+}
+
 class NativePopReg : public NativeInstruction {
  public:
   // Insert a pop instruction