[C2] Add patchable_call for MIPS.

Sun, 19 Mar 2017 17:04:32 -0400

author
fujie
date
Sun, 19 Mar 2017 17:04:32 -0400
changeset 381
5ed96f1a7d5a
parent 380
5d24e411bbe2
child 382
a0d5defa38f5

[C2] Add patchable_call for MIPS.

src/cpu/mips/vm/assembler_mips.cpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/assembler_mips.hpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/mips_64.ad file | annotate | diff | comparison | revisions
     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      }

mercurial