Sun, 19 Mar 2017 17:04:32 -0400
[C2] Add patchable_call for MIPS.
1.1 --- a/src/cpu/mips/vm/assembler_mips.cpp Sat Mar 18 07:08:36 2017 +0800 1.2 +++ b/src/cpu/mips/vm/assembler_mips.cpp Sun Mar 19 17:04:32 2017 -0400 1.3 @@ -521,45 +521,79 @@ 1.4 has_delay_slot(); 1.5 } 1.6 1.7 -void MacroAssembler::general_j(address entry) { 1.8 -#ifdef _LP64 1.9 - int dest = ((intptr_t)entry - (((intptr_t)pc() + 4) & 0xfffffffff0000000))>>2; 1.10 -#else 1.11 - int dest = ((intptr_t)entry - (((intptr_t)pc() + 4) & 0xf0000000))>>2; 1.12 -#endif 1.13 - if ((dest >= 0) && (dest < (1<<26))) { 1.14 - emit_long((j_op<<26) | dest); 1.15 - nop(); 1.16 - nop(); 1.17 - nop(); 1.18 - nop(); 1.19 - nop(); 1.20 - } else { 1.21 - patchable_set48(T9, (long)entry); 1.22 - jr(T9); 1.23 - nop(); 1.24 - } 1.25 - 1.26 +static inline address first_cache_address() { 1.27 + return CodeCache::low_bound() + sizeof(HeapBlock::Header); 1.28 } 1.29 1.30 -void MacroAssembler::general_jal(address entry) { 1.31 -#ifdef _LP64 1.32 - int dest = ((intptr_t)entry - (((intptr_t)pc() + 4) & 0xfffffffff0000000))>>2; 1.33 -#else 1.34 - int dest = ((intptr_t)entry - (((intptr_t)pc() + 4) & 0xf0000000))>>2; 1.35 -#endif 1.36 - if ((dest >= 0) && (dest < (1<<26))) { 1.37 - nop(); 1.38 - nop(); 1.39 - nop(); 1.40 - nop(); 1.41 - emit_long((jal_op<<26) | dest); 1.42 - nop(); 1.43 - } else { 1.44 - patchable_set48(T9, (long)entry); 1.45 - jalr(T9); 1.46 - nop(); 1.47 - } 1.48 +static inline address last_cache_address() { 1.49 + return CodeCache::high_bound() - Assembler::InstructionSize; 1.50 +} 1.51 + 1.52 +int MacroAssembler::call_size(address target, bool far, bool patchable) { 1.53 + if (patchable) return 6 << Assembler::LogInstructionSize; 1.54 + if (!far) return 2 << Assembler::LogInstructionSize; // jal + nop 1.55 + return (insts_for_set64((jlong)target) + 2) << Assembler::LogInstructionSize; 1.56 +} 1.57 + 1.58 +// Can we reach target using jal/j from anywhere 1.59 +// in the code cache (because code can be relocated)? 1.60 +bool MacroAssembler::reachable_from_cache(address target) { 1.61 + address cl = first_cache_address(); 1.62 + address ch = last_cache_address(); 1.63 + 1.64 + return fit_in_jal(target, cl) && fit_in_jal(target, ch); 1.65 +} 1.66 + 1.67 +void MacroAssembler::general_jump(address target) { 1.68 + if (reachable_from_cache(target)) { 1.69 + j(target); 1.70 + nop(); 1.71 + } else { 1.72 + set64(T9, (long)target); 1.73 + jr(T9); 1.74 + nop(); 1.75 + } 1.76 +} 1.77 + 1.78 +void MacroAssembler::patchable_jump(address target) { 1.79 + if (reachable_from_cache(target)) { 1.80 + nop(); 1.81 + nop(); 1.82 + nop(); 1.83 + nop(); 1.84 + j(target); 1.85 + nop(); 1.86 + } else { 1.87 + patchable_set48(T9, (long)target); 1.88 + jr(T9); 1.89 + nop(); 1.90 + } 1.91 +} 1.92 + 1.93 +void MacroAssembler::general_call(address target) { 1.94 + if (reachable_from_cache(target)) { 1.95 + jal(target); 1.96 + nop(); 1.97 + } else { 1.98 + set64(T9, (long)target); 1.99 + jalr(T9); 1.100 + nop(); 1.101 + } 1.102 +} 1.103 + 1.104 +void MacroAssembler::patchable_call(address target) { 1.105 + if (reachable_from_cache(target)) { 1.106 + nop(); 1.107 + nop(); 1.108 + nop(); 1.109 + nop(); 1.110 + jal(target); 1.111 + nop(); 1.112 + } else { 1.113 + patchable_set48(T9, (long)target); 1.114 + jalr(T9); 1.115 + nop(); 1.116 + } 1.117 } 1.118 1.119 void MacroAssembler::beq_far(Register rs, Register rt, address entry) 1.120 @@ -1135,7 +1169,7 @@ 1.121 assert(entry != NULL, "call most probably wrong"); 1.122 InstructionMark im(this); 1.123 relocate(rh); 1.124 - general_jal(entry); 1.125 + patchable_call(entry); 1.126 } 1.127 1.128 void MacroAssembler::c2bool(Register r) {
2.1 --- a/src/cpu/mips/vm/assembler_mips.hpp Sat Mar 18 07:08:36 2017 +0800 2.2 +++ b/src/cpu/mips/vm/assembler_mips.hpp Sun Mar 19 17:04:32 2017 -0400 2.3 @@ -365,6 +365,12 @@ 2.4 friend class StubGenerator; 2.5 2.6 public: 2.7 + 2.8 + public: 2.9 + 2.10 + static const int LogInstructionSize = 2; 2.11 + static const int InstructionSize = 1 << LogInstructionSize; 2.12 + 2.13 // opcode, highest 6 bits: bits[31...26] 2.14 enum ops { 2.15 special_op = 0x00, // special_ops 2.16 @@ -921,16 +927,14 @@ 2.17 static bool is_simm (int x, int nbits) { return -( 1 << nbits-1 ) <= x && x < ( 1 << nbits-1 ); } 2.18 static bool is_simm16(int x) { return is_simm(x, 16); } 2.19 2.20 - static bool fit_in_jal(int offset) { 2.21 - return is_simm(offset, 26); 2.22 - } 2.23 - 2.24 - 2.25 - // test if entry can be filled in the jl/jal, 2.26 - // must be used just before you emit jl/jal 2.27 - // by yjl 6/27/2005 2.28 - bool fit_int_jal(address entry) { 2.29 - return fit_in_jal(offset(entry)); 2.30 + static bool fit_in_jal(address target, address pc) { 2.31 +#ifdef _LP64 2.32 + int dst = ((intptr_t)target - (((intptr_t)pc + 4) & 0xfffffffff0000000))>>2; 2.33 +#else 2.34 + int dst = ((intptr_t)target - (((intptr_t)pc + 4) & 0xf0000000))>>2; 2.35 +#endif 2.36 + if ((dst >= 0) && (dst < (1<<26))) return true; 2.37 + else return false; 2.38 } 2.39 2.40 bool fit_int_branch(address entry) { 2.41 @@ -2457,8 +2461,15 @@ 2.42 2.43 void patchable_call32(Register d, jlong value); 2.44 2.45 - void general_j(address entry); 2.46 - void general_jal(address entry); 2.47 + static int call_size(address target, bool far, bool patchable); 2.48 + 2.49 + static bool reachable_from_cache(address target); 2.50 + 2.51 + void patchable_call(address target); 2.52 + void general_call(address target); 2.53 + 2.54 + void patchable_jump(address target); 2.55 + void general_jump(address target); 2.56 2.57 void dli(Register rd, long imm) { li(rd, imm); } 2.58 void li64(Register rd, long imm);
3.1 --- a/src/cpu/mips/vm/mips_64.ad Sat Mar 18 07:08:36 2017 +0800 3.2 +++ b/src/cpu/mips/vm/mips_64.ad Sun Mar 19 17:04:32 2017 -0400 3.3 @@ -3344,7 +3344,7 @@ 3.4 cbuf.set_insts_mark(); 3.5 __ relocate(relocInfo::runtime_call_type); 3.6 3.7 - __ general_jal((address)$meth$$method); 3.8 + __ patchable_call((address)$meth$$method); 3.9 %} 3.10 3.11 enc_class Java_Static_Call (method meth) %{ // JAVA STATIC CALL 3.12 @@ -3361,7 +3361,7 @@ 3.13 __ relocate(relocInfo::static_call_type); 3.14 } 3.15 3.16 - __ general_jal((address)($meth$$method)); 3.17 + __ patchable_call((address)($meth$$method)); 3.18 if( _method ) { // Emit stub for static call 3.19 emit_java_to_interp(cbuf); 3.20 }