[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