Merge
authorroland
Fri, 16 Oct 2015 11:47:04 +0000
changeset 33194 1af73c83efae
parent 33192 31b8f55e4c08 (current diff)
parent 33193 c7ffe5c06513 (diff)
child 33195 43b1272dbac7
child 33196 3d84eedbd82c
Merge
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Thu Oct 15 15:33:54 2015 +0000
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Fri Oct 16 11:47:04 2015 +0000
@@ -1709,6 +1709,20 @@
   return idivq_offset;
 }
 
+void MacroAssembler::membar(Membar_mask_bits order_constraint) {
+  address prev = pc() - NativeMembar::instruction_size;
+  if (prev == code()->last_membar()) {
+    NativeMembar *bar = NativeMembar_at(prev);
+    // We are merging two memory barrier instructions.  On AArch64 we
+    // can do this simply by ORing them together.
+    bar->set_kind(bar->get_kind() | order_constraint);
+    BLOCK_COMMENT("merged membar");
+  } else {
+    code()->set_last_membar(pc());
+    dmb(Assembler::barrier(order_constraint));
+  }
+}
+
 // MacroAssembler routines found actually to be needed
 
 void MacroAssembler::push(Register src)
--- a/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Thu Oct 15 15:33:54 2015 +0000
+++ b/hotspot/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Fri Oct 16 11:47:04 2015 +0000
@@ -152,6 +152,13 @@
     strw(scratch, a);
   }
 
+  void bind(Label& L) {
+    Assembler::bind(L);
+    code()->clear_last_membar();
+  }
+
+  void membar(Membar_mask_bits order_constraint);
+
   // Frame creation and destruction shared between JITs.
   void build_frame(int framesize);
   void remove_frame(int framesize);
--- a/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp	Thu Oct 15 15:33:54 2015 +0000
+++ b/hotspot/src/cpu/aarch64/vm/nativeInst_aarch64.hpp	Fri Oct 16 11:47:04 2015 +0000
@@ -101,6 +101,12 @@
   static bool maybe_cpool_ref(address instr) {
     return is_adrp_at(instr) || is_ldr_literal_at(instr);
   }
+
+  bool is_Membar() {
+    unsigned int insn = uint_at(0);
+    return Instruction_aarch64::extract(insn, 31, 12) == 0b11010101000000110011 &&
+      Instruction_aarch64::extract(insn, 7, 0) == 0b10111111;
+  }
 };
 
 inline NativeInstruction* nativeInstruction_at(address address) {
@@ -487,4 +493,15 @@
   return (NativeCallTrampolineStub*)addr;
 }
 
+class NativeMembar : public NativeInstruction {
+public:
+  unsigned int get_kind() { return Instruction_aarch64::extract(uint_at(0), 11, 8); }
+  void set_kind(int order_kind) { Instruction_aarch64::patch(addr_at(0), 11, 8, order_kind); }
+};
+
+inline NativeMembar *NativeMembar_at(address addr) {
+  assert(nativeInstruction_at(addr)->is_Membar(), "no membar found");
+  return (NativeMembar*)addr;
+}
+
 #endif // CPU_AARCH64_VM_NATIVEINST_AARCH64_HPP
--- a/hotspot/src/share/vm/asm/codeBuffer.hpp	Thu Oct 15 15:33:54 2015 +0000
+++ b/hotspot/src/share/vm/asm/codeBuffer.hpp	Fri Oct 16 11:47:04 2015 +0000
@@ -375,6 +375,8 @@
   OopRecorder  _default_oop_recorder;  // override with initialize_oop_recorder
   Arena*       _overflow_arena;
 
+  address      _last_membar;     // used to merge consecutive memory barriers
+
   address      _decode_begin;   // start address for decode
   address      decode_begin();
 
@@ -388,6 +390,7 @@
     _decode_begin    = NULL;
     _overflow_arena  = NULL;
     _code_strings    = CodeStrings();
+    _last_membar     = NULL;
   }
 
   void initialize(address code_start, csize_t code_size) {
@@ -577,6 +580,10 @@
   OopRecorder* oop_recorder() const   { return _oop_recorder; }
   CodeStrings& strings()              { return _code_strings; }
 
+  address last_membar() const { return _last_membar; }
+  void set_last_membar(address a) { _last_membar = a; }
+  void clear_last_membar() { set_last_membar(NULL); }
+
   void free_strings() {
     if (!_code_strings.is_null()) {
       _code_strings.free(); // sets _strings Null as a side-effect.