Closed DingliZhang closed 1 year ago
目前生成的报错信息:
--N: o10 Parm === o3 [[o24 o124 o527 o525 o523 o440 o437 o435 o431 o531 o219 o219 o331 o284 o533 o529 o336 o199 o199 o195 o537 o62 o541 o541 o39 o39 o535 ]] Parm0: byte[int:>=0]:exact *
IREGP 0 IREGP
IREGPNOSP 0 IREGPNOSP
IREGP_R10 0 IREGP_R10
IREGP_R11 0 IREGP_R11
IREGP_R12 0 IREGP_R12
IREGP_R13 0 IREGP_R13
IREGP_R14 0 IREGP_R14
IREGP_R15 0 IREGP_R15
IREGP_R16 0 IREGP_R16
IREGP_R28 0 IREGP_R28
JAVATHREAD_REGP 0 JAVATHREAD_REGP
INDIRECT 0 INDIRECT
INLINE_CACHE_REGP 0 INLINE_CACHE_REGP
MEMORY 0 INDIRECT
IREGNORP 0 IREGP
IREGILNP 0 IREGP
IREGILNPNOSP 0 IREGPNOSP
--N: o200 Phi === o201 o213 o192 [[o192 o199 ]] #int #tripcount
IREGI 0 IREGI
IREGINOSP 0 IREGINOSP
IREGI_R10 0 IREGI_R10
IREGI_R12 0 IREGI_R12
IREGI_R13 0 IREGI_R13
IREGI_R14 0 IREGI_R14
IREGIHEAPBASE 0 IREGIHEAPBASE
IREGIORL2I 0 IREGI
IREGIORL 0 IREGI
IREGILNP 0 IREGI
IREGILNPNOSP 0 IREGINOSP
是由 svec->dump() 所生成的:
void State::dump() {
tty->print("\n");
dump(0);
}
void State::dump(int depth) {
for( int j = 0; j < depth; j++ )
tty->print(" ");
tty->print("--N: ");
_leaf->dump();
uint i;
for( i = 0; i < _LAST_MACH_OPER; i++ )
// Check for valid entry
if( valid(i) ) {
for( int j = 0; j < depth; j++ )
tty->print(" ");
assert(_cost[i] != max_juint, "cost must be a valid value");
assert(_rule[i] < _last_Mach_Node, "rule[i] must be valid rule");
tty->print_cr("%s %d %s",
ruleName[i], _cost[i], ruleName[_rule[i]] );
}
tty->cr();
for( i=0; i<2; i++ )
if( _kids[i] )
_kids[i]->dump(depth+1);
}
报错信息中的两个节点是由_kids[i]->dump(depth+1);生成的,也就是当前报错对应的state的两个孩子节点:
State *_kids[2]; // Children of state node in label tree
o10 Parm
表示参数,是理想图中常用的节点,可能代表I/O输入,内存输入,指针输入,返回值及函数的实参。
o200 Phi
是为SSA准备的节点,通常用于处理数据流的合并。
o10 Parm === o3 [[o24 o124 o527 o525 o523 o440 o437 o435 o431 o531 o219 o219 o331 o284 o533 o529 o336 o199 o199 o195 o537 o62 o541 o541 o39 o39 o535 ]] Parm0: byte[int:>=0]:exact *
o200 Phi === o201 o213 o192 [[o192 o199 ]] #int #tripcount
是由 _leaf->dump();
所输出的,而 _leaf 是State类中一个Node类型的指针变量,代表了匹配树的理想节点。
参考:https://wiki.openjdk.java.net/display/HotSpot/C2+IR+Graph+and+Nodes
对此处的index右移5位的目的不理解。
// build/linux-riscv32-normal-custom-slowdebug/hotspot/variant-custom/support/adlc/ad_riscv32.hpp
class State : public ResourceObj {
public:
...
unsigned int _valid[(_LAST_MACH_OPER/32)+1]; // Bit Map of valid Cost/Rule entrie
...
}
//_LAST_MACH_OPER 的定义
enum MachOperands {
/* 0 */ UNIVERSE,
/* 1 */ LABEL,
...
/* 147 */ _BINARY_IREGP_R11_IREGP_R13,
// last internally defined operand
_LAST_MACH_OPER
};
其中_LAST_MACH_OPER是一个枚举变量,在MachOperands 中出现多个关于IMMI_63的变量,与IMMI_63相关的变量在riscv32中应该需要删掉,这样最终的_LAST_MACH_OPER的值会改变,最终影响到
最后影响结果: assert(false) failed: bad AD file。
由于 jdk11u/build/linux-riscv32-normal-custom-release/hotspot/variant-custom/gensrc/adfiles/ad_riscv32.hpp
文档的编译问题,初步修改调试没有明显变化,后续需要理清楚该文档跟riscv32.ad之间的关系。
尝试在riscv32.ad中删去关于IMMI_63的操作以及指令,但是没有影响。
对此处的index右移5位的目的不理解。
这里的话从_valid的定义就能理解了:
unsigned int _valid[(_LAST_MACH_OPER/32)+1];
右移五位和/32的效果是一样的,都是将当前的index映射到数组中对应的字节(32位),而字节中的其中一个bit对应了此index的0/1值。
1.我们对 build/linux-riscv32-normal-custom-slowdebug/hotspot/variant-custom/gensrc/adfiles/ad_riscv32.hpp:bool valid(uint index)
函数断点。
或者使用GDB命令进行断点。
2.切换到线程7(C2编译线程),然后点击栈顶方法,会提示对应的源文件 ad_riscv32.hpp 不存在,然后我们在提示的目录下创建该文件,即可完成对某些函数的断点调试。
对AD 文件生成的函数进行断点调试 中,可以执行以下gdb命令:
set substitute-path /home/dingli/jdk11u-jit/make/hotspot /home/dingli/jdk11u-jit/build/linux-riscv32-normal-custom-slowdebug/hotspot/variant-custom/gensrc/adfiles
因为build目录下的文件是在编译期间生成的,所以他会把make目录作为源文件的搜索路径,因此需要替换一下。
参考ARM32修改如下,可以向前推进一步。
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index 7aab43b3cc..6abf2ba7a4 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -5980,7 +5980,7 @@ instruct addI_reg_imm_l2i(iRegINoSp dst, iRegL src1, immIAdd src2) %{
%}
// Pointer Addition
-instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegL src2) %{
+instruct addP_reg_reg(iRegPNoSp dst, iRegP src1, iRegI src2) %{
match(Set dst (AddP src1 src2));
ins_cost(ALU_COST);
参考ARM32修复 addP_reg_reg instruct 在riscv32 下不能正确匹配 iRegI 的问题,PR:https://github.com/openjdk-riscv/jdk11u/pull/389 ,修复后可以向前推进一步。
执行命令/home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java -version
新的报错如下:
o560 CmpUL === _ o612 o559 [[o561 o562 ]]
--N: o560 CmpUL === _ o612 o559 [[o561 o562 ]]
--N: o612 AddL === _ o556 o611 [[o560 ]]
IREGLNOSP 100 addL_reg_imm
IREGL_R10 100 addL_reg_imm
IREGILNPNOSP 100 IREGLNOSP
--N: o556 ConvI2L === _ o93 [[o612 o614 ]] #long:minint..maxint
IREGL 0 IREGL
IREGLNOSP 1 IREGLNOSP
IREGL_R0R1 0 IREGL_R0R1
IREGL_R2R3 0 IREGL_R2R3
IREGL_R10 0 IREGL_R10
IREGIORL 0 IREGL
IREGILNP 0 IREGL
IREGILNPNOSP 1 IREGLNOSP
--N: o611 ConL === o0 [[o612 o583 ]] #long:-1
IMML 0 IMML
IMML_M1 0 IMML_M1
IMMLADD 0 IMMLADD
IMMLSUB 0 IMMLSUB
IMMLOFFSET 0 IMMLOFFSET
IREGLNOSP 100 loadConL
IREGL_R10 100 loadConL
IREGILNPNOSP 100 IREGLNOSP
IMMIORL 0 IMML
--N: o559 ConvI2L === _ o381 [[o560 ]] #long:minint..maxint
IREGLNOSP 100 convI2L_reg_reg
IREGL_R10 100 convI2L_reg_reg
IREGILNPNOSP 100 IREGLNOSP
_ConvI2L_iRegIorL2I_ 0 _ConvI2L_iRegIorL2I_
--N: o381 LoadRange === o547 o7 o380 [[o605 o559 ]] @bottom[int:>=0]+8 *, idx=5; #int:>=0
IREGI 0 IREGI
IREGINOSP 0 IREGINOSP
IREGI_R10 0 IREGI_R10
IREGI_R12 0 IREGI_R12
IREGI_R13 0 IREGI_R13
IREGI_R14 0 IREGI_R14
IREGIHEAPBASE 0 IREGIHEAPBASE
IREGIORL2I 0 IREGI
IREGIORL 0 IREGI
IREGILNP 0 IREGI
IREGILNPNOSP 0 IREGINOSP
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/matcher.cpp:1589
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/zifeihan/jdk11u/src/hotspot/share/opto/matcher.cpp:1589), pid=434695, tid=434714
# assert(false) failed: bad AD file
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.zifeihan.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.zifeihan.jdk11u, mixed mode, serial gc, linux-riscv32)
# 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/zifeihan/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid434695.log
#
# Compiler replay data is saved as:
# /home/zifeihan/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/replay_pid434695.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 434714
Dumping core ...
Aborted
目前riscv32.ad中,slli指令相关的偏移量的过滤器有几处设置为了63或者是0x3f,这明显是RV64的设置。根据规范,RV32的slli偏移量shamt【5】=0的时候,slli才能正常工作,所以过滤器应为0x1f。
当前报错信息中子节点里面的convI2L
对应的instruct convI2L_reg_reg
需要进行修改。
参照 src/hotspot/cpu/riscv32/templateTable_riscv32.cpp:TemplateTable::convert()
中的逻辑:
switch (bytecode()) {
case Bytecodes::_i2l:
__ srai(x11, x10, 0x1f);
break;
patch:
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index b2963bc811..8e7b36c76e 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -7339,10 +7339,12 @@ instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
%{
match(Set dst (ConvI2L src));
- ins_cost(ALU_COST);
- format %{ "add $dst, $src\t#@convI2L_reg_reg" %}
+ ins_cost(ALU_COST * 2);
+ format %{ "add $dst.lo, $src, zr\n\t"
+ "srai $dst.hi, $src, 31\t#@convI2L_reg_reg" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src$$reg), zr);
+ __ srai(as_Register($dst$$reg)->successor(), as_Register($src$$reg), 0x1f);
%}
ins_pipe(ialu_reg);
%}
对当前结果没有影响。
根据当前报错,对long型reg进行修改:
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index b2963bc811..70274da74a 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -358,14 +358,9 @@ reg_class int_r13_reg(R13);
// Singleton class for R14 int register
reg_class int_r14_reg(R14);
-// Class for all long registers
-reg_class all_reg(
- R0,R1,
- R2,R3
-);
-
-reg_class long_r0r1_reg(R0, R1);
-reg_class long_r2r3_reg(R2, R3);
+reg_class long_reg (R10, R11, R12, R13);
+reg_class long_r10r11_reg(R10, R11);
+reg_class long_r12r13_reg(R12, R13);
// Class for all long integer registers (excluding zr)
reg_class any_reg %{
@@ -711,10 +706,10 @@ source %{
_ANY_REG32_mask = _ALL_REG32_mask;
_ANY_REG32_mask.Remove(OptoReg::as_OptoReg(x0->as_VMReg()));
- _ANY_REG_mask = _ALL_REG_mask;
+ _ANY_REG_mask = _ALL_REG32_mask;
_ANY_REG_mask.SUBTRACT(_ZR_REG_mask);
- _PTR_REG_mask = _ALL_REG_mask;
+ _PTR_REG_mask = _ALL_REG32_mask;
_PTR_REG_mask.SUBTRACT(_ZR_REG_mask);
_NO_SPECIAL_REG32_mask = _ALL_REG32_mask;
@@ -2355,7 +2350,18 @@ frame %{
R10_num // Op_RegL
};
- return OptoRegPair(lo[ideal_reg]);
+ static const int hi[Op_RegL + 1] = { // enum name
+ 0, // Op_Node
+ 0, // Op_Set
+ OptoReg::Bad, // Op_RegN
+ OptoReg::Bad, // Op_RegI
+ OptoReg::Bad, // Op_RegP
+ OptoReg::Bad, // Op_RegF
+ F10_H_num, // Op_RegD
+ R11_num // Op_RegL
+ };
+
+ return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
%}
%}
@@ -2780,37 +2786,40 @@ operand iRegI_R14()
// Long Register Operands
operand iRegL()
%{
- constraint(ALLOC_IN_RC(any_reg));
- match(iRegL_R0R1);
- match(iRegL_R2R3);
+ constraint(ALLOC_IN_RC(long_reg));
+ match(RegL);
+ match(iRegL_R10R11);
+ match(iRegL_R12R13);
op_cost(0);
format %{ %}
interface(REG_INTER);
%}
-// Integer 32 bit Register not Special
+// Long Register not Special
operand iRegLNoSp()
%{
constraint(ALLOC_IN_RC(no_special_reg));
- match(iRegL_R0R1);
- match(iRegL_R2R3);
+ match(RegL);
+ match(iRegL_R10R11);
format %{ %}
interface(REG_INTER);
%}
-operand iRegL_R0R1()
+operand iRegL_R10R11()
%{
- constraint(ALLOC_IN_RC(long_r0r1_reg));
+ constraint(ALLOC_IN_RC(long_r10r11_reg));
match(RegL);
+ match(iRegLNoSp);
op_cost(0);
format %{ %}
interface(REG_INTER);
%}
-operand iRegL_R2R3()
+operand iRegL_R12R13()
%{
- constraint(ALLOC_IN_RC(long_r2r3_reg));
+ constraint(ALLOC_IN_RC(long_r12r13_reg));
match(RegL);
+ match(iRegLNoSp);
op_cost(0);
format %{ %}
interface(REG_INTER);
@@ -2960,17 +2969,6 @@ operand iRegIHeapbase()
interface(REG_INTER);
%}
-// Long 32 bit Register R10 only
-operand iRegL_R10()
-%{
- constraint(ALLOC_IN_RC(r10_reg));
- match(RegL);
- match(iRegLNoSp);
- op_cost(0);
- format %{ %}
- interface(REG_INTER);
-%}
-
// Float Register
// Float register operands
operand fRegF()
@@ -7341,8 +7339,12 @@ instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
ins_cost(ALU_COST);
format %{ "add $dst, $src\t#@convI2L_reg_reg" %}
+ ins_cost(ALU_COST * 2);
+ format %{ "add $dst.lo, $src, zr\n\t"
+ "srai $dst.hi, $src, 31\t#@convI2L_reg_reg" %}
ins_encode %{
__ add(as_Register($dst$$reg), as_Register($src$$reg), zr);
+ __ srai(as_Register($dst$$reg)->successor(), as_Register($src$$reg), 0x1f);
%}
ins_pipe(ialu_reg);
%}
@@ -9393,7 +9395,7 @@ instruct partialSubtypeCheckVsZero(iRegP_R14 sub, iRegP_R10 super, iRegP_R12 tem
%}
instruct string_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
- iRegI_R10 result, iRegP_R28 tmp1, iRegL_R0R1 tmp2, iRegL_R2R3 tmp3, rFlagsReg cr)
+ iRegI_R10 result, iRegP_R28 tmp1, iRegL_R10R11 tmp2, iRegL_R12R13 tmp3, rFlagsReg cr)
%{
predicate(((StrCompNode *)n)->encoding() == StrIntrinsicNode::UU);
match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2)));
@@ -9411,7 +9413,7 @@ instruct string_compareU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R
%}
instruct string_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
- iRegI_R10 result, iRegP_R28 tmp1, iRegL_R0R1 tmp2, iRegL_R2R3 tmp3, rFlagsReg cr)
+ iRegI_R10 result, iRegP_R28 tmp1, iRegL_R10R11 tmp2, iRegL_R12R13 tmp3, rFlagsReg cr)
%{
predicate(((StrCompNode *)n)->encoding() == StrIntrinsicNode::LL);
match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2)));
@@ -9428,7 +9430,7 @@ instruct string_compareL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R
%}
instruct string_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
- iRegI_R10 result, iRegP_R28 tmp1, iRegL_R0R1 tmp2, iRegL_R2R3 tmp3, rFlagsReg cr)
+ iRegI_R10 result, iRegP_R28 tmp1, iRegL_R10R11 tmp2, iRegL_R12R13 tmp3, rFlagsReg cr)
%{
predicate(((StrCompNode *)n)->encoding() == StrIntrinsicNode::UL);
match(Set result(StrComp(Binary str1 cnt1)(Binary str2 cnt2)));
@@ -9445,7 +9447,7 @@ instruct string_compareUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_
%}
instruct string_compareLU(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2, iRegI_R14 cnt2,
- iRegI_R10 result, iRegP_R28 tmp1, iRegL_R0R1 tmp2, iRegL_R2R3 tmp3,
+ iRegI_R10 result, iRegP_R28 tmp1, iRegL_R10R11 tmp2, iRegL_R12R13 tmp3,
rFlagsReg cr)
%{
predicate(((StrCompNode *)n)->encoding() == StrIntrinsicNode::LU);
@@ -9589,7 +9591,7 @@ instruct string_indexof_conUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2,
%}
// clearing of an array
-instruct clearArray_reg_reg(iRegL_R0R1 cnt, iRegP_R28 base, Universe dummy, rFlagsReg cr)
+instruct clearArray_reg_reg(iRegL_R10R11 cnt, iRegP_R28 base, Universe dummy, rFlagsReg cr)
%{
match(Set dummy (ClearArray cnt base));
effect(USE_KILL cnt, USE_KILL base, KILL cr);
修改点:
报错信息:
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x3b96ca98, pid=3223151, tid=3223156
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.dingli.jdk11u-jit)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.dingli.jdk11u-jit, mixed mode, serial gc, linux-riscv32)
# Problematic frame:
# J 11 c2 java.lang.StringLatin1.hashCode([B)I java.base (42 bytes) @ 0x3b96ca98 [0x3b96ca40+0x00000058]
#
# 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/dingli/jdk11u-jit/hs_err_pid3223151.log
Compiled method (c2) 2955 11 java.lang.StringLatin1::hashCode (42 bytes)
total in heap [0x3b96c908,0x3b96ce30] = 1320
relocation [0x3b96c9f8,0x3b96ca10] = 24
main code [0x3b96ca40,0x3b96cc40] = 512
stub code [0x3b96cc40,0x3b96cc74] = 52
metadata [0x3b96cc74,0x3b96cc78] = 4
scopes data [0x3b96cc78,0x3b96cce0] = 104
scopes pcs [0x3b96cce0,0x3b96ce20] = 320
dependencies [0x3b96ce20,0x3b96ce24] = 4
nul chk table [0x3b96ce24,0x3b96ce30] = 12
Loaded disassembler from /home/dingli/jdk11u-jit/build/linux-riscv32-normal-custom-slowdebug/jdk/lib/server/hsdis-riscv32.so
BFD: unrecognized disassembler option:
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 3223156
Dumping core ...
Aborted
但是之前的报错信息没有了,可以加上打印信息判断出来(73为之前的报错CmpUL对应的index):
diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp
index 9437d379d3..93d2a64a23 100644
--- a/src/hotspot/share/opto/matcher.cpp
+++ b/src/hotspot/share/opto/matcher.cpp
@@ -1582,7 +1582,11 @@ Node* Matcher::Label_Root(const Node* n, State* svec, Node* control, Node
*& mem)
for( x = 0; x < _LAST_MACH_OPER; x++ )
if( svec->valid(x) )
break;
-
+ if (n->Opcode() == 73) {
+ n->dump();
+ svec->dump();
+ warning("---------");
+ }
if (x >= _LAST_MACH_OPER) {
n->dump();
svec->dump();
推测:
推测:
- 引发了新的问题
- 有可能之前走到CmpUL节点的路径本身就是错的,目前还在进行排查。
通过调试在报错的位置汇编如下: 并且访问的 t2 并不是一个内存地址,t2的地址在上面被进行了左移16位,又右移了16位(被清零了):
基于上述修改,经过简化。修改如下:
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index 6abf2ba7a4..c0de2c7a95 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -714,7 +714,7 @@ source %{
_ANY_REG_mask = _ALL_REG_mask;
_ANY_REG_mask.SUBTRACT(_ZR_REG_mask);
- _PTR_REG_mask = _ALL_REG_mask;
+ _PTR_REG_mask = _ALL_REG32_mask;
_PTR_REG_mask.SUBTRACT(_ZR_REG_mask);
_NO_SPECIAL_REG32_mask = _ALL_REG32_mask;
@@ -1156,8 +1156,6 @@ uint MachSpillCopyNode::implementation(CodeBuffer *cbuf, PhaseRegAlloc *ra_, boo
if (dst_lo_rc == rc_int) { // gpr --> gpr copy
__ mv(as_Register(Matcher::_regEncode[dst_lo]),
as_Register(Matcher::_regEncode[src_lo]));
- if (this->ideal_reg() != Op_RegI) // zero extended for narrow oop or klass
- __ clear_upper_bits(as_Register(Matcher::_regEncode[dst_lo]), 16);
} else if (dst_lo_rc == rc_float) { // gpr --> fpr copy
__ fmv_w_x(as_FloatRegister(Matcher::_regEncode[dst_lo]),
as_Register(Matcher::_regEncode[src_lo]));
@@ -2355,7 +2353,18 @@ frame %{
R10_num // Op_RegL
};
- return OptoRegPair(lo[ideal_reg]);
+ static const int hi[Op_RegL + 1] = { // enum name
+ 0, // Op_Node
+ 0, // Op_Set
+ OptoReg::Bad, // Op_RegN
+ OptoReg::Bad, // Op_RegI
+ OptoReg::Bad, // Op_RegP
+ OptoReg::Bad, // Op_RegF
+ F10_H_num, // Op_RegD
+ R11_num // Op_RegL
+ };
+
+ return OptoRegPair(hi[ideal_reg], lo[ideal_reg]);
%}
%}
由于在32位上int类型和指针类型大小相同,因此将一下代码删除,不做特殊的清零操作,issue:https://github.com/openjdk-riscv/jdk11u/issues/367 也记录了这里需要删除。
- if (this->ideal_reg() != Op_RegI) // zero extended for narrow oop or klass
- __ clear_upper_bits(as_Register(Matcher::_regEncode[dst_lo]), 16);
在 https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1127178246 的基础之上添加https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1127407958 的修改,可以往前推进一步,最新的报错信息:
o1629 ClearArray === o1643 o1624 o1644 o1628 [[o1606 229 ]] Memory: @rawptr:BotPTR, idx=Raw;
--N: o1629 ClearArray === o1643 o1624 o1644 o1628 [[o1606 229 ]] Memory: @rawptr:BotPTR, idx=Raw;
--N: o1644 AddI === _ o1626 o1249 [[o1629 ]]
IREGI 200 addI_reg_imm
IREGINOSP 200 addI_reg_imm
IREGI_R10 200 addI_reg_imm
IREGI_R12 200 addI_reg_imm
IREGI_R13 200 addI_reg_imm
IREGI_R14 200 addI_reg_imm
IREGIORL2I 200 IREGI
IREGIORL 200 IREGI
IREGILNP 200 IREGI
IREGILNPNOSP 200 IREGINOSP
--N: o1626 URShiftI === _ o829 o1155 [[o1644 ]]
IREGI 100 urShiftI_reg_imm
IREGINOSP 100 urShiftI_reg_imm
IREGI_R10 100 urShiftI_reg_imm
IREGI_R12 100 urShiftI_reg_imm
IREGI_R13 100 urShiftI_reg_imm
IREGI_R14 100 urShiftI_reg_imm
IREGIORL2I 100 IREGI
IREGIORL 100 IREGI
IREGILNP 100 IREGI
IREGILNPNOSP 100 IREGINOSP
--N: o829 Phi === o68 o830 o69 o69 [[o1626 o1610 ]] #int
IREGI 0 IREGI
IREGINOSP 0 IREGINOSP
IREGI_R10 0 IREGI_R10
IREGI_R12 0 IREGI_R12
IREGI_R13 0 IREGI_R13
IREGI_R14 0 IREGI_R14
IREGIHEAPBASE 0 IREGIHEAPBASE
IREGIORL2I 0 IREGI
IREGIORL 0 IREGI
IREGILNP 0 IREGI
IREGILNPNOSP 0 IREGINOSP
--N: o1155 ConI === o0 [[o1626 ]] #int:3
IMMI 0 IMMI
IMMI_LE_4 0 IMMI_LE_4
IMMIADD 0 IMMIADD
IMMISUB 0 IMMISUB
IMMIOFFSET 0 IMMIOFFSET
IREGI 100 loadConI
IREGINOSP 100 loadConI
IREGI_R10 100 loadConI
IREGI_R12 100 loadConI
IREGI_R13 100 loadConI
IREGI_R14 100 loadConI
IREGIORL2I 100 IREGI
IREGIORL 100 IREGI
IREGILNP 100 IREGI
IREGILNPNOSP 100 IREGINOSP
IMMIORL 0 IMMI
--N: o1249 ConI === o0 [[o1644 ]] #int:-2
IMMI 0 IMMI
IMMI_LE_4 0 IMMI_LE_4
IMMIADD 0 IMMIADD
IMMISUB 0 IMMISUB
IMMIOFFSET 0 IMMIOFFSET
IREGI 100 loadConI
IREGINOSP 100 loadConI
IREGI_R10 100 loadConI
IREGI_R12 100 loadConI
IREGI_R13 100 loadConI
IREGI_R14 100 loadConI
IREGIORL2I 100 IREGI
IREGIORL 100 IREGI
IREGILNP 100 IREGI
IREGILNPNOSP 100 IREGINOSP
IMMIORL 0 IMMI
--N: o1628 AddP === _ o1609 o1609 o69 [[o1629 ]]
IREGP 200 addP_reg_reg
IREGPNOSP 200 addP_reg_reg
IREGP_R10 200 addP_reg_reg
IREGP_R11 200 addP_reg_reg
IREGP_R12 200 addP_reg_reg
IREGP_R13 200 addP_reg_reg
IREGP_R14 200 addP_reg_reg
IREGP_R15 200 addP_reg_reg
IREGP_R16 200 addP_reg_reg
IREGP_R28 200 addP_reg_reg
JAVATHREAD_REGP 200 addP_reg_reg
INDIRECT 200 addP_reg_reg
INDOFFI 0 INDOFFI
INLINE_CACHE_REGP 200 addP_reg_reg
MEMORY 0 INDOFFI
IREGNORP 200 IREGP
IREGILNP 200 IREGP
IREGILNPNOSP 200 IREGPNOSP
--N: o1609 LoadP === o68 o44 o1601 [[o1610 o1618 o1619 o1619 o1621 o1621 o1623 o1623 o1628 o1628 o1607 ]] @rawptr:BotPTR, idx=Raw; #rawptr:BotPTR (does not depend only on test)
IREGP 0 IREGP
IREGPNOSP 0 IREGPNOSP
IREGP_R10 0 IREGP_R10
IREGP_R11 0 IREGP_R11
IREGP_R12 0 IREGP_R12
IREGP_R13 0 IREGP_R13
IREGP_R14 0 IREGP_R14
IREGP_R15 0 IREGP_R15
IREGP_R16 0 IREGP_R16
IREGP_R28 0 IREGP_R28
JAVATHREAD_REGP 0 JAVATHREAD_REGP
INDIRECT 0 INDIRECT
INLINE_CACHE_REGP 0 INLINE_CACHE_REGP
MEMORY 0 INDIRECT
IREGNORP 0 IREGP
IREGILNP 0 IREGP
IREGILNPNOSP 0 IREGPNOSP
--N: o69 ConI === o0 [[o70 o829 o829 o1225 o1175 o1628 ]] #int:16
IMMI 0 IMMI
IMMIADD 0 IMMIADD
IMMISUB 0 IMMISUB
IMMIOFFSET 0 IMMIOFFSET
IREGI 100 loadConI
IREGINOSP 100 loadConI
IREGI_R10 100 loadConI
IREGI_R12 100 loadConI
IREGI_R13 100 loadConI
IREGI_R14 100 loadConI
IREGIORL2I 100 IREGI
IREGIORL 100 IREGI
IREGILNP 100 IREGI
IREGILNPNOSP 100 IREGINOSP
IMMIORL 0 IMMI
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/matcher.cpp:1589
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/dingli/jdk11u-jit/src/hotspot/share/opto/matcher.cpp:1589), pid=3694319, tid=3694338
# assert(false) failed: bad AD file
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.dingli.jdk11u-jit)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.dingli.jdk11u-jit, mixed mode, serial gc, linux-riscv32)
# 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/dingli/jdk11u-jit/hs_err_pid3694319.log
#
# Compiler replay data is saved as:
# /home/dingli/jdk11u-jit/replay_pid3694319.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 3694338
Dumping core ...
Aborted
是否往前推进可以通过对之前报错的CmpUL进行dump来测试:
diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp
index 9437d379d3..6be2a2df74 100644
--- a/src/hotspot/share/opto/matcher.cpp
+++ b/src/hotspot/share/opto/matcher.cpp
@@ -1582,7 +1582,12 @@ Node* Matcher::Label_Root(const Node* n, State* svec, Node* control, Node*& mem)
for( x = 0; x < _LAST_MACH_OPER; x++ )
if( svec->valid(x) )
break;
-
+ if (n->Opcode() == 73) {
+ n->dump();
+ svec->dump();
+ assert( false, "bad AD file" );
+ warning("---------");
+ }
if (x >= _LAST_MACH_OPER) {
n->dump();
svec->dump();
输出信息:
o560 CmpUL === _ o612 o559 [[o561 o562 ]]
--N: o560 CmpUL === _ o612 o559 [[o561 o562 ]]
_CmpUL_iRegL_iRegL 200 _CmpUL_iRegL_iRegL
--N: o612 AddL === _ o556 o611 [[o560 ]]
IREGL 100 addL_reg_imm
IREGLNOSP 100 addL_reg_imm
IREGL_R10R11 100 addL_reg_imm
IREGL_R12R13 100 addL_reg_imm
IREGIORL 100 IREGL
IREGILNP 100 IREGL
IREGILNPNOSP 100 IREGLNOSP
--N: o556 ConvI2L === _ o93 [[o612 o614 ]] #long:minint..maxint
IREGL 0 IREGL
IREGLNOSP 1 IREGLNOSP
IREGL_R10R11 0 IREGL_R10R11
IREGL_R12R13 0 IREGL_R12R13
IREGIORL 0 IREGL
IREGILNP 0 IREGL
IREGILNPNOSP 1 IREGLNOSP
--N: o611 ConL === o0 [[o612 o583 ]] #long:-1
IMML 0 IMML
IMML_M1 0 IMML_M1
IMMLADD 0 IMMLADD
IMMLSUB 0 IMMLSUB
IMMLOFFSET 0 IMMLOFFSET
IREGL 100 loadConL
IREGLNOSP 100 loadConL
IREGL_R10R11 100 loadConL
IREGL_R12R13 100 loadConL
IREGIORL 100 IREGL
IREGILNP 100 IREGL
IREGILNPNOSP 100 IREGLNOSP
IMMIORL 0 IMML
--N: o559 ConvI2L === _ o381 [[o560 ]] #long:minint..maxint
IREGL 100 convI2L_reg_reg
IREGLNOSP 100 convI2L_reg_reg
IREGL_R10R11 100 convI2L_reg_reg
IREGL_R12R13 100 convI2L_reg_reg
IREGIORL 100 IREGL
IREGILNP 100 IREGL
IREGILNPNOSP 100 IREGLNOSP
_ConvI2L_iRegIorL2I_ 0 _ConvI2L_iRegIorL2I_
--N: o381 LoadRange === o547 o7 o380 [[o605 o559 ]] @bottom[int:>=0]+8 *, idx=5; #int:>=0
IREGI 0 IREGI
IREGINOSP 0 IREGINOSP
IREGI_R10 0 IREGI_R10
IREGI_R12 0 IREGI_R12
IREGI_R13 0 IREGI_R13
IREGI_R14 0 IREGI_R14
IREGIHEAPBASE 0 IREGIHEAPBASE
IREGIORL2I 0 IREGI
IREGIORL 0 IREGI
IREGILNP 0 IREGI
IREGILNPNOSP 0 IREGINOSP
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/matcher.cpp:1588
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/dingli/jdk11u-jit/src/hotspot/share/opto/matcher.cpp:1588), pid=3696555, tid=3696571
# assert(false) failed: bad AD file
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.dingli.jdk11u-jit)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.dingli.jdk11u-jit, mixed mode, serial gc, linux-riscv32)
# 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/dingli/jdk11u-jit/hs_err_pid3696555.log
#
# Compiler replay data is saved as:
# /home/dingli/jdk11u-jit/replay_pid3696555.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 3696571
Dumping core ...
Aborted
由此可以看出断言是由测试的时候添加的assert所触发的,之前报错的CmpUL的子节点已经满足了匹配条件。 已提交PR #392
修复 clearArray 不能匹配的问题,PR: https://github.com/openjdk-riscv/jdk11u/pull/393 ,修改如下 :
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index f6c34ed503..31c501b306 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -2799,7 +2799,7 @@ operand iRegL()
// Long Register not Special
operand iRegLNoSp()
%{
- constraint(ALLOC_IN_RC(no_special_reg));
+ constraint(ALLOC_IN_RC(long_reg));
match(RegL);
match(iRegL_R10R11);
format %{ %}
@@ -9588,7 +9588,7 @@ instruct string_indexof_conUL(iRegP_R11 str1, iRegI_R12 cnt1, iRegP_R13 str2,
%}
// clearing of an array
-instruct clearArray_reg_reg(iRegL_R10R11 cnt, iRegP_R28 base, Universe dummy, rFlagsReg cr)
+instruct clearArray_reg_reg(iRegI_R14 cnt, iRegP_R28 base, Universe dummy, rFlagsReg cr)
%{
match(Set dummy (ClearArray cnt base));
effect(USE_KILL cnt, USE_KILL base, KILL cr);
修改点:
o1547 OrI === _ o1546 o1544 [[o1548 o1566 448 ]]
--N: o1547 OrI === _ o1546 o1544 [[o1548 o1566 448 ]]
--N: o1546 CastP2X === o1538 o310 [[o1547 ]] IREGL 100 castP2X IREGLNOSP 100 castP2X IREGL_R10R11 100 castP2X IREGL_R12R13 100 castP2X IREGIORL 100 IREGL IREGILNP 100 IREGL IREGILNPNOSP 100 IREGLNOSP _CastP2XiRegP 0 _CastP2XiRegP
--N: o310 ThreadLocal === o0 [[o312 o1526 o1576 o1546 o1603 o1601 397 ]]
IREGP 0 IREGP
IREGPNOSP 0 IREGPNOSP
IREGP_R10 0 IREGP_R10
IREGP_R11 0 IREGP_R11
IREGP_R12 0 IREGP_R12
IREGP_R13 0 IREGP_R13
IREGP_R14 0 IREGP_R14
IREGP_R15 0 IREGP_R15
IREGP_R16 0 IREGP_R16
IREGP_R28 0 IREGP_R28
JAVATHREAD_REGP 0 JAVATHREAD_REGP
INDIRECT 0 INDIRECT
INLINE_CACHE_REGP 0 INLINE_CACHE_REGP
MEMORY 0 INDIRECT
IREGNORP 0 IREGP
IREGILNP 0 IREGP
IREGILNPNOSP 0 IREGPNOSP
--N: o1544 LoadI === _ o44 o1543 [[o1547 o1665 ]] @klass java/lang/Object: 0x3e951298+112 *, idx=11; #int IREGI 0 IREGI IREGINOSP 0 IREGINOSP IREGI_R10 0 IREGI_R10 IREGI_R12 0 IREGI_R12 IREGI_R13 0 IREGI_R13 IREGI_R14 0 IREGI_R14 IREGIHEAPBASE 0 IREGIHEAPBASE IREGIORL2I 0 IREGI IREGIORL 0 IREGI IREGILNP 0 IREGI IREGILNPNOSP 0 IREGINOSP
#
#
#
#
#
#
# Current thread is 4175807 Dumping core ... Aborted
可以通过修改 src/hotspot/share/opto/matcher.cpp: Label_Root 函数,加日志方式来验证是否 ClearArray 节点是否能够正常通过。
参考arm32 发现riscv32.ad: castP2X 这里也需要修改
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index 31c501b306..59086f8c5f 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -7251,7 +7251,7 @@ instruct castX2P(iRegPNoSp dst, iRegL src) %{
ins_pipe(ialu_reg);
%}
-instruct castP2X(iRegLNoSp dst, iRegP src) %{
+instruct castP2X(iRegI dst, iRegP src) %{
match(Set dst (CastP2X src));
ins_cost(ALU_COST);
参考arm32 发现riscv32.ad: castP2X 这里也需要修改
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad index 31c501b306..59086f8c5f 100644 --- a/src/hotspot/cpu/riscv32/riscv32.ad +++ b/src/hotspot/cpu/riscv32/riscv32.ad @@ -7251,7 +7251,7 @@ instruct castX2P(iRegPNoSp dst, iRegL src) %{ ins_pipe(ialu_reg); %} -instruct castP2X(iRegLNoSp dst, iRegP src) %{ +instruct castP2X(iRegI dst, iRegP src) %{ match(Set dst (CastP2X src)); ins_cost(ALU_COST);
我建议这里改成 iRegINoSp
,更符合原先的代码格式。
根据上文提交 PR: https://github.com/openjdk-riscv/jdk11u/pull/396 修改点:
zifeihan@k9-plct:~/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin$ /home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/frame_riscv32.inline.hpp:79
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/zifeihan/jdk11u/src/hotspot/cpu/riscv32/frame_riscv32.inline.hpp:79), pid=1019264, tid=1019266
# assert(pc != __null) failed: no pc?
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.zifeihan.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.zifeihan.jdk11u, mixed mode, serial gc, linux-riscv32)
# 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/zifeihan/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid1019264.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 1019266
Dumping core ...
Aborted
zifeihan@k9-plct:~/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin$
验证修复是否有效,我们可以打上如下日志,因为 OrI 报错时的 n->Opcode() 为221,修复前走不到最后的日志位置。修复后可以走到最后的日志位置。
diff --git a/src/hotspot/share/opto/matcher.cpp b/src/hotspot/share/opto/matcher.cpp
index 9437d379d3..07b8cf466a 100644
--- a/src/hotspot/share/opto/matcher.cpp
+++ b/src/hotspot/share/opto/matcher.cpp
@@ -1588,6 +1588,16 @@ Node* Matcher::Label_Root(const Node* n, State* svec, Node* control, Node*& mem)
svec->dump();
assert( false, "bad AD file" );
}
+
+ int aa = n->Opcode();
+ if (aa == 221)
+ {
+ warning("----------------------");
+ n->dump();
+ svec->dump();
+ warning("----------------------");
+ }
+
#endif
return control;
}
打上这个patch来输出日志:
diff --git a/src/hotspot/cpu/riscv32/frame_riscv32.inline.hpp b/src/hotspot/cpu/riscv32/frame_riscv32.inline.hpp
index 1f7a278ec6..c882d69cc7 100644
--- a/src/hotspot/cpu/riscv32/frame_riscv32.inline.hpp
+++ b/src/hotspot/cpu/riscv32/frame_riscv32.inline.hpp
@@ -77,6 +77,7 @@ inline frame::frame(intptr_t* ptr_sp, intptr_t* unextended_sp, intptr_t* ptr_fp,
_fp = ptr_fp;
_pc = pc;
assert(pc != NULL, "no pc?");
+ warning("yes pc!");
_cb = CodeCache::find_blob(pc);
adjust_unextended_sp();
添加上这个修改 https://github.com/openjdk-riscv/jdk11u/issues/381#issue-1213836018
可以发现多打印了一行日志,报错信息也改变了(左侧为PR #396 之后的报错 ):
在 PR #396 的代码下确实会有大概10%的概率出现下列报错:
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/sharedRuntime.cpp:1259
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/dingli/jdk11u-jit/src/hotspot/share/runtime/sharedRuntime.cpp:1259), pid=2794490, tid=2794492
# guarantee(caller_cb != NULL && caller_cb->is_compiled()) failed: must be called from compiled method
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.dingli.jdk11u-jit)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.dingli.jdk11u-jit, mixed mode, serial gc, linux-riscv32)
# 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/dingli/jdk11u-jit/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid2794490.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
在 https://github.com/openjdk-riscv/jdk11u/issues/381#issue-1213836018 修改前后分别运行100次,日志如下: log_run_8.log log_run_16.log
可以看到在其中StackAlignmentInBytes为8的情况下报错有89次是no pc
,11次是 failed: must be called from compiled method
,StackAlignmentInBytes为16的时候报错全部是 failed: must be called from compiled method
,结合 https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1128552870 ,https://github.com/openjdk-riscv/jdk11u/issues/381#issue-1213836018 确实可以往前推进,并且固定报错信息。
已提交PR #397
当下的entry_frame_call_wrapper_offset和RV64、aarch64是一样的,都是-8,但是X86和arm的32位用的都是0或者2。 这个值,是由stubGenerator_riscv32.cpp之中的enum call_stub_layout之中的call_wrapper_off = -8决定的。 目前,还没有其他架构的64位和32位使用相同的结果,所以,怀疑RV32的enum call_stub_layout和RV64一致是否合适。
OpenJDK for RV32G当前的报错如下:
zifeihan@k9-plct:~/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin$ /home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/sharedRuntime.cpp:1259
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/zifeihan/jdk11u/src/hotspot/share/runtime/sharedRuntime.cpp:1259), pid=776332, tid=776334
# guarantee(caller_cb != NULL && caller_cb->is_compiled()) failed: must be called from compiled method
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.zifeihan.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.zifeihan.jdk11u, mixed mode, serial gc, linux-riscv32)
# 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/zifeihan/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid776332.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 776334
Dumping core ...
Aborted
通过如下参数打印编译日志:/home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java -XX:+LogCompilation -XX:LogFile=/home/zifeihan/aaaaa.xml
OpenJDK for RV32G 编译日志附件:aaaaa.xml.zip
可以看到如下方法编译失败:jdk.internal.org.objectweb.asm.ByteVector putUTF8 (Ljava/lang/String;)Ljdk/internal/org/objectweb/asm/ByteVector;
相同的方法在BishengJDK 里面并没有报错, 因为OpenJDK for RV32G是在第一次进入src/hotspot/share/runtime/sharedRuntime.cpp:SharedRuntime::resolve_sub_helper(JavaThread *thread,bool is_virtual,bool is_optimized, TRAPS)
方法时报错的,通过在 bishengJDK 代码中对 OpenJDK for RV32G 报错的位置进行打印日志数据,发现本身 codeblob 指向的方法是 "jdk.internal.org.objectweb.asm.ByteVector.putUTF8(Ljava/lang/String;)Ljdk/internal/org/objectweb/asm/ByteVector;"
这个方法也正好对应了 OpenJDK for RV32G 编译日志中报错的方法。
BishengJDK 编译日志附件:bishengJDK.xml.zip
推测目前可能造成 OpenJDK for RV32G 报错 的问题有两个:
jdk.internal.org.objectweb.asm.ByteVector putUTF8 (Ljava/lang/String;)Ljdk/internal/org/objectweb/asm/ByteVector;
编译失败导致的报错,这个报错之前在aarch64上也出现过:https://bugs.openjdk.java.net/browse/JDK-8183543 。jdk.internal.org.objectweb.asm.ByteVector putUTF8 (Ljava/lang/String;)Ljdk/internal/org/objectweb/asm/ByteVector;
的方法,也有可能OpenJDK for RV32G 当前的 codeblob 指向的是一个错误的codeblob
- 因为
jdk.internal.org.objectweb.asm.ByteVector putUTF8 (Ljava/lang/String;)Ljdk/internal/org/objectweb/asm/ByteVector;
编译失败导致的报错,这个报错之前在aarch64上也出现过:https://bugs.openjdk.java.net/browse/JDK-8183543 。
参考arm, x86 的64位和32位对比,INTPRESSURE 参数应该是指明用作 long 类型数据运算寄存器的个数。
编译报错的问题打上如下patch,然后重新执行,编译日志里面就没有报错的日志了:
diff --git a/src/hotspot/cpu/riscv32/c2_globals_riscv32.hpp b/src/hotspot/cpu/riscv32/c2_globals_riscv32.hpp
index 08a2de1235..90c7b6d1dd 100644
--- a/src/hotspot/cpu/riscv32/c2_globals_riscv32.hpp
+++ b/src/hotspot/cpu/riscv32/c2_globals_riscv32.hpp
@@ -50,7 +50,7 @@ define_pd_global(intx, ConditionalMoveLimit, 0);
define_pd_global(intx, FLOATPRESSURE, 64);
define_pd_global(intx, FreqInlineSize, 325);
define_pd_global(intx, MinJumpTableSize, 10);
-define_pd_global(intx, INTPRESSURE, 24);
+define_pd_global(intx, INTPRESSURE, 12);
define_pd_global(intx, InteriorEntryAlignment, 16);
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
define_pd_global(intx, LoopUnrollLimit, 60);
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index a3837df4df..891d7125c8 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -361,7 +361,7 @@ reg_class int_r14_reg(R14);
// Singleton class for R29 int register
reg_class int_r29_reg(R29);
-reg_class long_reg (R10, R11, R12, R13);
+reg_class long_reg (R10,R11, R12,R13, R14,R15, R16,R17, R18,R19, R20,R21);
reg_class long_r10r11_reg(R10, R11);
reg_class long_r12r13_reg(R12, R13);
针对目前的报错:
zifeihan@k9-plct:~/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin$ /home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/sharedRuntime.cpp:1259
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/zifeihan/jdk11u/src/hotspot/share/runtime/sharedRuntime.cpp:1259), pid=776332, tid=776334
# guarantee(caller_cb != NULL && caller_cb->is_compiled()) failed: must be called from compiled method
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.zifeihan.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.zifeihan.jdk11u, mixed mode, serial gc, linux-riscv32)
# 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/zifeihan/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid776332.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 776334
Dumping core ...
Aborted
为了查看报错时的codeblob 指针指向,我们加入如下日志:
diff --git a/src/hotspot/cpu/riscv32/frame_riscv32.cpp b/src/hotspot/cpu/riscv32/frame_riscv32.cpp
index 56fab75baa..4c966aa2dc 100644
--- a/src/hotspot/cpu/riscv32/frame_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/frame_riscv32.cpp
@@ -463,6 +463,7 @@ frame frame::sender_for_compiled_frame(RegisterMap* map) const {
// the return_address is always the word on the stack
address sender_pc = (address) *(l_sender_sp-1);
+ warning("sender pc: %p , value: %p", l_sender_sp-1, sender_pc);
intptr_t** saved_fp_addr = (intptr_t**) (l_sender_sp - frame::sender_sp_offset);
首先我们将断点打在 /home/zifeihan/jdk11u/src/hotspot/share/runtime/sharedRuntime.cpp:1259
查看报错时的调用栈。
该函数大体汇编代码如下,并可以大致推测该函数保存了很多寄存器,并结合调用场景分析应该是src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp:gen_c2i_adapter 函数生成的汇编代码。
通过对bishengJDK的调试,发现bishengJDK的codeblob 的指针指向是通过类似上述汇编函数的第一条和第二条指令来修改的,也就是如下两条汇编代码,也就是这里通过 4(sp) 来指向codeblob,注意这条汇编的内存地址(*0x3b8a8684),下一步需要在该地址打断点。
第二步,查看通过warning("sender pc: %p , value: %p", l_sender_sp-1, sender_pc);
打印出来的内存地址,是否是上一步所说的 4(sp) 指向的内存地址。
第三步,重新启动程序,并将断点打到*0x3b8a8684
,并查看前后40条指令,对比是否是第一步所看的汇编函数的指令,此处可以看到确实是该函数。
这里我们查看 4(sp) 的地址为:sp + 4 = 0x3ec89ac0 + 4 = 0x3ec89ac4 , 这个地址和我们通过warning("sender pc: %p , value: %p", l_sender_sp-1, sender_pc);
打印出来的内存地址:0x3ec89bc4 相差了 256
第四步,查看 src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp:gen_c2i_adapter
函数逻辑,查看该函数中调用了push_CPU_state
函数,然而该函数保存浮点数寄存器,但是这里使用 fsd 指令把每个浮点数寄存器用了wordsize(4)字节的的内存空间来保存。于是我们修改此处代码如下:
diff --git a/src/hotspot/cpu/riscv32/frame_riscv32.cpp b/src/hotspot/cpu/riscv32/frame_riscv32.cpp
index 56fab75baa..4c966aa2dc 100644
--- a/src/hotspot/cpu/riscv32/frame_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/frame_riscv32.cpp
@@ -463,6 +463,7 @@ frame frame::sender_for_compiled_frame(RegisterMap* map) const {
// the return_address is always the word on the stack
address sender_pc = (address) *(l_sender_sp-1);
+ warning("sender pc: %p , value: %p", l_sender_sp-1, sender_pc);
intptr_t** saved_fp_addr = (intptr_t**) (l_sender_sp - frame::sender_sp_offset);
diff --git a/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp b/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp
index a709354131..2c2509b580 100644
--- a/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp
@@ -1152,17 +1152,17 @@ void MacroAssembler::popa() {
void MacroAssembler::push_CPU_state() {
push_reg(0xfffffff8, sp); // integer registers except zr(x0) & ra(x1) & sp(x2)
// float registers
- addi(sp, sp, - 32 * wordSize);
+ addi(sp, sp, - 32 * 2 * wordSize);
for (int i = 0; i <= 31; i ++) {
- fsd(as_FloatRegister(i), Address(sp, i * wordSize));
+ fsd(as_FloatRegister(i), Address(sp, i * 2 * wordSize));
}
}
void MacroAssembler::pop_CPU_state() {
for (int i = 0; i <= 31; i ++) {
- fld(as_FloatRegister(i), Address(sp, i * wordSize));
+ fld(as_FloatRegister(i), Address(sp, i * 2 * wordSize));
}
- addi(sp, sp, 32 * wordSize);
+ addi(sp, sp, 32 * 2 * wordSize);
pop_reg(0xfffffff8, sp); // integer registers except zr(x0) & ra(x1) & sp(x2)
}
然后编译重新启动,再次通过上面的办法调试,发现 4(sp) 的地址为:sp + 4 = 0x3ec89ac0 + 4 = 0x3ec89ac4 , 这个地址和我们通过warning("sender pc: %p , value: %p", l_sender_sp-1, sender_pc);
打印出来的内存地址: 0x3ec89b44 相差了 128
通过这里的代码调试,我们发现在 src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp:gen_c2i_adapter 中对 sp 的操作,会影响当前的报错问题。如果我们在这里将还缺失的128偏移量补上去,那么当前的问题就得以解决。
这里我们通过将开辟的大小 * 3 ,来补上缺失的 256 字节的大小。
注意:已提交pr: https://github.com/openjdk-riscv/jdk11u/pull/401 ,修复后对当前结果没影响。如上述,修复后通过调试发现,内存差距小了。目前这里我觉得改成将原有大小 * 2是合理的,因为 fsd 操作 8 字节的内存数据,但是改成 3 就不合理了,目前还相差的 128 字节数据还在排查中。
diff --git a/src/hotspot/cpu/riscv32/frame_riscv32.cpp b/src/hotspot/cpu/riscv32/frame_riscv32.cpp
index 56fab75baa..4c966aa2dc 100644
--- a/src/hotspot/cpu/riscv32/frame_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/frame_riscv32.cpp
@@ -463,6 +463,7 @@ frame frame::sender_for_compiled_frame(RegisterMap* map) const {
// the return_address is always the word on the stack
address sender_pc = (address) *(l_sender_sp-1);
+ warning("sender pc: %p , value: %p", l_sender_sp-1, sender_pc);
intptr_t** saved_fp_addr = (intptr_t**) (l_sender_sp - frame::sender_sp_offset);
diff --git a/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp b/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp
index a709354131..2c2509b580 100644
--- a/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp
@@ -1152,17 +1152,17 @@ void MacroAssembler::popa() {
void MacroAssembler::push_CPU_state() {
push_reg(0xfffffff8, sp); // integer registers except zr(x0) & ra(x1) & sp(x2)
// float registers
- addi(sp, sp, - 32 * wordSize);
+ addi(sp, sp, - 32 * 2 * wordSize);
for (int i = 0; i <= 31; i ++) {
- fsd(as_FloatRegister(i), Address(sp, i * wordSize));
+ fsd(as_FloatRegister(i), Address(sp, i * 2 * wordSize));
}
}
void MacroAssembler::pop_CPU_state() {
for (int i = 0; i <= 31; i ++) {
- fld(as_FloatRegister(i), Address(sp, i * wordSize));
+ fld(as_FloatRegister(i), Address(sp, i * 2 * wordSize));
}
- addi(sp, sp, 32 * wordSize);
+ addi(sp, sp, 32 * 2 * wordSize);
pop_reg(0xfffffff8, sp); // integer registers except zr(x0) & ra(x1) & sp(x2)
}
打上如下patch,即可解决当前遇到的编译问题,src/hotspot/share/runtime/sharedRuntime.cpp:SharedRuntime::resolve_sub_helper(JavaThread *thread,bool is_virtual,bool is_optimized, TRAPS) 也可以正常执行结束,修复后遇到了一个新的问题,目前正在排查新的问题。
diff --git a/src/hotspot/cpu/riscv32/c2_globals_riscv32.hpp b/src/hotspot/cpu/riscv32/c2_globals_riscv32.hpp
index 08a2de1235..90c7b6d1dd 100644
--- a/src/hotspot/cpu/riscv32/c2_globals_riscv32.hpp
+++ b/src/hotspot/cpu/riscv32/c2_globals_riscv32.hpp
@@ -50,7 +50,7 @@ define_pd_global(intx, ConditionalMoveLimit, 0);
define_pd_global(intx, FLOATPRESSURE, 64);
define_pd_global(intx, FreqInlineSize, 325);
define_pd_global(intx, MinJumpTableSize, 10);
-define_pd_global(intx, INTPRESSURE, 24);
+define_pd_global(intx, INTPRESSURE, 12);
define_pd_global(intx, InteriorEntryAlignment, 16);
define_pd_global(intx, NewSizeThreadIncrease, ScaleForWordSize(4*K));
define_pd_global(intx, LoopUnrollLimit, 60);
diff --git a/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp b/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp
index a709354131..2c2509b580 100644
--- a/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/macroAssembler_riscv32.cpp
@@ -1152,17 +1152,17 @@ void MacroAssembler::popa() {
void MacroAssembler::push_CPU_state() {
push_reg(0xfffffff8, sp); // integer registers except zr(x0) & ra(x1) & sp(x2)
// float registers
- addi(sp, sp, - 32 * wordSize);
+ addi(sp, sp, - 32 * 2 * wordSize);
for (int i = 0; i <= 31; i ++) {
- fsd(as_FloatRegister(i), Address(sp, i * wordSize));
+ fsd(as_FloatRegister(i), Address(sp, i * 2 * wordSize));
}
}
void MacroAssembler::pop_CPU_state() {
for (int i = 0; i <= 31; i ++) {
- fld(as_FloatRegister(i), Address(sp, i * wordSize));
+ fld(as_FloatRegister(i), Address(sp, i * 2 * wordSize));
}
- addi(sp, sp, 32 * wordSize);
+ addi(sp, sp, 32 * 2 * wordSize);
pop_reg(0xfffffff8, sp); // integer registers except zr(x0) & ra(x1) & sp(x2)
}
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index a3837df4df..891d7125c8 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -361,7 +361,7 @@ reg_class int_r14_reg(R14);
// Singleton class for R29 int register
reg_class int_r29_reg(R29);
-reg_class long_reg (R10, R11, R12, R13);
+reg_class long_reg (R10,R11, R12,R13, R14,R15, R16,R17, R18,R19, R20,R21);
reg_class long_r10r11_reg(R10, R11);
reg_class long_r12r13_reg(R12, R13);
diff --git a/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp b/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
index 7fbcd0bc0f..468cce0810 100644
--- a/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
@@ -94,13 +94,13 @@ class RegisterSaver {
// |---ra---|
static int reg_offset_in_bytes(Register r) {
assert (r->encoding() > 2, "ra and sp not saved");
- return (32 /* floats*/ + r->encoding() - 2 /* x1, x2*/) * wordSize;
+ return (r->encoding() - 2 /* x1, x2*/) * wordSize + 32 * 2 * wordSize /* floats*/ ;
}
static int x10_offset_in_bytes(void) { return reg_offset_in_bytes(x10); } // x10
static int xmethod_offset_in_bytes(void) { return reg_offset_in_bytes(xmethod); } // x31
static int tmp0_offset_in_bytes(void) { return reg_offset_in_bytes(t0); } // x5
static int f0_offset_in_bytes(void) { return 0; }
- static int f10_offset_in_bytes(void) { return 10 /* floats*/ * wordSize; }
+ static int f10_offset_in_bytes(void) { return 10 /* floats*/ * 2 * wordSize; }
static int return_offset_in_bytes(void) { return return_off * BytesPerInt; }
// During deoptimization only the result registers need to be restored,
@@ -116,9 +116,9 @@ class RegisterSaver {
// setting for it. We must therefore force the layout
// so that it agrees with the frame sender code.
x0_off = fpu_state_off + FPUStateSizeInWords,
- fp_off = x0_off + 30 * 2,
- return_off = fp_off + 2, // slot for return address
- reg_save_size = return_off + 2
+ fp_off = x0_off + 30,
+ return_off = fp_off + 1, // slot for return address
+ reg_save_size = return_off + 1
};
};
@@ -150,7 +150,7 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_
for (int i = 3; i < RegisterImpl::number_of_registers; i++) {
Register r = as_Register(i);
if (r != xthread && r != t0 && r != t1) {
- int sp_offset = 2 * ((i - 2) + 32); // SP offsets are in 4-byte words, register slots are 8 bytes
+ int sp_offset = (i - 2) + (32 * 2); // SP offsets are in 4-byte words, register slots are 8 bytes
// wide, 32 floating-point registers
oop_map->set_callee_saved(VMRegImpl::stack2reg(sp_offset + additional_frame_slots), r->as_VMReg());
}
修复后的结果:
通过查看jit编译日志,也可以看到比原来编译的方法更多了,可以通过如下命令打印jit日志:/home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java -XX:+LogCompilation -XX:LogFile=jit.log
通过对原来的报错方法打断点,发现该方法可以正常执行完成
- fp_off = x0_off + 30 * 2, - return_off = fp_off + 2, // slot for return address - reg_save_size = return_off + 2 + fp_off = x0_off + 30, + return_off = fp_off + 1, // slot for return address + reg_save_size = return_off + 1
这一部分是参考arm尝试进行的修复,按照arm32位推测,整数寄存器宽度为4字节,因此这里不需要*2
- return (32 / floats/ + r->encoding() - 2 / x1, x2/) * wordSize;
- return (r->encoding() - 2 / x1, x2/) wordSize + 32 2 wordSize / floats*/ ;
建议改为: return (2 32 / floats/ + r->encoding() - 2 / x1, x2/) wordSize
打上如下patch,即可解决当前遇到的编译问题,src/hotspot/share/runtime/sharedRuntime.cpp:SharedRuntime::resolve_sub_helper(JavaThread *thread,bool is_virtual,bool is_optimized, TRAPS) 也可以正常执行结束
目前的报错如下
zifeihan@k9-plct:~/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin$ /home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot -g 28080 ./java -XX:+LogCompilation -XX:LogFile=compile.log
Warning: TraceDependencies results may be inflated by VerifyDependencies
OpenJDK Server VM warning: hello
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/oopMap.cpp:552
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/zifeihan/jdk11u/src/hotspot/share/compiler/oopMap.cpp:552), pid=2561590, tid=2561689
# assert(last->pc_offset() == pc_offset) failed: oopmap not found
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.zifeihan.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.zifeihan.jdk11u, mixed mode, serial gc, linux-riscv32)
# 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/zifeihan/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid2561590.log
OpenJDK Server VM warning: hello
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 2561689
Dumping core ...
Aborted
assert 中的80是从经过如下函数处理转换而来,主要是通过原来的值32 + 12 NativeInstruction::instruction_size = 80 , 抛开原来的值32,优先排查这里的 12 NativeInstruction::instruction_size 合理性。
在昨天的测试中发现,使用make images编译的时候,会报错: 这个错误经过排查是由 #396 引入的,后续需要解决。
根据 @zifeihan 的分析,在pr 393的时候 虽然都是bad ad file的报错 ,但是make 和make images报错的node节点不同。可能在make images还有报错的节点也需要修改:
分析报错信息,可以看到URShiftI是需要一个IREGIORL2I节点来匹配的,也就是castP2X需要在DFA中将IREGIORL2I设置为VALID,而在 https://github.com/openjdk-riscv/jdk11u/pull/396 中已经将castP2X的参数修改过了。我们可以回退到PR #393 的节点,只修改castP2X的参数,编译后可以看到: 上图这里的castP2X已经拥有了IREGIORL2I节点,而报错信息对应了PR #396 中对R29的修改:
可以添加打印日志来查看是否修复了URShiftI的问题: 可以看到URShiftI相关的报错已经修复了。
PR396共有两个修改,一个是castP2X参数由iRegLNoSp变为iRegINoSp的修改,一个是R29相关的修改。这两个修改都解决各自的问题。当这两个修改分开提交的时候,正常解决各自的问题,没有异常。但是当着两个修改同时提交之后,make images编译出来的结果,就会导致出现“Error occurred during initialization of boot layer”的错误。
当前通过make images编译出的可执行文件,在执行过程中存在如下报错:
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: /home/zifeihan/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/modules/jdk.naming.rmi
Caused by: java.lang.module.InvalidModuleDescriptorException: Package com.sun.jndi.rmi.registry missing from ModulePackages class file attribute
接下来通过添加打印日志,辅助排查该问题如:
diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java b/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java
index 33e5b33f96..744fae0fba 100644
--- a/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java
+++ b/src/java.base/share/classes/jdk/internal/module/ModuleInfo.java
@@ -310,7 +310,16 @@ public final class ModuleInfo {
}
if (allPackages != null) {
Set<String> knownPackages = JLMA.packages(builder);
+ System.out.println("-------------");
+ System.out.println(allPackages);
+ System.out.println(knownPackages);
+ System.out.println("-------------");
if (!allPackages.containsAll(knownPackages)) {
+
+ System.out.println("+++++++++++++");
+ System.out.println(allPackages);
+ System.out.println(knownPackages);
+ System.out.println("+++++++++++++");
Set<String> missingPackages = new HashSet<>(knownPackages);
missingPackages.removeAll(allPackages);
assert !missingPackages.isEmpty();
可以看到这里的 if (!allPackages.containsAll(knownPackages)) {
判断条件成立了,导致进入了报错的节点。但实际上通过打印出来的数据,自己写一个方法进行测试,也不会进入类似报错的节点。这里的Set 数据结构也很奇怪,按理来说Set不能有重复的元素,但是这里通过日志打印出来了。通过 if (!allPackages.containsAll(knownPackages)) {
本应该不成立的判断条件也说明了Set这个数据结构中的判断有问题。
通过查看jit的编译日志,通过如下参数:/home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java -XX:+LogCompilation -XX:LogFile=compile.log
查看编译的java方法的日志。
日志如下:
<task_queued compile_id='16' method='java.lang.StringLatin1 replace ([BCC)Ljava/lang/String;' bytes='196' count='309' backedge_count='5000' iicount='309' stamp='2.895' comment='count' hot_count='309'/>
<task_queued compile_id='17' method='java.lang.StringLatin1 indexOf ([BII)I' bytes='61' count='1081' backedge_count='5000' iicount='1081' stamp='2.899' comment='count' hot_count='1081'/>
<task_queued compile_id='18' method='java.io.DataInputStream readUTF (Ljava/io/DataInput;)Ljava/lang/String;' bytes='501' count='414' backedge_count='5000' iicount='414' stamp='2.921' comment='count' hot_count='414'/>
<task_queued compile_id='19' method='java.lang.StringUTF16 compress ([CI[BII)I' bytes='50' count='414' backedge_count='5000' iicount='414' stamp='2.922' comment='count' hot_count='414'/>
<task_queued compile_id='20' method='jdk.internal.module.ModuleInfo$ConstantPool checkUnqualifiedName (Ljava/lang/String;ILjava/lang/String;)V' bytes='131' count='358' backedge_count='5000' iicount='358' stamp='2.941' comment='count' hot_count='358'/>
<task_queued compile_id='21' method='java.lang.StringLatin1 inflate ([BI[CII)V' bytes='34' count='127' backedge_count='5000' iicount='127' stamp='2.951' comment='count' hot_count='127'/>
<task_queued compile_id='22' method='sun.nio.cs.UTF_8$Encoder encodeArrayLoop (Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;' bytes='489' count='117' backedge_count='5000' iicount='117' stamp='2.952' comment='count' hot_count='117'/>
<task_queued compile_id='23' method='java.lang.Object <init> ()V' bytes='1' count='5000' backedge_count='1' iicount='10000' stamp='3.035' comment='count' hot_count='10000'/>
<
我们在启动过程中通过屏蔽某个方法的jit编译,来查看是否是该方法导致了当前问题的发生,通过类似如下参数:/home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java -XX:CompileCommand=exclude,"java/lang/StringLatin1.replace" -XX:+LogCompilation -XX:LogFile=compile.log
当屏蔽到java.lang.StringLatin1 indexOf
方法时,发现原本报错的数据正常了。因此推测Set数据结构在添加或者判断数据时,可能调用到了java.lang.StringLatin1 indexOf
方法,目前需要通过对java.lang.StringLatin1 indexOf
方法生成的jit代码调试,排查问题发生的具体位置。
基于 comment 的分析,观察了此时的报错
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/icBuffer_riscv32.cpp:65
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/zhangxiang/rv32/jdk11u/src/hotspot/cpu/riscv32/icBuffer_riscv32.cpp:65), pid=754419, tid=754421
# assert(masm-> pc() - start == ic_stub_code_size()) failed: must be
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.zhangxiang.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.zhangxiang.jdk11u, mixed mode, serial gc, linux-riscv32)
# 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/zhangxiang/rv32/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid754419.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 754421
Dumping core ...
Aborted
再看报错处函数
void InlineCacheBuffer::assemble_ic_buffer_code(address code_begin, void* cached_value, address entry_point) {
assert_cond(code_begin != NULL && entry_point != NULL);
ResourceMark rm;
CodeBuffer code(code_begin, ic_stub_code_size());
MacroAssembler* masm = new MacroAssembler(&code);
// note: even though the code contains an embedded value, we do not need reloc info
// because
// (1) the value is old (i.e., doesn't matter for scavenges)
// (2) these ICStubs are removed *before* a GC happens, so the roots disappear
address start = __ pc();
Label l;
__ lw(t1, l);
__ far_jump(ExternalAddress(entry_point));
__ align(wordSize);
__ bind(l);
__ emit_int32((intptr_t)cached_value);
// Only need to invalidate the 1st two instructions - not the whole ic stub
ICache::invalidate_range(code_begin, InlineCacheBuffer::ic_stub_code_size());
int temp=__ pc() - start;
assert(__ pc() - start == ic_stub_code_size(), "must be");
}
对ic_stub_code_size()阅读发现,
int InlineCacheBuffer::ic_stub_code_size() {
// 6: auipc + lw + auipc + jalr + address(2 * instruction_size)
// 5: auipc + lw + j + address(2 * instruction_size )
return (MacroAssembler::far_branches() ? 6 : 5) * NativeInstruction::instruction_size;
}
其中address(2 * instruction_size)在rv64中,地址长度为8字节,由于instruction_size值为4,所以需要×2.而在rv32中,不需要再x2,那么相应的返回值的6-->5,5-->4.
int InlineCacheBuffer::ic_stub_code_size() {
// 5: auipc + lw + auipc + jalr + address(1 * instruction_size)
// 4: auipc + lw + j + address(1 * instruction_size )
return (MacroAssembler::far_branches() ? 5 : 4) * NativeInstruction::instruction_size;
}
修改后的
qemu32 ./java-bak -version
qemu32 ./java-bak -XX:CompileCommand=exclude,"java/lang/StringLatin1.replace" -version
make
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/oopMap.cpp:547
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/zhangxiang/rv32/jdk11u/src/hotspot/share/compiler/oopMap.cpp:547), pid=1379443, tid=1379445
# assert(last->pc_offset() == pc_offset) failed: oopmap not found
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.zhangxiang.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.zhangxiang.jdk11u, mixed mode, serial gc, linux-riscv32)
# 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/zhangxiang/rv32/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid1379443.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 1379445
Dumping core ...
Aborted
make images
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: /home/zhangxiang/rv32/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/modules/java.compiler
Caused by: java.lang.module.InvalidModuleDescriptorException: Module attribute not found
且此时make images与make的结果不一致。
基于 qemu32 ./java-bak -XX:+LogCompilation -XX:LogFile=compile.log -version
查看log后发现
<nmethod compile_id='11' compiler='c2' entry='0x3b960d40' size='1320' address='0x3b960c08' relocation_offset='240' insts_offset='312' stub_offset='824' scopes_data_offset='880' scopes_pcs_offset='984' dependencies_offset='1304' nul_chk_table_offset='1308' metadata_offset='876' method='java.lang.StringLatin1 hashCode ([B)I' bytes='42' count='582' backedge_count='8556' iicount='582' stamp='2.798'/>
<nmethod compile_id='12' compiler='c2' entry='0x3b960980' size='904' address='0x3b960848' relocation_offset='240' insts_offset='312' stub_offset='504' scopes_data_offset='584' scopes_pcs_offset='680' dependencies_offset='888' nul_chk_table_offset='892' metadata_offset='572' method='java.lang.String charAt (I)C' bytes='25' count='7278' backedge_count='1' iicount='17277' stamp='2.831'/>
<nmethod compile_id='13' compiler='c2' entry='0x3b9606c0' size='676' address='0x3b960588' relocation_offset='240' insts_offset='312' stub_offset='440' scopes_data_offset='496' scopes_pcs_offset='532' dependencies_offset='660' nul_chk_table_offset='664' metadata_offset='492' method='java.lang.StringLatin1 charAt ([BI)C' bytes='28' count='7278' backedge_count='1' iicount='17277' stamp='2.843'/>
<writer thread='773840'/>
<task_queued compile_id='16' method='java.lang.StringLatin1 replace ([BCC)Ljava/lang/String;' bytes='196' count='308' backedge_count='5000' iicount='308' stamp='2.857' comment='count' hot_count='308'/>
<task_queued compile_id='17' method='java.lang.StringLatin1 indexOf ([BII)I' bytes='61' count='1144' backedge_count='5000' iicount='1144' stamp='2.861' comment='count' hot_count='1144'/>
<task_queued compile_id='18' method='java.io.DataInputStream readUTF (Ljava/io/DataInput;)Ljava/lang/String;' bytes='501' count='414' backedge_count='5000' iicount='414' stamp='2.884' comment='count' hot_count='414'/>
<task_queued compile_id='19' method='java.lang.StringUTF16 compress ([CI[BII)I' bytes='50' count='414' backedge_count='5000' iicount='414' stamp='2.884' comment='count' hot_count='414'/>
<task_queued compile_id='20' method='jdk.internal.module.ModuleInfo$ConstantPool checkUnqualifiedName (Ljava/lang/String;ILjava/lang/String;)V' bytes='131' count='358' backedge_count='5000' iicount='358' stamp='2.903' comment='count' hot_count='358'/>
<task_queued compile_id='21' method='java.lang.StringLatin1 inflate ([BI[CII)V' bytes='34' count='127' backedge_count='5000' iicount='127' stamp='2.915' comment='count' hot_count='127'/>
<task_queued compile_id='22' method='sun.nio.cs.UTF_8$Encoder encodeArrayLoop (Ljava/nio/CharBuffer;Ljava/nio/ByteBuffer;)Ljava/nio/charset/CoderResult;' bytes='489' count='117' backedge_count='5000' iicount='117' stamp='2.915' comment='count' hot_count='117'/>
<task_queued compile_id='23' method='java.lang.Object <init> ()V' bytes='1' count='5000' backedge_count='1' iicount='10000' stamp='3.004' comment='count' hot_count='10000'/>
<writer thread='773855'/>
与comment 中的log一致。
在 da0122 的基础上,观察 https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1157460071 的报错,报错位于:
https://github.com/openjdk-riscv/jdk11u/blob/da01225aa369883c93bffaab75ab17fba5de604f/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp#L150-L159
观察ARM的逻辑:
发现32位和64位的逻辑是不同的,在rv32与rv64的处理也可能是不一样的,明显的一点是 intptr_t* locals
中的 intptr_t
在rv32和rv64中的长度不同分别是4和8(intptr_t总是与地址的字节数相同)。参照ARM将locals的赋值判断更改为只有 interpreter_frame->sender_sp() + max_locals
,同时加上https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1160522308 中的改动,patch为:
diff --git a/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp b/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp
index b8a408a592..a2470c9a97 100644
--- a/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp
@@ -147,17 +147,7 @@ void AbstractInterpreter::layout_activation(Method* method,
// expression stack. For other types of caller frame it doesn't
// matter.
intptr_t* locals = NULL;
- if (caller->is_interpreted_frame()) {
- locals = caller->interpreter_frame_last_sp() + caller_actual_parameters - 1;
- } else {
locals = interpreter_frame->sender_sp() + max_locals - 1;
- }
-
-#ifdef ASSERT
- if (caller->is_interpreted_frame()) {
- assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
- }
-#endif
interpreter_frame->interpreter_frame_set_locals(locals);
BasicObjectLock* montop = interpreter_frame->interpreter_frame_monitor_begin();
diff --git a/src/hotspot/cpu/riscv32/icBuffer_riscv32.cpp b/src/hotspot/cpu/riscv32/icBuffer_riscv32.cpp
index b571e97812..0966fed0a3 100644
--- a/src/hotspot/cpu/riscv32/icBuffer_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/icBuffer_riscv32.cpp
@@ -37,7 +37,7 @@
int InlineCacheBuffer::ic_stub_code_size() {
// 6: auipc + lw + auipc + jalr + address(2 * instruction_size)
// 5: auipc + lw + j + address(2 * instruction_size )
- return (MacroAssembler::far_branches() ? 6 : 5) * NativeInstruction::instruction_size;
+ return (MacroAssembler::far_branches() ? 5 : 4) * NativeInstruction::instruction_size;
}
#define __ masm->
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index b9f4e08981..0d6f5ebfa3 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -872,7 +872,7 @@ int MachCallRuntimeNode::ret_addr_offset() {
if (cb != NULL) {
return MacroAssembler::far_branch_size();
} else {
- return 12 * NativeInstruction::instruction_size;
+ return 8 * NativeInstruction::instruction_size;
}
}
输出信息为:
$ qemu32 build/linux-riscv32-normal-custom-slowdebug/jdk/bin/java -version
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x3f1a6dd4, pid=2220290, tid=2220292
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.dingli.jdk11u-jit)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.dingli.jdk11u-jit, mixed mode, serial gc, linux-riscv32)
# Problematic frame:
# V [libjvm.so+0x45cdd4] frame::interpreter_frame_method() const+0x86
#
# 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/dingli/jdk11u-jit/hs_err_pid2220290.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 2220292
Dumping core ...
Aborted
在打上上述make中的patch的情况下执行 make images
,输出如下:
$ qemu32 build/linux-riscv32-normal-custom-slowdebug/jdk/bin/java -version
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: /home/dingli/jdk11u-jit/build/linux-riscv32-normal-custom-slowdebug/jdk/modules/jdk.management
Caused by: java.lang.module.InvalidModuleDescriptorException: Package com.sun.management.internal missing from ModulePackages class file attribute
参照 https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1160359846 重中的方法执行:
$ qemu32 build/linux-riscv32-normal-custom-slowdebug/jdk/bin/java -XX:CompileCommand=exclude,"java.lang.StringLatin1::replace" -XX:+LogCompilation -XX:LogFile=compile.log -version
查看compile.log中的方法:
<task compile_id='18' method='jdk.internal.module.ModuleInfo$ConstantPool checkUnqualifiedName (Ljava/lang/String;ILjava/lang/String;)V' bytes='131' count='5000' backedge_count='5000' iicount='786' stamp='3.233'>
<task compile_id='9' method='java.lang.String isLatin1 ()Z' bytes='19' count='5025' backedge_count='1' iicount='10025' stamp='2.616'>
<task compile_id='11' method='java.lang.StringLatin1 hashCode ([B)I' bytes='42' count='453' backedge_count='5035' iicount='453' stamp='2.739'>
<task compile_id='12' method='java.lang.String charAt (I)C' bytes='25' count='6271' backedge_count='1' iicount='16270' stamp='2.869'>
<task compile_id='13' method='java.lang.StringLatin1 charAt ([BI)C' bytes='28' count='8874' backedge_count='1' iicount='18873' stamp='2.903'>
<task compile_id='16' method='java.io.DataInputStream readUTF (Ljava/io/DataInput;)Ljava/lang/String;' bytes='501' count='414' backedge_count='5017' iicount='414' stamp='2.926'>
<task compile_id='17' method='java.lang.StringUTF16 compress ([CI[BII)I' bytes='50' count='5000' backedge_count='5006' iicount='934' stamp='3.233'>
分别屏蔽上述几个方法,发现当前的报错是由 java.io.DataInputStream::readUTF
引起的,将这个方法加入到屏蔽的行列之中:
$ qemu32 build/linux-riscv32-normal-custom-slowdebug/jdk/bin/java -XX:CompileCommand=exclude,"java.lang.StringLatin1::replace" -XX:CompileCommand=exclude,"java.io.DataInputStream::readUTF" -version
CompileCommand: exclude java/lang/StringLatin1.replace
CompileCommand: exclude java/io/DataInputStream.readUTF
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x3b874230, pid=2389683, tid=2389685
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.dingli.jdk11u-jit)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.dingli.jdk11u-jit, mixed mode, serial gc, linux-riscv32)
# Problematic frame:
#
[error occurred during error reporting (printing problematic frame), id 0xb, SIGSEGV (0xb) at pc=0x3f1a6dc6]
# 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/dingli/jdk11u-jit/hs_err_pid2389683.log
Could not load hsdis-riscv32.so; library not loadable; PrintAssembly is disabled
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 2389685
Dumping core ...
Aborted
如果把patch中的这一部分删除:
diff --git a/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp b/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp
index b8a408a592..a2470c9a97 100644
--- a/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp
@@ -147,17 +147,7 @@ void AbstractInterpreter::layout_activation(Method* method,
// expression stack. For other types of caller frame it doesn't
// matter.
intptr_t* locals = NULL;
- if (caller->is_interpreted_frame()) {
- locals = caller->interpreter_frame_last_sp() + caller_actual_parameters - 1;
- } else {
locals = interpreter_frame->sender_sp() + max_locals - 1;
- }
-
-#ifdef ASSERT
- if (caller->is_interpreted_frame()) {
- assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
- }
-#endif
那么输出结果为:
$ qemu32 build/linux-riscv32-normal-custom-slowdebug/jdk/bin/java -XX:CompileCommand=exclude,"java.lang.StringLatin1::replace" -XX:CompileCommand=exclude,"java.io.DataInputStream::readUTF" -version
CompileCommand: exclude java/lang/StringLatin1.replace
CompileCommand: exclude java/io/DataInputStream.readUTF
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x3ee20fa0, pid=2366721, tid=2366723
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.dingli.jdk11u-jit)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.dingli.jdk11u-jit, mixed mode, serial gc, linux-riscv32)
# Problematic frame:
# V [libjvm.so+0xd6fa0] frame::interpreter_frame_last_sp() const+0x16
#
# 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/dingli/jdk11u-jit/hs_err_pid2366721.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 2366723
Dumping core ...
Aborted
可以看到报错都是 frame::interpreter_frameXX,接下来准备研究相关的逻辑。
make images的Error occurred during initialization of boot layer 问题分析(以slowdebug模式为例): 1、make images执行是先执行了make,生成了build/linux-riscv32-normal-custom-slowdebug/jdk目录,然后再执行images相关内容,生成build/linux-riscv32-normal-custom-slowdebug/images目录; 2、make和make jdk是同样的效果; 3、build/linux-riscv32-normal-custom-slowdebug/images/jdk目录的内容是可以拿到别的地方直接运行的,但是build/linux-riscv32-normal-custom-slowdebug/jdk目录的不行; 4、build/linux-riscv32-normal-custom-slowdebug/images目录的下的java -version可以直接运行,不会遇到错误; 5、这个问题只有slowdebug和fastdebug才会产生,release模式下不会产生该问题,release模式下可以得到和make相同的运行结果。
其他可能:有可能本身构建images的问题,参见:https://bugs.openjdk.org/browse/JDK-8216489
make images的Error occurred during initialization of boot layer 问题分析(以slowdebug模式为例): 1、make images执行是先执行了make,生成了build/linux-riscv32-normal-custom-slowdebug/jdk目录,然后再执行images相关内容,生成build/linux-riscv32-normal-custom-slowdebug/images目录; 2、make和make jdk是同样的效果; 3、build/linux-riscv32-normal-custom-slowdebug/images/jdk目录的内容是可以拿到别的地方直接运行的,但是build/linux-riscv32-normal-custom-slowdebug/jdk目录的不行; 4、build/linux-riscv32-normal-custom-slowdebug/images目录的下的java -version可以直接运行,不会遇到错误; 5、这个问题只有slowdebug和fastdebug才会产生,release模式下不会产生该问题,release模式下可以得到和make相同的运行结果。
其他可能:有可能本身构建images的问题,参见:https://bugs.openjdk.org/browse/JDK-8216489
目前C2 make出现如下报错:
zifeihan@k9-plct:~/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin$ /home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java -XX:+LogCompilation -XX:LogFile=compile.logWarning: TraceDependencies results may be inflated by VerifyDependencies
OpenJDK Server VM warning: hello
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/abstractInterpreter_riscv32.cpp:166
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/zifeihan/jdk11u/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp:166), pid=2671342, tid=2671347
# assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset) failed: bad placement
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.zifeihan.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.zifeihan.jdk11u, mixed mode, serial gc, linux-riscv32)
# 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/zifeihan/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/hs_err_pid2671342.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 2671347
Dumping core ...
Aborted
通过打上如下patch (含有部分的打印日志),原本报错的断言会正常通过 ,而且通过调试日志可以看出 ,此时的locals , ccccc 的数据也正常了 , 数据差为4字节。主要修改 __ add(sp, sp, (SimpleRuntimeFrame::framesize) << 1);
因为在bishengJDK下,SP 需要16字节对其,但是32位下目前都是按照8字节对其的。
diff --git a/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp b/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp
index b8a408a592..9e45e515fe 100644
--- a/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/abstractInterpreter_riscv32.cpp
@@ -153,8 +153,16 @@ void AbstractInterpreter::layout_activation(Method* method,
locals = interpreter_frame->sender_sp() + max_locals - 1;
}
+char* aaaaaa = method->name_and_sig_as_C_string();
+char* ddd = "sun.nio.fs.UnixPath.hasDotOrDotDot()Z";
+intptr_t* ccccc = caller->fp() + frame::interpreter_frame_initial_sp_offset;
+
#ifdef ASSERT
if (caller->is_interpreted_frame()) {
+ if (strcmp(aaaaaa, ddd) == 0)
+ {
+ warning("hello");
+ }
assert(locals < caller->fp() + frame::interpreter_frame_initial_sp_offset, "bad placement");
}
#endif
diff --git a/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp b/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
index 841151126f..89bac2b671 100644
--- a/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
+++ b/src/hotspot/cpu/riscv32/sharedRuntime_riscv32.cpp
@@ -2491,7 +2491,7 @@ void SharedRuntime::generate_uncommon_trap_blob() {
// 2: deopting frame (no frame link)
// 3: caller of deopting frame (could be compiled/interpreted).
- __ add(sp, sp, (SimpleRuntimeFrame::framesize) << LogBytesPerInt); // Epilog!
+ __ add(sp, sp, (SimpleRuntimeFrame::framesize) << 1); // Epilog!
// Pop deoptimized frame (int)
__ lw(x12, Address(x14,
patch打上后的报错如下,通过调试,发现确实是往下推进了。
在修复前,可以看到locals , ccccc的数据差很大,并且所在的数据段也和caller的数据段相差很大。
通过对bishengJDK的调试,发现locals , ccccc的数据差为8字节。
在上述的修改基础上,执行make,当前的错误提示:
Error occurred during initialization of boot layer java.lang.module.FindException: Error reading module: /home/shining/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/modules/jdk.scripting.nashorn Caused by: java.lang.module.InvalidModuleDescriptorException: Package jdk.nashorn.api.scripting not found in module
其中Package jdk.nashorn.api.scripting是存在的。这里找不到是有问题的。根据网络查询资料,可以将/home/shining/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/modules/jdk.scripting.nashorn目录下的module-info.class删除掉,就可以找到Package jdk.nashorn.api.scripting。
之后,会遇到错误:
Error occurred during initialization of boot layer java.lang.module.FindException: Error reading module: /home/shining/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/modules/java.net.http Caused by: java.lang.module.InvalidModuleDescriptorException: Package java.net.http not found in modul
同样,删除/home/shining/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/modules/java.net.http目录下的module-info.class也可以解决该问题。
最后,会遇到问题:
最后,会遇到问题:
在执行时加上 -XX:CompileCommand=exclude,java/lang/StringLatin1.*
参数,屏蔽 StringLatin1 类被JIT编译后,也会出现同样的报错:
可以使用如下命令,/home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java -XX:CompileCommand=exclude,"java/lang/StringLatin1.*" -XX:CompileCommand=exclude,"java/lang/String.*" -XX:+LogCompilation -XX:LogFile=compile.log
将类java/lang/StringLatin1
, java/lang/String
屏蔽JIT编译,会继续向前推进一步:
通过脚本重复执行“./java -version”命令,将生成log总结到一起发现:
Error occurred during initialization of boot layer
java.lang.module.FindException: Error reading module: /home/zhangxiang/rv32/jdk11u/build/linux-riscv32-normal-custom-slowdebug/jdk/modules/jdk.scripting.nashorn
Caused by: java.lang.module.InvalidModuleDescriptorException: Package jdk.nashorn.api.scripting not found in module
以及
Dumping core ...
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/iterator.inline.hpp:60
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/zhangxiang/rv32/jdk11u/src/hotspot/share/memory/iterator.inline.hpp:60), pid=1246259, tid=1246294
# assert(Universe::heap()->is_in_closed_subset(o)) failed: should be in closed *p 0x2e64ab64 0xbaadbabe
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.zhangxiang.jdk11u)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.zhangxiang.jdk11u, mixed mode, serial gc, linux-riscv32)
# 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/zhangxiang/rv32/jdk11u/hs_err_pid1246259.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
两种报错都会产生。所以目前的报错结果不稳定。
在 https://github.com/openjdk-riscv/jdk11u/commit/5f22cb8c12a3bb4ff5c6ea40fc65fdfe0eae3ac2 的基础上,同时加上以下两个patch: https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1166691134 https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1160522308
执行100次下列命令:
/home/dingli/qemu-5.2.0-rv32/bin/qemu-riscv32 -L /opt/riscv32/sysroot /home/dingli/jdk11u-jit/build/linux-riscv32-normal-custom-slowdebug/jdk/bin/java -XX:CompileCommand=exclude,"java/lang/StringLatin1.*" -XX:CompileCommand=exclude,"java/lang/String.*" -XX:+LogCompilation -XX:LogFile=compile.log >> log_100.log 2>&1
会出现两种情况:
CompileCommand: exclude java/lang/StringLatin1.*
CompileCommand: exclude java/lang/String.*
Warning: TraceDependencies results may be inflated by VerifyDependencies
#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x3b893a1c, pid=881672, tid=881678
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.dingli.jdk11u-jit)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.dingli.jdk11u-jit, mixed mode, serial gc, linux-riscv32)
# Problematic frame:
# j jdk.internal.module.ModulePath.toPackageName(Ljava/nio/file/Path;)Ljava/util/Optional;+44 java.base
#
# 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/dingli/jdk11u-jit/hs_err_pid881672.log
Loaded disassembler from /home/dingli/jdk11u-jit/build/linux-riscv32-normal-custom-slowdebug/jdk/lib/server/hsdis-riscv32.so
BFD: unrecognized disassembler option:
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 881678
Dumping core ...
CompileCommand: exclude java/lang/StringLatin1.*
CompileCommand: exclude java/lang/String.*
Warning: TraceDependencies results may be inflated by VerifyDependencies
# To suppress the following error report, specify this argument
# after -XX: or in .hotspotrc: SuppressErrorAt=/riscv32.ad:1137
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (/home/dingli/jdk11u-jit/src/hotspot/cpu/riscv32/riscv32.ad:1137), pid=922692, tid=926513
# assert((src_lo & 1) == 0 && src_lo + 1 == src_hi && (dst_lo & 1) == 0 && dst_lo + 1 == dst_hi) failed: expected aligned-adjacent pairs
#
# JRE version: OpenJDK Runtime Environment (11.0.9) (slowdebug build 11.0.9-internal+0-adhoc.dingli.jdk11u-jit)
# Java VM: OpenJDK Server VM (slowdebug 11.0.9-internal+0-adhoc.dingli.jdk11u-jit, mixed mode, serial gc, linux-riscv32)
# 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/dingli/jdk11u-jit/hs_err_pid922692.log
[thread 922922 also had an error]
#
# Compiler replay data is saved as:
# /home/dingli/jdk11u-jit/replay_pid922692.log
#
# If you would like to submit a bug report, please visit:
# https://bugreport.java.com/bugreport/crash.jsp
#
Current thread is 926513
Dumping core ...
但是在之后的多次测试中,结果都为上述第一种报错。
bishengJDK java.lang.StringLatin1 hashCode
JIT日志,通过类似如下参数打印:/home/zifeihan/qemu64/bin/qemu-riscv64 -L /opt/riscv64/sysroot ./java -XX:-UseCompressedOops -XX:+PrintOptoAssembly -XX:+LogCompilation -XX:LogFile=compile.log
<opto_assembly compile_id='11'>
{method}
- this oop: 0x00000047fabb0800
- method holder: 'java/lang/StringLatin1'
- constants: 0x00000047fabae8f0 constant pool [314] {0x00000047fabae8f0} for 'java/lang/StringLatin1' cache=0x00000047fabb2d20
- access: 0xc1000009 public static
- name: 'hashCode'
- signature: '([B)I'
- max stack: 4
- max locals: 6
- size of params: 1
- method size: 12
- vtable index: -2
- i2i entry: 0x000000400b1038c0
- adapters: AHE@0x000000400437bfa0: 0xb0000000 i2c: 0x000000400b1c5480 c2i: 0x000000400b1c54b8 c2iUV: 0x000000400b1c5490
- compiled entry 0x000000400b1c54b8
- code size: 42
- code start: 0x00000047fabb07a0
- code end (excl): 0x00000047fabb07ca
- method data: 0x00000047fadc3228
- checked ex length: 0
- linenumber start: 0x00000047fabb07ca
- localvar length: 3
- localvar start: 0x00000047fabb07da
#
# int ( byte[int:>=0]:exact * )
#
#r012 c_rarg1:c_rarg1 : parm 0: byte[int:>=0]:exact *
# -- Old sp -- Framesize: 48 --
#r135 sp+44: in_preserve
#r134 sp+40: return address
#r133 sp+36: in_preserve
#r132 sp+32: saved fp register
#r131 sp+28: pad2, stack alignment
#r130 sp+24: pad2, stack alignment
#r129 sp+20: Fixed slot 1
#r128 sp+16: Fixed slot 0
#r139 sp+12: spill
#r138 sp+ 8: spill
#r137 sp+ 4: spill
#r136 sp+ 0: spill
#
abababab N1: # B1 <- B15 B14 B12 Freq: 1
abababab
000 B1: # B15 B2 <- BLOCK HEAD IS JUNK Freq: 1
000 # stack bang size=48
sd fp, [sp, #-16]sd lr, [sp, #-8]sub sp, sp, #48
01c spill R11 -> R7 # spill size = 64
020 lwu R8, [R11, #16] # range, #@loadRange
024 NullCheck R11
024
024 B2: # B13 B3 <- B1 Freq: 0.999999
024 + ble R8, zr, B13 #@cmpUEqNeLeGt_reg_imm0_branch P=0.044228 C=6783.000000
024
028 B3: # B14 B4 <- B2 Freq: 0.955771
028 + addiw R29, R8, #-1 #@addI_reg_imm
02c + bgeu R29, R8, B14 #@cmpU_branch P=0.000001 C=-1.000000
02c
030 B4: # B9 B5 <- B3 Freq: 0.95577
030 + li R28, #-2147483648 # int, #@loadConI
034 + addiw R12, R8, #-7 #@addI_reg_imm
038 + cmplt op1, op2 #@cmpI
mv_t R12, R28 #@cmovI
040 + li R13, #1 # int, #@loadConI
044 + lbu R10, [R11, #24] # byte, #@loadUB
048 + ble R12, R13, B9 #@cmpI_branch P=0.000001 C=-1.000000
048
04c B5: # B6 <- B4 Freq: 0.955769
04c + slliw R28, R10, (#5 & 0x1f) #@lShiftI_reg_imm
050 + subw R29, R28, R10 #@subI_reg_reg
054 + li R11, #8000 # int, #@loadConI
05c + -- // R23=Thread::current(), empty, #@tlsLoadP
05c
05c B6: # B7 <- B5 B8 Loop: B6-B8 Freq: 21.6099
05c subw R28, R12, R13 #@subI_reg_reg
060 + ble R28, R11, Lsrc1. #@minI_rReg
mv R30, R11
j Ldone
bind Lsrc1
mv R30, R28
bind #@minI_rReg
070 + addw R14, R30, R13 #@addI_reg_reg
nop # 3 bytes pad for loops and calls
080 B7: # B7 B8 <- B6 B7 Loop: B7-B7 inner main of N58 strip mined Freq: 488.601
080 + addw R28, R13 #@convI2L_reg_reg
084 + add R10, R7, R28 # ptr, #@addP_reg_reg
088 + lbu R28, [R10, #24] # byte, #@loadUB
08c + addw R28, R29, R28 #@addI_reg_reg
090 + lbu R31, [R10, #25] # byte, #@loadUB
094 + slliw R30, R28, (#5 & 0x1f) #@lShiftI_reg_imm
098 + subw R28, R30, R28 #@subI_reg_reg
09c + addw R28, R28, R31 #@addI_reg_reg
0a0 + lbu R30, [R10, #26] # byte, #@loadUB
0a4 + slliw R31, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0a8 + subw R28, R31, R28 #@subI_reg_reg
0ac + addw R28, R28, R30 #@addI_reg_reg
0b0 + lbu R31, [R10, #27] # byte, #@loadUB
0b4 + slliw R29, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0b8 + subw R29, R29, R28 #@subI_reg_reg
0bc + addw R28, R29, R31 #@addI_reg_reg
0c0 + lbu R30, [R10, #28] # byte, #@loadUB
0c4 + slliw R31, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0c8 + subw R28, R31, R28 #@subI_reg_reg
0cc + addw R28, R28, R30 #@addI_reg_reg
0d0 + lbu R31, [R10, #29] # byte, #@loadUB
0d4 + slliw R30, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0d8 + subw R28, R30, R28 #@subI_reg_reg
0dc + addw R28, R28, R31 #@addI_reg_reg
0e0 + lbu R30, [R10, #30] # byte, #@loadUB
0e4 + slliw R31, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0e8 + subw R28, R31, R28 #@subI_reg_reg
0ec + addw R28, R28, R30 #@addI_reg_reg
0f0 + lbu R31, [R10, #31] # byte, #@loadUB
0f4 + slliw R30, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0f8 + subw R28, R30, R28 #@subI_reg_reg
0fc + addw R10, R28, R31 #@addI_reg_reg
100 + slliw R29, R10, (#5 & 0x1f) #@lShiftI_reg_imm
104 + addiw R13, R13, #8 #@addI_reg_imm
108 + subw R29, R29, R10 #@subI_reg_reg
10c + blt R13, R14, B7 #@cmpI_loop P=0.955772 C=6483.000000
10c
110 B8: # B6 B9 <- B7 Freq: 21.6099
110 + ld R28, [R23, #288] # ptr, #@loadP
114 + lwu zr, [R28] # Safepoint: poll for GC, #@safePoint # java.lang.StringLatin1::hashCode @ bci:37 L[0]=_ L[1]=R10 L[2]=R7 L[3]=R8 L[4]=R13 L[5]=_
# OopMap{x7=Oop off=276}
118 + blt R13, R12, B6 #@cmpI_branch P=0.955772 C=6483.000000
118
11c B9: # B12 B10 <- B4 B8 Freq: 0.95577
11c + bge R13, R8, B12 #@cmpI_branch P=0.500000 C=-1.000000
11c
120 B10: # B11 <- B9 Freq: 0.477885
120 + # castII of R13, #@castII
120
120 B11: # B11 B12 <- B10 B11 Loop: B11-B11 inner post of N167 Freq: 0.95577
120 addw R28, R13 #@convI2L_reg_reg
124 + add R28, R7, R28 # ptr, #@addP_reg_reg
128 + slliw R30, R10, (#5 & 0x1f) #@lShiftI_reg_imm
12c + lbu R28, [R28, #24] # byte, #@loadUB
130 + subw R29, R30, R10 #@subI_reg_reg
134 + addiw R13, R13, #1 #@addI_reg_imm
138 + addw R10, R29, R28 #@addI_reg_reg
13c + blt R13, R8, B11 #@cmpI_loop P=0.500000 C=6483.000000
13c
140 B12: # N1 <- B11 B9 B13 Freq: 0.999998
140 # pop frame 48
add sp, sp, #48
ld lr, [sp,#-16]
ld fp, [sp,#-8]
# touch polling page
li t0, #0x400b044000
ld zr, [t0]
154 + ret // return register, #@Ret
154
158 B13: # B12 <- B2 Freq: 0.0442282
158 + li R10, #0 # int, #@loadConI
15c + j B12 #@branch
15c
160 B14: # N1 <- B3 Freq: 9.68462e-07
160 + li R11, #-130 # int, #@loadConI
164 spill R7 -> [sp, #0] # spill size = 64
168 CALL,static 0x000000400b133a40 #@CallStaticJavaDirect wrapper for: uncommon_trap(reason='predicate' action='maybe_recompile')
# java.lang.StringLatin1::hashCode @ bci:13 L[0]=_ L[1]=#0 L[2]=sp + #0 L[3]=R8 L[4]=#0 L[5]=_ STK[0]=#0 STK[1]=R8
# OopMap{[0]=Oop off=364}
16c #@ShouldNotReachHere
16c
170 B15: # N1 <- B1 Freq: 1.01328e-06
170 + li R11, #-10 # int, #@loadConI
174 CALL,static 0x000000400b133a40 #@CallStaticJavaDirect wrapper for: uncommon_trap(reason='null_check' action='maybe_recompile')
# java.lang.StringLatin1::hashCode @ bci:5 L[0]=_ L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ STK[0]=#NULL
# OopMap{off=376}
178 #@ShouldNotReachHere
178
</opto_assembly>
OpenJDK for RV32G java.lang.StringLatin1 hashCode
JIT日志,通过类似如下参数打印:/home/zifeihan/qemu32/bin/qemu-riscv32 -L /opt/riscv32/sysroot ./java -XX:+PrintOptoAssembly -XX:+LogCompilation -XX:LogFile=compile.log
<opto_assembly compile_id='13'>
{method}
- this oop: 0x2ddae070
- method holder: 'java/lang/StringLatin1'
- constants: 0x2ddacb30 constant pool [314] {0x2ddacb30} for 'java/lang/StringLatin1' cache=0x2ddaff48
- access: 0xc1000009 public static
- name: 'hashCode'
- signature: '([B)I'
- max stack: 4
- max locals: 6
- size of params: 1
- method size: 14
- vtable index: -2
- i2i entry: 0x3b87f100
- adapters: AHE@0x3e9ae8a0: 0xa0000000 i2c: 0x3b92cb40 c2i: 0x3b92cb78 c2iUV: 0x3b92cb50
- compiled entry 0x3b92cb78
- code size: 42
- code start: 0x2ddae010
- code end (excl): 0x2ddae03a
- method data: 0x2df20468
- checked ex length: 0
- linenumber start: 0x2ddae03a
- localvar length: 3
- localvar start: 0x2ddae046
#
# int ( byte[int:>=0]:exact * )
#
#r006 c_rarg1 : parm 0: byte[int:>=0]:exact *
# -- Old sp -- Framesize: 32 --
#r131 sp+28: return address
#r130 sp+24: saved fp register
#r129 sp+20: pad2, stack alignment
#r128 sp+16: Fixed slot 0
#r135 sp+12: spill
#r134 sp+ 8: spill
#r133 sp+ 4: spill
#r132 sp+ 0: spill
#
abababab N1: # B1 <- B14 B13 B11 Freq: 1
abababab
000 B1: # B14 B2 <- BLOCK HEAD IS JUNK Freq: 1
000 # stack bang size=32
sw fp, [sp, #-8]sw lr, [sp, #-4]sub sp, sp, #32
020 spill R11 -> R7 # spill size = 32
024 lw R8, [R11, #8] # range, #@loadRange
028 NullCheck R11
028
028 B2: # B12 B3 <- B1 Freq: 0.999999
028 + ble R8, zr, B12 #@cmpUEqNeLeGt_reg_imm0_branch P=0.042304 C=8628.000000
028
02c B3: # B13 B4 <- B2 Freq: 0.957695
02c + addi R28, R8, #-1 #@addI_reg_imm
030 + bgeu R28, R8, B13 #@cmpU_branch P=0.000001 C=-1.000000
030
034 B4: # B8 B5 <- B3 Freq: 0.957694
034 + li R30, #-2147483648 # int, #@loadConI
03c + addi R11, R8, #-15 #@addI_reg_imm
040 + cmplt op1, op2 #@cmpI
mv_t R11, R30 #@cmovI
048 + li R31, #1 # int, #@loadConI
050 + lbu R10, [R7, #12] # byte, #@loadUB
054 + ble R11, R31, B8 #@cmpI_branch P=0.000001 C=-1.000000
054
058 B5: # B7 <- B4 Freq: 0.957693
058 + slli R29, R10, (#5 & 0x1f) #@lShiftI_reg_imm
05c + sub R28, R29, R10 #@subI_reg_reg
060 + j B7 #@branch
nop # 3 bytes pad for loops and calls
070 B6: # B7 <- B7 top-of-loop Freq: 21.6806
070 + slli R29, R10, (#5 & 0x1f) #@lShiftI_reg_imm
074 + sub R28, R29, R10 #@subI_reg_reg
074
078 B7: # B6 B8 <- B5 B6 Loop: B7-B6 inner main of N50 Freq: 22.6383
078 + add R12, R7, R31 # ptr, #@addP_reg_reg
07c + lbu R30, [R12, #12] # byte, #@loadUB
080 + add R30, R28, R30 #@addI_reg_reg
084 + slli R28, R30, (#5 & 0x1f) #@lShiftI_reg_imm
088 + lbu R29, [R12, #13] # byte, #@loadUB
08c + sub R30, R28, R30 #@subI_reg_reg
090 + add R30, R30, R29 #@addI_reg_reg
094 + slli R29, R30, (#5 & 0x1f) #@lShiftI_reg_imm
098 + lbu R28, [R12, #14] # byte, #@loadUB
09c + sub R30, R29, R30 #@subI_reg_reg
0a0 + add R30, R30, R28 #@addI_reg_reg
0a4 + slli R28, R30, (#5 & 0x1f) #@lShiftI_reg_imm
0a8 + lbu R29, [R12, #15] # byte, #@loadUB
0ac + sub R30, R28, R30 #@subI_reg_reg
0b0 + add R30, R30, R29 #@addI_reg_reg
0b4 + slli R29, R30, (#5 & 0x1f) #@lShiftI_reg_imm
0b8 + lbu R28, [R12, #16] # byte, #@loadUB
0bc + sub R30, R29, R30 #@subI_reg_reg
0c0 + add R28, R30, R28 #@addI_reg_reg
0c4 + slli R10, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0c8 + lbu R29, [R12, #17] # byte, #@loadUB
0cc + sub R28, R10, R28 #@subI_reg_reg
0d0 + add R28, R28, R29 #@addI_reg_reg
0d4 + slli R30, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0d8 + lbu R10, [R12, #18] # byte, #@loadUB
0dc + sub R28, R30, R28 #@subI_reg_reg
0e0 + add R28, R28, R10 #@addI_reg_reg
0e4 + slli R10, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0e8 + lbu R30, [R12, #19] # byte, #@loadUB
0ec + sub R28, R10, R28 #@subI_reg_reg
0f0 + add R28, R28, R30 #@addI_reg_reg
0f4 + slli R30, R28, (#5 & 0x1f) #@lShiftI_reg_imm
0f8 + lbu R10, [R12, #20] # byte, #@loadUB
0fc + sub R28, R30, R28 #@subI_reg_reg
100 + add R28, R28, R10 #@addI_reg_reg
104 + lbu R30, [R12, #21] # byte, #@loadUB
108 + slli R10, R28, (#5 & 0x1f) #@lShiftI_reg_imm
10c + sub R28, R10, R28 #@subI_reg_reg
110 + add R28, R28, R30 #@addI_reg_reg
114 + lbu R10, [R12, #22] # byte, #@loadUB
118 + slli R30, R28, (#5 & 0x1f) #@lShiftI_reg_imm
11c + sub R28, R30, R28 #@subI_reg_reg
120 + add R28, R28, R10 #@addI_reg_reg
124 + lbu R30, [R12, #23] # byte, #@loadUB
128 + slli R10, R28, (#5 & 0x1f) #@lShiftI_reg_imm
12c + sub R28, R10, R28 #@subI_reg_reg
130 + add R28, R28, R30 #@addI_reg_reg
134 + lbu R10, [R12, #24] # byte, #@loadUB
138 + slli R30, R28, (#5 & 0x1f) #@lShiftI_reg_imm
13c + sub R28, R30, R28 #@subI_reg_reg
140 + add R28, R28, R10 #@addI_reg_reg
144 + lbu R30, [R12, #25] # byte, #@loadUB
148 + slli R10, R28, (#5 & 0x1f) #@lShiftI_reg_imm
14c + sub R28, R10, R28 #@subI_reg_reg
150 + add R28, R28, R30 #@addI_reg_reg
154 + lbu R10, [R12, #26] # byte, #@loadUB
158 + slli R30, R28, (#5 & 0x1f) #@lShiftI_reg_imm
15c + sub R28, R30, R28 #@subI_reg_reg
160 + add R28, R28, R10 #@addI_reg_reg
164 + slli R10, R28, (#5 & 0x1f) #@lShiftI_reg_imm
168 + lbu R30, [R12, #27] # byte, #@loadUB
16c + sub R28, R10, R28 #@subI_reg_reg
170 + addi R31, R31, #16 #@addI_reg_imm
174 + add R10, R28, R30 #@addI_reg_reg
178 + blt R31, R11, B6 #@cmpI_loop P=0.957696 C=8263.000000
178
17c B8: # B11 B9 <- B4 B7 Freq: 0.957694
17c + bge R31, R8, B11 #@cmpI_branch P=0.500000 C=-1.000000
17c
180 B9: # B10 <- B8 Freq: 0.478847
180 + # castII of R31, #@castII
180
180 B10: # B10 B11 <- B9 B10 Loop: B10-B10 inner post of N161 Freq: 0.957694
180 add R28, R7, R31 # ptr, #@addP_reg_reg
184 + lbu R29, [R28, #12] # byte, #@loadUB
188 + slli R28, R10, (#5 & 0x1f) #@lShiftI_reg_imm
18c + sub R30, R28, R10 #@subI_reg_reg
190 + addi R31, R31, #1 #@addI_reg_imm
194 + add R10, R30, R29 #@addI_reg_reg
198 + blt R31, R8, B10 #@cmpI_loop P=0.500000 C=8263.000000
198
19c B11: # N1 <- B10 B8 B12 Freq: 0.999998
19c # pop frame 32
add sp, sp, #32
lw lr, [sp,#-8]
lw fp, [sp,#-4]
# touch polling page
li t0, #0x3e829000
lw zr, [t0]
1b0 + ret // return register, #@Ret
1b0
1b4 B12: # B11 <- B2 Freq: 0.0423041
1b4 + li R10, #0 # int, #@loadConI
1bc + j B11 #@branch
1bc
1c0 B13: # N1 <- B3 Freq: 9.70412e-07
1c0 + li R11, #-130 # int, #@loadConI
1c8 spill R7 -> [sp, #0] # spill size = 32
1cc CALL,static 0x3b8a8d40 #@CallStaticJavaDirect wrapper for: uncommon_trap(reason='predicate' action='maybe_recompile')
# java.lang.StringLatin1::hashCode @ bci:13 L[0]=_ L[1]=#0 L[2]=sp + #0 L[3]=R8 L[4]=#0 L[5]=_ STK[0]=#0 STK[1]=R8
# OopMap{[0]=Oop off=464}
1d0 #@ShouldNotReachHere
1d0
1d4 B14: # N1 <- B1 Freq: 1.01328e-06
1d4 + li R11, #-10 # int, #@loadConI
1dc CALL,static 0x3b8a8d40 #@CallStaticJavaDirect wrapper for: uncommon_trap(reason='null_check' action='maybe_recompile')
# java.lang.StringLatin1::hashCode @ bci:5 L[0]=_ L[1]=_ L[2]=_ L[3]=_ L[4]=_ L[5]=_ STK[0]=#NULL
# OopMap{off=480}
1e0 #@ShouldNotReachHere
1e0
</opto_assembly>
关于在bishengJDK下会生成了一个关于Long类型操作的节点 convI2L_reg_reg
因为这个节点并没有做做64位的兼容操作,尝试修复如下:
zifeihan@k9-plct:~/jdk11u$ git diff
diff --git a/src/hotspot/cpu/riscv32/riscv32.ad b/src/hotspot/cpu/riscv32/riscv32.ad
index 0d6f5ebfa3..19de4c2364 100644
--- a/src/hotspot/cpu/riscv32/riscv32.ad
+++ b/src/hotspot/cpu/riscv32/riscv32.ad
@@ -7353,9 +7353,11 @@ instruct convI2L_reg_reg(iRegLNoSp dst, iRegIorL2I src)
match(Set dst (ConvI2L src));
ins_cost(ALU_COST);
- format %{ "add $dst, $src\t#@convI2L_reg_reg" %}
+ format %{ "mv $dst.lo, $src\t# \n\t"
+ "srai $dst.hi, $dst.lo, 0x1f\t# #@convI2L_reg_reg" %}
ins_encode %{
- __ add(as_Register($dst$$reg), as_Register($src$$reg), zr);
+ __ mv(as_Register($dst$$reg), as_Register($src$$reg));
+ __ srai(as_Register($dst$$reg)->successor(), as_Register($dst$$reg), 0x1f);
%}
ins_pipe(ialu_reg);
%}
修复后OpenJDK for RV32G使用 -XX:+PrintOptoAssembly 打印编译日志,但是 java.lang.StringLatin1 hashCode
方法中依然没有convI2L_reg_reg
节点,但是别的方法中的convI2L_reg_reg
的汇编生成逻辑被修改了
然后通过 -XX:+PrintAssembly 打印最终执行时的汇编,发现最终汇编如下:
FYI:参考 https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1180611255 中的方法对新版本https://github.com/openjdk-riscv/jdk11u/commit/84b6b047bb0da023780587b748f85052d22eaa82 进行了打印,发现与旧版本 https://github.com/openjdk-riscv/jdk11u/commit/8ecab9f0bfda037e081a424af9f2e1537f94ecce 相比编译的方法减少了:
但是在又尝试了几次之后,新版本https://github.com/openjdk-riscv/jdk11u/commit/84b6b047bb0da023780587b748f85052d22eaa82 的编译方法的最大id也变为了55,目前还在分析出现差异的原因,以及减少是否是偶发性的情况。
FYI:参考 #388 (comment) 中的方法对新版本84b6b04 进行了打印,发现与旧版本 8ecab9f 相比编译的方法减少了:
这种 task_queued 标签的方法,是还在编译队列中,并不一定是成功编译的,这里对比的话,可能需要参考 nmethod 标签的内容,这种才是已经编译成功的方法,也标识了编译后的汇编代码的起始位置。
已提交PR:https://github.com/openjdk-riscv/jdk11u/pull/433 ,用来修复 convI2L_reg_reg 对Long类型的处理。对当前结果无影响,PR验证参考:https://github.com/openjdk-riscv/jdk11u/issues/388#issuecomment-1180611255
C2调试的主issue https://github.com/openjdk-riscv/jdk11u/issues/342 比较长,目前的问题可能需要深入分析,因此新开一个issue进行记录。 目前的报错:
是由于在循环中没有使 svec->valid(x) 函数成立的index。
svec->valid(x)会在build目录下的ad_riscv32.hpp进行定义:
这里的 _valid 是类State的一个public数组,存储了 _LAST_MACH_OPER 个oprand的vaild值(0/1,用int以字节形式对vaild值进行保存,因此会以32个为一组):
而_LAST_MACH_OPER是由riscv32.ad文件中对应的operand所生成的,所以接下来要看看 _valid数组是在哪里赋值的。
通过查看源代码,发现其与DFA相关。这里的src/hotspot/share/adlc/dfa.cpp为了生成 DFA,会遍历 ADLC 前端生成的理想操作码/匹配列表,以构建case语句(一系列 if 语句)的内容,来匹配ad文件中的理想操作码。
在类State中包含一个成员函数
DFA
:在 build/linux-riscv32-normal-custom-slowdebug/hotspot/variant-custom/support/adlc/dfa_riscv32.cpp 中会对opcode进行匹配,然后调用DFA_PRODUCTION__SET_VALID等宏,从而将类State中的 _valid 数组进行赋值:
接下来需要结合当前的报错信息,分析State中opcode没有匹配上的原因。