[C2] Add patchable_jump for MIPS.

Tue, 28 Mar 2017 06:08:41 -0400

author
fujie
date
Tue, 28 Mar 2017 06:08:41 -0400
changeset 386
f50649f9eda6
parent 385
ee9f465c10a9
child 387
2f19d36583f4

[C2] Add patchable_jump for MIPS.

src/cpu/mips/vm/compiledIC_mips.cpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/icBuffer_mips.cpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/icache_mips.cpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/mips_64.ad file | annotate | diff | comparison | revisions
src/cpu/mips/vm/nativeInst_mips.cpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/nativeInst_mips.hpp file | annotate | diff | comparison | revisions
src/cpu/mips/vm/sharedRuntime_mips_64.cpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/mips/vm/compiledIC_mips.cpp	Wed Mar 22 11:43:05 2017 -0400
     1.2 +++ b/src/cpu/mips/vm/compiledIC_mips.cpp	Tue Mar 28 06:08:41 2017 -0400
     1.3 @@ -109,9 +109,7 @@
     1.4  
     1.5    cbuf.set_insts_mark();
     1.6    address call_pc = (address)-1;
     1.7 -  __ patchable_set48(AT, (long)call_pc);
     1.8 -  __ jr(AT);
     1.9 -  __ nop();
    1.10 +  __ patchable_jump(call_pc);
    1.11    __ align(16);
    1.12    __ end_a_stub();
    1.13    // Update current stubs pointer and restore code_end.
     2.1 --- a/src/cpu/mips/vm/icBuffer_mips.cpp	Wed Mar 22 11:43:05 2017 -0400
     2.2 +++ b/src/cpu/mips/vm/icBuffer_mips.cpp	Tue Mar 28 06:08:41 2017 -0400
     2.3 @@ -63,13 +63,13 @@
     2.4  
     2.5    __ lui(T9, Assembler::split_high((int)entry_point));
     2.6    __ addiu(T9, T9, Assembler::split_low((int)entry_point));
     2.7 +  __ jr(T9);
     2.8 +  __ delayed()->nop();
     2.9  #else
    2.10    __ patchable_set48(T1, (long)cached_value);
    2.11  
    2.12 -  __ patchable_set48(T9, (long)entry_point);
    2.13 +  __ patchable_jump(entry_point);
    2.14  #endif
    2.15 -  __ jr(T9);
    2.16 -  __ delayed()->nop();
    2.17    __ flush();
    2.18  #undef __ 
    2.19  }
     3.1 --- a/src/cpu/mips/vm/icache_mips.cpp	Wed Mar 22 11:43:05 2017 -0400
     3.2 +++ b/src/cpu/mips/vm/icache_mips.cpp	Tue Mar 28 06:08:41 2017 -0400
     3.3 @@ -40,34 +40,18 @@
     3.4  void ICacheStubGenerator::generate_icache_flush(ICache::flush_icache_stub_t* flush_icache_stub) {};
     3.5  
     3.6  void ICache::call_flush_stub(address start, int lines) {
     3.7 -	//in fact, the current os implementation simply flush all ICACHE&DCACHE
     3.8 -#ifndef CACHE_OPT
     3.9 -	/* Loongson3A supports automatic synchronization between Icache and Dcache.
    3.10 -         * No manual synchronization is needed. */
    3.11 -	cacheflush(start, lines * line_size , ICACHE);
    3.12 -#endif
    3.13 -//	sysmips(3, 0, 0, 0);
    3.14 +  cacheflush(start, lines * line_size , ICACHE);
    3.15  }
    3.16  
    3.17  void ICache::invalidate_word(address addr) {
    3.18 -	//cacheflush(addr, 4, ICACHE);
    3.19 -
    3.20 -#ifndef CACHE_OPT
    3.21 -	cacheflush(addr,4, ICACHE);
    3.22 -#endif
    3.23 -//	sysmips(3, 0, 0, 0);
    3.24 +  cacheflush(addr,4, ICACHE);
    3.25  }
    3.26  
    3.27  void ICache::invalidate_range(address start, int nbytes) {
    3.28 -#ifndef CACHE_OPT
    3.29 -	cacheflush(start, nbytes, ICACHE);
    3.30 -#endif
    3.31 -//	sysmips(3, 0, 0, 0);
    3.32 +  cacheflush(start, nbytes, ICACHE);
    3.33  }
    3.34  
    3.35  void ICache::invalidate_all() {
    3.36 -#ifndef CACHE_OPT
    3.37 -	sysmips(3, 0, 0, 0);
    3.38 -#endif
    3.39 +  sysmips(3, 0, 0, 0);
    3.40  }
    3.41  
     4.1 --- a/src/cpu/mips/vm/mips_64.ad	Wed Mar 22 11:43:05 2017 -0400
     4.2 +++ b/src/cpu/mips/vm/mips_64.ad	Tue Mar 28 06:08:41 2017 -0400
     4.3 @@ -536,18 +536,6 @@
     4.4  // Emit exception handler code.
     4.5  // Stuff framesize into a register and call a VM stub routine.
     4.6  int HandlerImpl::emit_exception_handler(CodeBuffer& cbuf) {
     4.7 -/*
     4.8 -  // Note that the code buffer's insts_mark is always relative to insts.
     4.9 -  // That's why we must use the macroassembler to generate a handler.
    4.10 -  MacroAssembler _masm(&cbuf);
    4.11 -  address base = __ start_a_stub(size_exception_handler());
    4.12 -  if (base == NULL)  return 0;  // CodeBuffer::expand failed
    4.13 -  int offset = __ offset();
    4.14 -  __ jump(RuntimeAddress(OptoRuntime::exception_blob()->entry_point()));
    4.15 -  assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
    4.16 -  __ end_a_stub();
    4.17 -  return offset;
    4.18 -*/
    4.19    // Note that the code buffer's insts_mark is always relative to insts.
    4.20    // That's why we must use the macroassembler to generate a handler.
    4.21    MacroAssembler _masm(&cbuf);
    4.22 @@ -558,24 +546,9 @@
    4.23  
    4.24    __ block_comment("; emit_exception_handler");
    4.25  
    4.26 -  /* 2012/9/25 FIXME Jin: According to X86, we should use direct jumpt.
    4.27 - *    *  However, this will trigger an assert after the 40th method:
    4.28 - *       *
    4.29 - *          *        39   b   java.lang.Throwable::<init> (25 bytes)
    4.30 - *             *       ---   ns  java.lang.Throwable::fillInStackTrace
    4.31 - *                *        40  !b   java.net.URLClassLoader::findClass (29 bytes)
    4.32 - *                   *       /vm/opto/runtime.cpp, 900 , assert(caller.is_compiled_frame(),"must be")
    4.33 - *                      *        40   made not entrant  (2)  java.net.URLClassLoader::findClass (29 bytes)
    4.34 - *                         *
    4.35 - *                            *  If we change from JR to JALR, the assert will disappear, but WebClient will
    4.36 - *                               *  fail  after the 403th method with unknown reason.
    4.37 - *                                  */
    4.38    cbuf.set_insts_mark();
    4.39    __ relocate(relocInfo::runtime_call_type);
    4.40 -
    4.41 -  __ patchable_set48(T9, (long)OptoRuntime::exception_blob()->entry_point());
    4.42 -  __ jr(T9);
    4.43 -  __ delayed()->nop();
    4.44 +  __ patchable_jump((address)OptoRuntime::exception_blob()->entry_point());
    4.45    __ align(16);
    4.46    assert(__ offset() - offset <= (int) size_exception_handler(), "overflow");
    4.47    __ end_a_stub();
    4.48 @@ -598,10 +571,7 @@
    4.49  
    4.50    cbuf.set_insts_mark();
    4.51    __ relocate(relocInfo::runtime_call_type);
    4.52 -
    4.53 -  __ patchable_set48(T9, (long)SharedRuntime::deopt_blob()->unpack());
    4.54 -  __ jalr(T9);
    4.55 -  __ delayed()->nop();
    4.56 +  __ patchable_call(SharedRuntime::deopt_blob()->unpack());
    4.57    __ align(16);
    4.58    assert(__ offset() - offset <= (int) size_deopt_handler(), "overflow");
    4.59    __ end_a_stub();
    4.60 @@ -651,13 +621,6 @@
    4.61  
    4.62    __ relocate(static_stub_Relocation::spec(mark), 0);
    4.63  
    4.64 -  /* 2012/10/29 Jin: Rmethod contains methodOop, it should be relocated for GC */
    4.65 -/*
    4.66 -  int oop_index = __ oop_recorder()->allocate_index(NULL);
    4.67 -  RelocationHolder rspec = oop_Relocation::spec(oop_index);
    4.68 -  __ relocate(rspec);
    4.69 -*/
    4.70 -
    4.71    // static stub relocation also tags the methodOop in the code-stream.
    4.72    __ patchable_set48(S3, (long)0);
    4.73    // This is recognized as unresolved by relocs/nativeInst/ic code
    4.74 @@ -666,9 +629,7 @@
    4.75  
    4.76    cbuf.set_insts_mark();
    4.77    address call_pc = (address)-1;
    4.78 -  __ patchable_set48(AT, (long)call_pc);
    4.79 -  __ jr(AT);
    4.80 -  __ nop();
    4.81 +  __ patchable_jump(call_pc);
    4.82    __ align(16);
    4.83    __ end_a_stub();
    4.84    // Update current stubs pointer and restore code_end.
    4.85 @@ -1574,9 +1535,7 @@
    4.86    __ nop();
    4.87  
    4.88    __ relocate(relocInfo::runtime_call_type);
    4.89 -  __ patchable_set48(T9, (long)SharedRuntime::get_ic_miss_stub());
    4.90 -  __ jr(T9);
    4.91 -  __ nop();
    4.92 +  __ patchable_jump((address)SharedRuntime::get_ic_miss_stub());
    4.93  
    4.94    /* WARNING these NOPs are critical so that verified entry point is properly
    4.95     *      8 bytes aligned for patching by NativeJump::patch_verified_entry() */
    4.96 @@ -5388,9 +5347,7 @@
    4.97      cbuf.relocate(cbuf.insts_mark(), runtime_call_Relocation::spec());
    4.98  
    4.99      // call OptoRuntime::rethrow_stub to get the exception handler in parent method
   4.100 -    __ patchable_set48(T9, (jlong)OptoRuntime::rethrow_stub());
   4.101 -    __ jr(T9);
   4.102 -    __ nop();
   4.103 +    __ patchable_jump((address)OptoRuntime::rethrow_stub());
   4.104    %}
   4.105    ins_pipe( pipe_jump );
   4.106  %}
     5.1 --- a/src/cpu/mips/vm/nativeInst_mips.cpp	Wed Mar 22 11:43:05 2017 -0400
     5.2 +++ b/src/cpu/mips/vm/nativeInst_mips.cpp	Tue Mar 28 06:08:41 2017 -0400
     5.3 @@ -45,7 +45,11 @@
     5.4  void NativeInstruction::set_long_at(int offset, long i) {
     5.5    address addr = addr_at(offset);
     5.6    *(long*)addr = i;
     5.7 -  //ICache::invalidate_word(addr);
     5.8 +#ifdef _LP64
     5.9 +  ICache::invalidate_range(addr, 8);
    5.10 +#else
    5.11 +  ICache::invalidate_word(addr);
    5.12 +#endif
    5.13  }
    5.14  
    5.15  static int illegal_instruction_bits = 0;
    5.16 @@ -445,12 +449,10 @@
    5.17  
    5.18  void  NativeCall::patch_on_jalr_gs(address dst) {
    5.19         patch_set48_gs(dst);
    5.20 -       ICache::invalidate_range(addr_at(0), 16);
    5.21  }
    5.22  
    5.23  void  NativeCall::patch_on_jalr(address dst) {
    5.24         patch_set48(dst);
    5.25 -       ICache::invalidate_range(addr_at(0), 16);
    5.26  }
    5.27  
    5.28  void  NativeCall::patch_set48_gs(address dest) {
    5.29 @@ -532,6 +534,8 @@
    5.30  
    5.31    atomic_store128_ptr func = get_atomic_store128_func();
    5.32    (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
    5.33 +
    5.34 +  ICache::invalidate_range(addr_at(0), 16);
    5.35  }
    5.36  
    5.37  void  NativeCall::patch_set32_gs(address dest) {
    5.38 @@ -649,6 +653,8 @@
    5.39      //nop();
    5.40      set_int_at(count << 2, 0);
    5.41    }
    5.42 +
    5.43 +  ICache::invalidate_range(addr_at(0), 16);
    5.44  }
    5.45  
    5.46  void  NativeCall::patch_set32(address dest) {
    5.47 @@ -1131,6 +1137,89 @@
    5.48           ((NativeInstruction *)this)->is_cond_jump(), "not a general jump instruction");
    5.49  }
    5.50  
    5.51 +void  NativeGeneralJump::patch_set48_gs(address dest) {
    5.52 +  jlong value = (jlong) dest;
    5.53 +  int  rt_reg = (int_at(0) & (0x1f << 16));
    5.54 +
    5.55 +  if (rt_reg == 0) rt_reg = 25 << 16; // r25 is T9 
    5.56 +
    5.57 +  int  rs_reg = rt_reg << 5;
    5.58 +  int  rd_reg = rt_reg >> 5;
    5.59 +
    5.60 +  int hi = (int)(value >> 32);
    5.61 +  int lo = (int)(value & ~0);
    5.62 +
    5.63 +  int count = 0;
    5.64 +
    5.65 +  int insts[4] = {0, 0, 0, 0};
    5.66 +
    5.67 +  if (value == lo) {  // 32-bit integer
    5.68 +    if (Assembler::is_simm16(value)) {
    5.69 +      //daddiu(d, R0, value);
    5.70 +      //set_int_at(count << 2, (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value));
    5.71 +      insts[count] = (Assembler::daddiu_op << 26) | rt_reg | Assembler::split_low(value);
    5.72 +      count += 1;
    5.73 +    } else {
    5.74 +      //lui(d, split_low(value >> 16));
    5.75 +      //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16));
    5.76 +      insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 16);
    5.77 +      count += 1;
    5.78 +      if (Assembler::split_low(value)) {
    5.79 +        //ori(d, d, split_low(value));
    5.80 +        //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
    5.81 +        insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
    5.82 +        count += 1;
    5.83 +      }
    5.84 +    }
    5.85 +  } else if (hi == 0) {  // hardware zero-extends to upper 32
    5.86 +      //ori(d, R0, julong(value) >> 16);
    5.87 +      //set_int_at(count << 2, (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16));
    5.88 +      insts[count] = (Assembler::ori_op << 26) | rt_reg | Assembler::split_low(julong(value) >> 16);
    5.89 +      count += 1;
    5.90 +      //dsll(d, d, 16);
    5.91 +      //set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
    5.92 +      insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
    5.93 +      count += 1;
    5.94 +      if (Assembler::split_low(value)) {
    5.95 +        //ori(d, d, split_low(value));
    5.96 +        //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
    5.97 +        insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
    5.98 +        count += 1;
    5.99 +      }
   5.100 +  } else if ((value> 0) && Assembler::is_simm16(value >> 32)) {
   5.101 +    //lui(d, value >> 32);
   5.102 +    //set_int_at(count << 2, (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32));
   5.103 +    insts[count] = (Assembler::lui_op << 26) | rt_reg | Assembler::split_low(value >> 32);
   5.104 +    count += 1;
   5.105 +    //ori(d, d, split_low(value >> 16));
   5.106 +    //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16));
   5.107 +    insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value >> 16);
   5.108 +    count += 1;
   5.109 +    //dsll(d, d, 16);
   5.110 +    //set_int_at(count << 2, (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6));
   5.111 +    insts[count] = (Assembler::dsll_op) | rt_reg | rd_reg | (16 << 6);
   5.112 +    count += 1;
   5.113 +    //ori(d, d, split_low(value));
   5.114 +    //set_int_at(count << 2, (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value));
   5.115 +    insts[count] = (Assembler::ori_op << 26) | rs_reg | rt_reg | Assembler::split_low(value);
   5.116 +    count += 1;
   5.117 +  } else {
   5.118 +    tty->print_cr("dest = 0x%x", value);
   5.119 +    guarantee(false, "Not supported yet !");
   5.120 +  }
   5.121 +
   5.122 +  for (count; count < 4; count++) {
   5.123 +    //nop();
   5.124 +    //set_int_at(count << 2, 0);
   5.125 +    insts[count] = 0;
   5.126 +  }
   5.127 +
   5.128 +  atomic_store128_ptr func = get_atomic_store128_func();
   5.129 +  (*func)((long *)addr_at(0), 0, *(long *)&insts[0], *(long *)&insts[2]);
   5.130 +
   5.131 +  ICache::invalidate_range(addr_at(0), 16);
   5.132 +}
   5.133 +
   5.134  void  NativeGeneralJump::patch_set48(address dest) {
   5.135    jlong value = (jlong) dest;
   5.136    int  rt_reg = (int_at(0) & (0x1f << 16));
   5.137 @@ -1191,6 +1280,38 @@
   5.138      //nop();
   5.139      set_int_at(count << 2, 0);
   5.140    }
   5.141 +
   5.142 +  ICache::invalidate_range(addr_at(0), 16);
   5.143 +}
   5.144 +
   5.145 +
   5.146 +void  NativeGeneralJump::patch_on_j_gs(address dst) {
   5.147 +#ifdef _LP64
   5.148 +        long dest = ((long)dst - (((long)addr_at(20)) & 0xfffffffff0000000))>>2;
   5.149 +#else
   5.150 +        long dest = ((long)dst - (((long)addr_at(20)) & 0xf0000000))>>2;
   5.151 +#endif
   5.152 +        if ((dest >= 0) && (dest < (1<<26))) {
   5.153 +          jint j_inst = (Assembler::j_op << 26) | dest;
   5.154 +          set_int_at(16, j_inst);
   5.155 +          ICache::invalidate_range(addr_at(16), 4);
   5.156 +        } else {
   5.157 +          ShouldNotReachHere();
   5.158 +        }
   5.159 +}
   5.160 +
   5.161 +void  NativeGeneralJump::patch_on_j(address dst) {
   5.162 +       patch_on_j_gs(dst);
   5.163 +}
   5.164 +
   5.165 +void  NativeGeneralJump::patch_on_jr_gs(address dst) {
   5.166 +       patch_set48_gs(dst);
   5.167 +       ICache::invalidate_range(addr_at(0), 16);
   5.168 +}
   5.169 +
   5.170 +void  NativeGeneralJump::patch_on_jr(address dst) {
   5.171 +       patch_set48(dst);
   5.172 +       ICache::invalidate_range(addr_at(0), 16);
   5.173  }
   5.174  
   5.175  
   5.176 @@ -1214,8 +1335,20 @@
   5.177      set_int_at(4, (int_at(4) & 0xffff0000) | (Assembler::split_low((intptr_t)dest) & 0xffff));
   5.178      ICache::invalidate_range(addr_at(0), 8);
   5.179  #else
   5.180 -  patch_set48(dest);
   5.181 -  ICache::invalidate_range(addr_at(0), 24);
   5.182 +    if (is_op(int_at(16), Assembler::j_op)) {
   5.183 +      if (UseLoongsonISA) {
   5.184 +        patch_on_j_gs(dest);
   5.185 +      } else {
   5.186 +        patch_on_j(dest);
   5.187 +      }
   5.188 +    } else if (is_special_op(int_at(16), Assembler::jr_op)) {
   5.189 +      if (UseLoongsonISA) {
   5.190 +        guarantee(!os::is_MP() || (((long)addr_at(0) % 16) == 0), "destination must be aligned for GSSD");
   5.191 +        patch_on_jr_gs(dest);
   5.192 +      } else {
   5.193 +        patch_on_jr(dest);
   5.194 +      }
   5.195 +    }
   5.196  #endif
   5.197    }
   5.198  }
   5.199 @@ -1297,6 +1430,24 @@
   5.200      return target;
   5.201    }
   5.202  
   5.203 +  // nop
   5.204 +  // nop
   5.205 +  // nop
   5.206 +  // nop 
   5.207 +  // j target
   5.208 +  // nop
   5.209 +  if ( nativeInstruction_at(addr_at(0))->is_nop() &&
   5.210 +        nativeInstruction_at(addr_at(4))->is_nop()   &&
   5.211 +        nativeInstruction_at(addr_at(8))->is_nop()   &&
   5.212 +        nativeInstruction_at(addr_at(12))->is_nop()  &&
   5.213 +        is_op(int_at(16), Assembler::j_op)         &&
   5.214 +        nativeInstruction_at(addr_at(20))->is_nop()) {
   5.215 +      int instr_index = int_at(16) & 0x3ffffff;
   5.216 +      intptr_t target_high = ((intptr_t)addr_at(20)) & 0xfffffffff0000000;
   5.217 +      intptr_t target = target_high | (instr_index << 2);
   5.218 +      return (address)target;
   5.219 +  }
   5.220 +
   5.221    // li64
   5.222    if ( is_op(Assembler::lui_op) &&
   5.223          is_op(int_at(4), Assembler::ori_op) &&
   5.224 @@ -1494,6 +1645,22 @@
   5.225      return true;
   5.226    if (is_op(int_at(12), Assembler::lui_op)) /* original b_far */
   5.227      return true;
   5.228 +
   5.229 +  // nop
   5.230 +  // nop
   5.231 +  // nop
   5.232 +  // nop
   5.233 +  // j target 
   5.234 +  // nop
   5.235 +  if ( is_nop() &&
   5.236 +         nativeInstruction_at(addr_at(4))->is_nop()  &&
   5.237 +         nativeInstruction_at(addr_at(8))->is_nop()  &&
   5.238 +         nativeInstruction_at(addr_at(12))->is_nop() &&
   5.239 +         nativeInstruction_at(addr_at(16))->is_op(Assembler::j_op) &&
   5.240 +         nativeInstruction_at(addr_at(20))->is_nop() ) {
   5.241 +      return true;
   5.242 +  }
   5.243 +
   5.244    if (is_op(int_at(0), Assembler::lui_op) &&
   5.245            is_op(int_at(4), Assembler::ori_op) &&
   5.246            is_special_op(int_at(8), Assembler::dsll_op) &&
     6.1 --- a/src/cpu/mips/vm/nativeInst_mips.hpp	Wed Mar 22 11:43:05 2017 -0400
     6.2 +++ b/src/cpu/mips/vm/nativeInst_mips.hpp	Tue Mar 28 06:08:41 2017 -0400
     6.3 @@ -433,7 +433,15 @@
     6.4    address instruction_address() const { return addr_at(instruction_offset); }
     6.5    address jump_destination();
     6.6  
     6.7 +  void  patch_set48_gs(address dest);
     6.8    void  patch_set48(address dest);
     6.9 +
    6.10 +  void  patch_on_jr_gs(address dest);
    6.11 +  void  patch_on_jr(address dest);
    6.12 +
    6.13 +  void  patch_on_j_gs(address dest);
    6.14 +  void  patch_on_j(address dest);
    6.15 +
    6.16    void  set_jump_destination(address dest);
    6.17  
    6.18  	// Creation
     7.1 --- a/src/cpu/mips/vm/sharedRuntime_mips_64.cpp	Wed Mar 22 11:43:05 2017 -0400
     7.2 +++ b/src/cpu/mips/vm/sharedRuntime_mips_64.cpp	Tue Mar 28 06:08:41 2017 -0400
     7.3 @@ -4079,9 +4079,7 @@
     7.4    __ move(A0, thread);
     7.5    // argument already in T0
     7.6    __ move(A1, T0);
     7.7 -  __ patchable_set48(T9, (long)Deoptimization::uncommon_trap);
     7.8 -  __ jalr(T9);
     7.9 -  __ delayed()->nop();
    7.10 +  __ patchable_call((address)Deoptimization::uncommon_trap);
    7.11  
    7.12    // Set an oopmap for the call site
    7.13    OopMapSet *oop_maps = new OopMapSet();
    7.14 @@ -4201,9 +4199,7 @@
    7.15    // restore return values to their stack-slots with the new SP.
    7.16    __ move(A0, thread);
    7.17    __ move(A1, Deoptimization::Unpack_uncommon_trap);
    7.18 -  __ patchable_set48(T9, (long)Deoptimization::unpack_frames);
    7.19 -  __ jalr(T9);
    7.20 -  __ delayed()->nop();
    7.21 +  __ patchable_call((address)Deoptimization::unpack_frames);
    7.22    // Set an oopmap for the call site
    7.23    //oop_maps->add_gc_map( __ offset(), true, new OopMap( framesize, 0 ) ); 
    7.24    oop_maps->add_gc_map( __ offset(),  new OopMap( framesize, 0 ) );//Fu
    7.25 @@ -4323,9 +4319,7 @@
    7.26    __ push(RA);
    7.27    //__ lui(T9, Assembler::split_high((int)StubRoutines::forward_exception_entry()));
    7.28    //__ addiu(T9, T9, Assembler::split_low((int)StubRoutines::forward_exception_entry()));
    7.29 -  __ li(T9, StubRoutines::forward_exception_entry());
    7.30 -  __ jr(T9);
    7.31 -  __ delayed()->nop();
    7.32 +  __ patchable_jump((address)StubRoutines::forward_exception_entry());
    7.33  
    7.34    // No exception case
    7.35    __ bind(noException);

mercurial