[aarch64-port-dev ] Problematic frame: ~BufferBlob::native signature handlers

Andrew Haley aph at redhat.com
Wed Sep 4 02:59:48 PDT 2013


On 09/04/2013 06:39 AM, Cao Hoang Thu wrote:
> I got error when run any java command: (example: java -version or java)
> 
> # A fatal error has been detected by the Java Runtime Environment:
> #
> #  SIGILL (0x4) at pc=0x0000007f920c281c, pid=1910, tid=548033499664
> #
> # JRE version:  (8.0) (build )
> # Java VM: OpenJDK 64-Bit Client VM (25.0-b22 mixed mode linux-aarch64 )
> # Problematic frame:
> # v  ~BufferBlob::native signature handlers
> #
> # Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
> #
> # If you would like to submit a bug report, please visit:
> #   http://bugreport.sun.com/bugreport/crash.jsp
> #

Yes, we know about this one.  It's a cache flush bug that affects some
environments.  Try this patch.

Andrew.


# HG changeset patch
# User aph
# Date 1378288603 -3600
# Node ID d3018f52f95024ab552222f1086fa2b94a502d6f
# Parent  39453e27d28bb97d40e138103e49c33d3758177f
Implement ICacheStubGenerator::generate_icache_flush

diff -r 39453e27d28b -r d3018f52f950 src/cpu/aarch64/vm/assembler_aarch64.hpp
--- a/src/cpu/aarch64/vm/assembler_aarch64.hpp	Wed Sep 04 10:55:35 2013 +0100
+++ b/src/cpu/aarch64/vm/assembler_aarch64.hpp	Wed Sep 04 10:56:43 2013 +0100
@@ -978,6 +978,14 @@
     system(0b00, 0b011, 0b00011, SY, 0b110);
   }

+  void dc(Register Rt) {
+    system(0b01, 0b011, 0b0111, 0b1011, 0b001, Rt);
+  }
+
+  void ic(Register Rt) {
+    system(0b01, 0b011, 0b0111, 0b0101, 0b001, Rt);
+  }
+
   // Unconditional branch (register)
   void branch_reg(Register R, int opc) {
     starti;
diff -r 39453e27d28b -r d3018f52f950 src/cpu/aarch64/vm/icache_aarch64.cpp
--- a/src/cpu/aarch64/vm/icache_aarch64.cpp	Wed Sep 04 10:55:35 2013 +0100
+++ b/src/cpu/aarch64/vm/icache_aarch64.cpp	Wed Sep 04 10:56:43 2013 +0100
@@ -33,21 +33,13 @@

 #define __ _masm->

-int _flush_icache_stub_dummy(address addr, int lines, int magic)
-{
-  // no need to do any cache flushing on x86 so just obey the implicit
-  // contract to return the magic arg
-
-  return magic;
-}
-
 void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) {

   aarch64TestHook();

   StubCodeMark mark(this, "ICache", "flush_icache_stub");

-  address start = __ pc();
+  address entry = __ pc();

   // generate a c stub prolog which will bootstrap into the ARM code
   // which follows, loading the 3 general registers passed by the
@@ -57,24 +49,21 @@
   __ c_stub_prolog(3, 0, MacroAssembler::ret_type_integral);
 #endif

-  address entry = __ pc();
+  Register start = r0, lines = r1, auto_magic = r2;

-  // hmm, think we probably need an instruction synchronizaton barrier
-  // and a memory and data synchronization barrier but we will find
-  // out when we get real hardware :-)
+  // First flush the dcache
+  __ generate_flush_loop(&Assembler::dc, start, lines);

-  // n.b. SY means a system wide barrier which is the overkill option
+  __ dsb(Assembler::SY);

-  address loop = __ pc();
-  __ dsb(Assembler::SY);
-  __ isb();
-  // args 1 and 2 identify the start address and size of the flush
-  // region but we cannot use them on ARM. the stub is supposed to
-  // return the 3rd argument
-  __ mov(r0, r2);
+  // And then the icache
+  __ generate_flush_loop(&Assembler::ic, start, lines);
+
+  // the stub is supposed to return the 3rd argument
+  __ mov(r0, auto_magic);
   __ ret(r30);

-  *flush_icache_stub =  (ICache::flush_icache_stub_t)start;
+  *flush_icache_stub =  (ICache::flush_icache_stub_t)entry;
 }

 #undef __
