Closed shining1984 closed 11 months ago
--- a/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
@@ -429,8 +429,8 @@ static void gen_c2i_adapter(MacroAssembler *masm,
// must be only an int (or less ) so move only 32bits to slot
__ sw(r, Address(sp, st_off));
} else {
- __ sw(r, Address(sp, next_off));
- __ sw(r_2->as_Register(), Address(sp, st_off));
+ __ sw(zr, Address(sp, next_off));
+ __ sw(zr, Address(sp, st_off));
}
} else {
assert(r_1->is_FloatRegister(), "");
通过对gen_c2i_adapter()对应位置的修改,也可以证明,gen_c2i_adapter的内容实际上对目前的问题没有影响。
riscv32目录下,以x11和successor为关键字,分别进行了排查,没有发现高低位寄存器内容放反的地方。
riscv32.ad 中有 return OptoRegPair(hi[ideal_reg], lo[ideal_reg]); 这个表达,arm32和rv64都是这种表达。把高位放到前边,有点奇怪。 把riscv32.ad 中的x11和x10都交换了位置,也没有影响现在的运行结果。
https://github.com/openjdk-riscv/jdk11u/pull/582 修改了 x10/x11 在save/restore_native_result中的顺序,并未影响运行结果。 也就是这里的T_LONG的处理,和当前的问题无关。
目前这个数据是会通过long_move()的<R.R>-><R.R>分支的,如果将分支内的代码改为:
--- a/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
@@ -831,8 +831,8 @@ static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) {
if (dst.second()->is_reg()) {
//<R.R>-><R.R>
assert(dst.first()->is_reg() && dst.second()->is_reg() && src.first()->is_reg() && src.second()->is_reg(), "must be");
- __ mv(dst.first()->as_Register(), src.first()->as_Register());
- __ mv(dst.second()->as_Register(), src.second()->as_Register());
+ __ mv(dst.first()->as_Register(), src.second()->as_Register());
+ __ mv(dst.second()->as_Register(), src.first()->as_Register());
} else {
//<R.R>-><R.S>
assert(dst.first()->is_reg() && dst.second()->is_reg() && src.first()->is_reg() && src.second()->is_stack(), "must be");
也会让offset的问题跳过,直接到达readdir的错误。但是这里显然不能这么改。根据之前的推测,这里的修改如同i2c修改一样,错误的地方应该还在这个环节之后。
riscv32.ad中的 MachSpillCopyNode::implementation()中的寄存器高低位交换,会引发更早的错误。 具体修改如下:
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -1157,10 +1157,10 @@ uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, boo
case rc_int:
if (dst_lo_rc == rc_int) { // gpr --> gpr copy
__ mv(as_Register(Matcher::_regEncode[dst_lo]),
- as_Register(Matcher::_regEncode[src_lo]));
+ as_Register(Matcher::_regEncode[src_hi]));
if (is64) {
__ mv(as_Register(Matcher::_regEncode[dst_hi]),
- as_Register(Matcher::_regEncode[src_hi]));
+ as_Register(Matcher::_regEncode[src_lo]));
}
} else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
if (is64) {
引发错误:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x3b96afc4, pid=3346991, tid=3346993
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.shining.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.shining.jdk11u, mixed mode, serial gc, linux-riscv32)
# Problematic frame:
# J 13 c2 java.lang.StringLatin1.hashCode([B)I java.base (42 bytes) @ 0x3b96afc4 [0x3b96ae40+0x00000184]
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /home/shining/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid3346991.log
Compiled method (c2) 2944 13 java.lang.StringLatin1::hashCode (42 bytes)
total in heap [0x3b96ad08,0x3b96b230] = 1320
relocation [0x3b96adf8,0x3b96ae10] = 24
main code [0x3b96ae40,0x3b96b040] = 512
stub code [0x3b96b040,0x3b96b074] = 52
metadata [0x3b96b074,0x3b96b078] = 4
scopes data [0x3b96b078,0x3b96b0e0] = 104
scopes pcs [0x3b96b0e0,0x3b96b220] = 320
dependencies [0x3b96b220,0x3b96b224] = 4
nul chk table [0x3b96b224,0x3b96b230] = 12
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 3346993
Dumping core ...
这时候输出的编译log,才执行300多行。 根据错误信息,跟踪到src/java.base/share/classes/java/lang/StringLatin1.java中的hashcode,没发现什么问题。
public static int hashCode(byte[] value) {
int h = 0;
for (byte v : value) {
h = 31 * h + (v & 0xff);
}
return h;
}
编译这个方法,也不涉及到复杂的内容。 这个部分应该和offset无关。
sharedRuntime_riscv32.cpp中的java_calling_convention/c_calling_convention T_LONG数据对于前后交换不影响这个问题,会导致其他的问题。
riscv32.ad中所有long关键字的代码全过了一遍,直接代码都review了,间接代码都记录下来了,列了个清单。目前没发现什么问题。
目前这个问题,make images的情况下,在images/jdk/bin下的javac会遇到错误:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x3f8daf96, pid=2377020, tid=2377022
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.shining.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.shining.jdk11u, mixed mode, serial gc, linux-riscv32)
# Problematic frame:
# V [libjvm.so+0xb8ef96] EnableIf<HasDecorator<128ull, 128ull>::value, signed char>::type RawAccessBarrier<128ull>::load_internal<128ull, signed char>(void*)+0xe
#
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
错误信息中提到:
Java frames: (J=compiled Java code, j=interpreted, Vv=VM code)
J 38 jdk.internal.misc.Unsafe.getByte(Ljava/lang/Object;J)B java.base@11.0.9-internal (0 bytes) @ 0x3b6984bc [0x3b698400+0x000000bc]
j jdk.internal.misc.Unsafe.getByte(J)B+3 java.base@11.0.9-internal
j java.nio.DirectByteBuffer.get()B+11 java.base@11.0.9-internal
同样的代码,如果编译为core模式(解释器模式),javac是正常运行的,没有问题。
make情况下,直接使用jdk/bin下的javac,和java -version所获取的错误一致,所以背后还是同样的错误。可能是反应在不同的版本和错误上。
怀疑数据的offset本来出了问题,不断尝试之后,列出了上述情况。
579 提交之后,进行调试:
调试发现,只有r_1赋值为零的时候,offset的错误才能跳过去,r_2赋值为零,offset的错误都不能跳过去,还是过大。 或者,将r_1使用ld_off,r_2使用next_off,这样才能跳过offset错误。
综合这两种情况分析,这里的r_1应该是被当做long数据的高位使用了,r_2被当做低位使用了。根据上下文的环境理解,r_1应该是低位,r_2应该是高位才对。