Wed, 07 Feb 2018 13:00:31 +0800
#6578 On MIPS, add the end of the previous instruction to the implicit exception table when the node is a null check
Reviewed-by: fujie
Summary: the last instruction of the previous node (usually a instruction sequence) is the instruction which access memory on MIPS.
For example:
StoreB
NullCheck
=>
daddiu at,zero,1 ;wrong implicit exception dispatch position
sb at,18(s3) ;right implicit exception dispatch position
1.1 --- a/src/cpu/mips/vm/mips_64.ad Wed Feb 07 15:44:45 2018 +0800 1.2 +++ b/src/cpu/mips/vm/mips_64.ad Wed Feb 07 13:00:31 2018 +0800 1.3 @@ -2927,9 +2927,6 @@ 1.4 int disp = $mem$$disp; 1.5 Register dst_reg = as_Register($dst$$reg); 1.6 1.7 - // For implicit null check 1.8 - __ lb(AT, as_Register(base), 0); 1.9 - 1.10 if( index != 0 ) { 1.11 if (scale == 0) { 1.12 __ daddu(AT, as_Register(base), as_Register(index)); 1.13 @@ -2996,9 +2993,6 @@ 1.14 int disp = $mem$$disp; 1.15 1.16 if( index != 0 ) { 1.17 - // For implicit null check 1.18 - __ lb(AT, as_Register(base), 0); 1.19 - 1.20 if (scale == 0) { 1.21 __ daddu(AT, as_Register(base), as_Register(index)); 1.22 } else {
2.1 --- a/src/cpu/mips/vm/nativeInst_mips.hpp Wed Feb 07 15:44:45 2018 +0800 2.2 +++ b/src/cpu/mips/vm/nativeInst_mips.hpp Wed Feb 07 13:00:31 2018 +0800 2.3 @@ -56,10 +56,12 @@ 2.4 public: 2.5 enum mips_specific_constants { 2.6 nop_instruction_code = 0, 2.7 - nop_instruction_size = 4 2.8 + nop_instruction_size = 4, 2.9 + sync_instruction_code = 0xf 2.10 }; 2.11 2.12 bool is_nop() { return long_at(0) == nop_instruction_code; } 2.13 + bool is_sync() { return long_at(0) == sync_instruction_code; } 2.14 bool is_dtrace_trap(); 2.15 inline bool is_call(); 2.16 inline bool is_illegal();
3.1 --- a/src/share/vm/opto/output.cpp Wed Feb 07 15:44:45 2018 +0800 3.2 +++ b/src/share/vm/opto/output.cpp Wed Feb 07 13:00:31 2018 +0800 3.3 @@ -1530,6 +1530,29 @@ 3.4 DEBUG_ONLY( uint instr_offset = cb->insts_size(); ) 3.5 n->emit(*cb, _regalloc); 3.6 current_offset = cb->insts_size(); 3.7 +#ifdef MIPS64 3.8 + if (!n->is_Proj()) { 3.9 + // For MIPS, the first instruction of the previous node (usually a instruction sequence) sometime 3.10 + // is not the instruction which access memory. adjust is needed. previous_offset points to the 3.11 + // instruction which access memory. Instruction size is 4. cb->insts_size() and 3.12 + // cb->insts()->end() are the location of current instruction. 3.13 + int adjust = 4; 3.14 + NativeInstruction* inst = (NativeInstruction*) (cb->insts()->end() - 4); 3.15 + if (inst->is_sync()) { 3.16 + // a sync may be the last instruction, see store_B_immI_enc_sync 3.17 + adjust += 4; 3.18 + inst = (NativeInstruction*) (cb->insts()->end() - 8); 3.19 + } 3.20 + if (PatchContinuousLoad) { 3.21 + // if PatchContinuousLoad is true, a nop may be inserted after a load instruction and 3.22 + // the adjust would be 2 instructions. 3.23 + if (inst->is_nop()) { 3.24 + adjust += 4; 3.25 + } 3.26 + } 3.27 + previous_offset = current_offset - adjust; 3.28 + } 3.29 +#endif 3.30 3.31 #ifdef ASSERT 3.32 if (n->size(_regalloc) < (current_offset-instr_offset)) {