diff -r 39453e27d28b -r d3018f52f950 src/cpu/aarch64/vm/icache_aarch64.hpp
--- a/src/cpu/aarch64/vm/icache_aarch64.hpp	Wed Sep 04 10:55:35 2013 +0100
+++ b/src/cpu/aarch64/vm/icache_aarch64.hpp	Wed Sep 04 10:56:43 2013 +0100
@@ -30,16 +30,6 @@
 // Interface for updating the instruction cache.  Whenever the VM modifies
 // code, part of the processor instruction cache potentially has to be flushed.

-// On the x86, this is a no-op -- the I-cache is guaranteed to be consistent
-// after the next jump, and the VM never modifies instructions directly ahead
-// of the instruction fetch path.
-
-// [phh] It's not clear that the above comment is correct, because on an MP
-// system where the dcaches are not snooped, only the thread doing the invalidate
-// will see the update.  Even in the snooped case, a memory fence would be
-// necessary if stores weren't ordered.  Fortunately, they are on all known
-// x86 implementations.
-
 class ICache : public AbstractICache {
  public:
   enum {
diff -r 39453e27d28b -r d3018f52f950 src/cpu/aarch64/vm/macroAssembler_aarch64.cpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Sep 04 10:55:35 2013 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.cpp	Wed Sep 04 10:56:43 2013 +0100
@@ -2588,3 +2588,19 @@
   }
 }

+void MacroAssembler::generate_flush_loop(flush_insn flush, Register start, Register lines) {
+  Label again, exit;
+
+  assert_different_registers(start, lines, rscratch1, rscratch2);
+
+  cmp(lines, zr);
+  br(Assembler::LE, exit);
+  mov(rscratch1, start);
+  mov(rscratch2, lines);
+  bind(again);
+  (this->*flush)(rscratch1);
+  sub(rscratch2, rscratch2, 1);
+  add(rscratch1, rscratch1, ICache::line_size);
+  cbnz(rscratch2, again);
+  bind(exit);
+}
diff -r 39453e27d28b -r d3018f52f950 src/cpu/aarch64/vm/macroAssembler_aarch64.hpp
--- a/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Wed Sep 04 10:55:35 2013 +0100
+++ b/src/cpu/aarch64/vm/macroAssembler_aarch64.hpp	Wed Sep 04 10:56:43 2013 +0100
@@ -1365,6 +1365,9 @@
   }

   address read_polling_page(Register r, address page, relocInfo::relocType rtype);
+
+  typedef void (Assembler::* flush_insn)(Register Rt);
+  void generate_flush_loop(flush_insn flush, Register start, Register lines);
 };

 #ifdef ASSERT
diff -r 39453e27d28b -r d3018f52f950 src/share/vm/runtime/icache.cpp
--- a/src/share/vm/runtime/icache.cpp	Wed Sep 04 10:55:35 2013 +0100
+++ b/src/share/vm/runtime/icache.cpp	Wed Sep 04 10:56:43 2013 +0100
@@ -55,8 +55,8 @@
   static int magic = 0xbaadbabe;

   int auto_magic = magic; // Make a local copy to avoid race condition
-  // int r = (*_flush_icache_stub)(start, lines, auto_magic);
-  // guarantee(r == auto_magic, "flush stub routine did not execute");
+  int r = (*_flush_icache_stub)(start, lines, auto_magic);
+  guarantee(r == auto_magic, "flush stub routine did not execute");
   ++magic;
 }




More information about the aarch64-port-dev mailing list