1.1 --- a/src/cpu/mips/vm/sharedRuntime_mips_64.cpp Fri Sep 01 10:28:22 2017 +0800 1.2 +++ b/src/cpu/mips/vm/sharedRuntime_mips_64.cpp Thu Sep 07 09:12:16 2017 +0800 1.3 @@ -43,126 +43,95 @@ 1.4 #endif 1.5 1.6 #define __ masm-> 1.7 + 1.8 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size; 1.9 1.10 class RegisterSaver { 1.11 - enum { FPU_regs_live = 32 }; 1.12 - // Capture info about frame layout 1.13 - enum layout { 1.14 + enum { FPU_regs_live = 32 }; 1.15 + // Capture info about frame layout 1.16 + enum layout { 1.17 #define DEF_LAYOUT_OFFS(regname) regname ## _off, regname ## H_off, 1.18 - DEF_LAYOUT_OFFS(for_16_bytes_aligned) 1.19 - DEF_LAYOUT_OFFS(fpr0) 1.20 - DEF_LAYOUT_OFFS(fpr1) 1.21 - DEF_LAYOUT_OFFS(fpr2) 1.22 - DEF_LAYOUT_OFFS(fpr3) 1.23 - DEF_LAYOUT_OFFS(fpr4) 1.24 - DEF_LAYOUT_OFFS(fpr5) 1.25 - DEF_LAYOUT_OFFS(fpr6) 1.26 - DEF_LAYOUT_OFFS(fpr7) 1.27 - DEF_LAYOUT_OFFS(fpr8) 1.28 - DEF_LAYOUT_OFFS(fpr9) 1.29 - DEF_LAYOUT_OFFS(fpr10) 1.30 - DEF_LAYOUT_OFFS(fpr11) 1.31 - DEF_LAYOUT_OFFS(fpr12) 1.32 - DEF_LAYOUT_OFFS(fpr13) 1.33 - DEF_LAYOUT_OFFS(fpr14) 1.34 - DEF_LAYOUT_OFFS(fpr15) 1.35 - DEF_LAYOUT_OFFS(fpr16) 1.36 - DEF_LAYOUT_OFFS(fpr17) 1.37 - DEF_LAYOUT_OFFS(fpr18) 1.38 - DEF_LAYOUT_OFFS(fpr19) 1.39 - DEF_LAYOUT_OFFS(fpr20) 1.40 - DEF_LAYOUT_OFFS(fpr21) 1.41 - DEF_LAYOUT_OFFS(fpr22) 1.42 - DEF_LAYOUT_OFFS(fpr23) 1.43 - DEF_LAYOUT_OFFS(fpr24) 1.44 - DEF_LAYOUT_OFFS(fpr25) 1.45 - DEF_LAYOUT_OFFS(fpr26) 1.46 - DEF_LAYOUT_OFFS(fpr27) 1.47 - DEF_LAYOUT_OFFS(fpr28) 1.48 - DEF_LAYOUT_OFFS(fpr29) 1.49 - DEF_LAYOUT_OFFS(fpr30) 1.50 - DEF_LAYOUT_OFFS(fpr31) 1.51 - 1.52 - DEF_LAYOUT_OFFS(v0) 1.53 - DEF_LAYOUT_OFFS(v1) 1.54 - DEF_LAYOUT_OFFS(a0) 1.55 - DEF_LAYOUT_OFFS(a1) 1.56 - DEF_LAYOUT_OFFS(a2) 1.57 - DEF_LAYOUT_OFFS(a3) 1.58 - DEF_LAYOUT_OFFS(a4) 1.59 - DEF_LAYOUT_OFFS(a5) 1.60 - DEF_LAYOUT_OFFS(a6) 1.61 - DEF_LAYOUT_OFFS(a7) 1.62 - DEF_LAYOUT_OFFS(t0) 1.63 - DEF_LAYOUT_OFFS(t1) 1.64 - DEF_LAYOUT_OFFS(t2) 1.65 - DEF_LAYOUT_OFFS(t3) 1.66 - DEF_LAYOUT_OFFS(s0) 1.67 - DEF_LAYOUT_OFFS(s1) 1.68 - DEF_LAYOUT_OFFS(s2) 1.69 - DEF_LAYOUT_OFFS(s3) 1.70 - DEF_LAYOUT_OFFS(s4) 1.71 - DEF_LAYOUT_OFFS(s5) 1.72 - DEF_LAYOUT_OFFS(s6) 1.73 - DEF_LAYOUT_OFFS(s7) 1.74 - DEF_LAYOUT_OFFS(t8) 1.75 - DEF_LAYOUT_OFFS(t9) 1.76 - 1.77 - DEF_LAYOUT_OFFS(gp) 1.78 - DEF_LAYOUT_OFFS(fp) 1.79 - DEF_LAYOUT_OFFS(return) 1.80 -/* 1.81 - fpr0_off, fpr1_off, 1.82 - fpr2_off, fpr3_off, 1.83 - fpr4_off, fpr5_off, 1.84 - fpr6_off, fpr7_off, 1.85 - fpr8_off, fpr9_off, 1.86 - fpr10_off, fpr11_off, 1.87 - fpr12_off, fpr13_off, 1.88 - fpr14_off, fpr15_off, 1.89 - fpr16_off, fpr17_off, 1.90 - fpr18_off, fpr19_off, 1.91 - fpr20_off, fpr21_off, 1.92 - fpr22_off, fpr23_off, 1.93 - fpr24_off, fpr25_off, 1.94 - fpr26_off, fpr27_off, 1.95 - fpr28_off, fpr29_off, 1.96 - fpr30_off, fpr31_off, 1.97 - 1.98 - v0_off, v1_off, 1.99 - a0_off, a1_off, 1.100 - a2_off, a3_off, 1.101 - a4_off, a5_off, 1.102 - a6_off, a7_off, 1.103 - t0_off, t1_off, t2_off, t3_off, 1.104 - s0_off, s1_off, s2_off, s3_off, s4_off, s5_off, s6_off, s7_off, 1.105 - t8_off, t9_off, 1.106 - 1.107 - gp_off, fp_off, 1.108 - return_off, 1.109 -*/ 1.110 - reg_save_size 1.111 - }; 1.112 + DEF_LAYOUT_OFFS(for_16_bytes_aligned) 1.113 + DEF_LAYOUT_OFFS(fpr0) 1.114 + DEF_LAYOUT_OFFS(fpr1) 1.115 + DEF_LAYOUT_OFFS(fpr2) 1.116 + DEF_LAYOUT_OFFS(fpr3) 1.117 + DEF_LAYOUT_OFFS(fpr4) 1.118 + DEF_LAYOUT_OFFS(fpr5) 1.119 + DEF_LAYOUT_OFFS(fpr6) 1.120 + DEF_LAYOUT_OFFS(fpr7) 1.121 + DEF_LAYOUT_OFFS(fpr8) 1.122 + DEF_LAYOUT_OFFS(fpr9) 1.123 + DEF_LAYOUT_OFFS(fpr10) 1.124 + DEF_LAYOUT_OFFS(fpr11) 1.125 + DEF_LAYOUT_OFFS(fpr12) 1.126 + DEF_LAYOUT_OFFS(fpr13) 1.127 + DEF_LAYOUT_OFFS(fpr14) 1.128 + DEF_LAYOUT_OFFS(fpr15) 1.129 + DEF_LAYOUT_OFFS(fpr16) 1.130 + DEF_LAYOUT_OFFS(fpr17) 1.131 + DEF_LAYOUT_OFFS(fpr18) 1.132 + DEF_LAYOUT_OFFS(fpr19) 1.133 + DEF_LAYOUT_OFFS(fpr20) 1.134 + DEF_LAYOUT_OFFS(fpr21) 1.135 + DEF_LAYOUT_OFFS(fpr22) 1.136 + DEF_LAYOUT_OFFS(fpr23) 1.137 + DEF_LAYOUT_OFFS(fpr24) 1.138 + DEF_LAYOUT_OFFS(fpr25) 1.139 + DEF_LAYOUT_OFFS(fpr26) 1.140 + DEF_LAYOUT_OFFS(fpr27) 1.141 + DEF_LAYOUT_OFFS(fpr28) 1.142 + DEF_LAYOUT_OFFS(fpr29) 1.143 + DEF_LAYOUT_OFFS(fpr30) 1.144 + DEF_LAYOUT_OFFS(fpr31) 1.145 + 1.146 + DEF_LAYOUT_OFFS(v0) 1.147 + DEF_LAYOUT_OFFS(v1) 1.148 + DEF_LAYOUT_OFFS(a0) 1.149 + DEF_LAYOUT_OFFS(a1) 1.150 + DEF_LAYOUT_OFFS(a2) 1.151 + DEF_LAYOUT_OFFS(a3) 1.152 + DEF_LAYOUT_OFFS(a4) 1.153 + DEF_LAYOUT_OFFS(a5) 1.154 + DEF_LAYOUT_OFFS(a6) 1.155 + DEF_LAYOUT_OFFS(a7) 1.156 + DEF_LAYOUT_OFFS(t0) 1.157 + DEF_LAYOUT_OFFS(t1) 1.158 + DEF_LAYOUT_OFFS(t2) 1.159 + DEF_LAYOUT_OFFS(t3) 1.160 + DEF_LAYOUT_OFFS(s0) 1.161 + DEF_LAYOUT_OFFS(s1) 1.162 + DEF_LAYOUT_OFFS(s2) 1.163 + DEF_LAYOUT_OFFS(s3) 1.164 + DEF_LAYOUT_OFFS(s4) 1.165 + DEF_LAYOUT_OFFS(s5) 1.166 + DEF_LAYOUT_OFFS(s6) 1.167 + DEF_LAYOUT_OFFS(s7) 1.168 + DEF_LAYOUT_OFFS(t8) 1.169 + DEF_LAYOUT_OFFS(t9) 1.170 + 1.171 + DEF_LAYOUT_OFFS(gp) 1.172 + DEF_LAYOUT_OFFS(fp) 1.173 + DEF_LAYOUT_OFFS(return) 1.174 + reg_save_size 1.175 + }; 1.176 1.177 public: 1.178 1.179 - static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors =false ); 1.180 - static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false); 1.181 - //FIXME, I have no idea which register to use 1.182 - static int raOffset(void) { return return_off / 2; } 1.183 - //Rmethod 1.184 - static int methodOffset(void) { return s3_off / 2; } 1.185 - 1.186 - static int v0Offset(void) { return v0_off / 2; } 1.187 - static int v1Offset(void) { return v1_off / 2; } 1.188 - 1.189 - static int fpResultOffset(void) { return fpr0_off / 2; } 1.190 - 1.191 - // During deoptimization only the result register need to be restored 1.192 - // all the other values have already been extracted. 1.193 - 1.194 - static void restore_result_registers(MacroAssembler* masm); 1.195 + static OopMap* save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors =false ); 1.196 + static void restore_live_registers(MacroAssembler* masm, bool restore_vectors = false); 1.197 + static int raOffset(void) { return return_off / 2; } 1.198 + //Rmethod 1.199 + static int methodOffset(void) { return s3_off / 2; } 1.200 + 1.201 + static int v0Offset(void) { return v0_off / 2; } 1.202 + static int v1Offset(void) { return v1_off / 2; } 1.203 + 1.204 + static int fpResultOffset(void) { return fpr0_off / 2; } 1.205 + 1.206 + // During deoptimization only the result register need to be restored 1.207 + // all the other values have already been extracted. 1.208 + static void restore_result_registers(MacroAssembler* masm); 1.209 }; 1.210 1.211 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors ) { 1.212 @@ -183,7 +152,7 @@ 1.213 int frame_size_in_words = frame_size_in_bytes / wordSize; 1.214 *total_frame_words = frame_size_in_words; 1.215 1.216 - // save registers, fpu state, and flags 1.217 + // save registers, fpu state, and flags 1.218 // We assume caller has already has return address slot on the stack 1.219 // We push epb twice in this sequence because we want the real ebp 1.220 // to be under the return like a normal enter and we want to use pushad 1.221 @@ -194,24 +163,24 @@ 1.222 __ sdc1(F0, SP, fpr0_off * jintSize); __ sdc1(F1, SP, fpr1_off * jintSize); 1.223 __ sdc1(F2, SP, fpr2_off * jintSize); __ sdc1(F3, SP, fpr3_off * jintSize); 1.224 __ sdc1(F4, SP, fpr4_off * jintSize); __ sdc1(F5, SP, fpr5_off * jintSize); 1.225 - __ sdc1(F6, SP, fpr6_off * jintSize); __ sdc1(F7, SP, fpr7_off * jintSize); 1.226 - __ sdc1(F8, SP, fpr8_off * jintSize); __ sdc1(F9, SP, fpr9_off * jintSize); 1.227 - __ sdc1(F10, SP, fpr10_off * jintSize); __ sdc1(F11, SP, fpr11_off * jintSize); 1.228 - __ sdc1(F12, SP, fpr12_off * jintSize); __ sdc1(F13, SP, fpr13_off * jintSize); 1.229 - __ sdc1(F14, SP, fpr14_off * jintSize); __ sdc1(F15, SP, fpr15_off * jintSize); 1.230 - __ sdc1(F16, SP, fpr16_off * jintSize); __ sdc1(F17, SP, fpr17_off * jintSize); 1.231 - __ sdc1(F18, SP, fpr18_off * jintSize); __ sdc1(F19, SP, fpr19_off * jintSize); 1.232 - __ sdc1(F20, SP, fpr20_off * jintSize); __ sdc1(F21, SP, fpr21_off * jintSize); 1.233 - __ sdc1(F22, SP, fpr22_off * jintSize); __ sdc1(F23, SP, fpr23_off * jintSize); 1.234 - __ sdc1(F24, SP, fpr24_off * jintSize); __ sdc1(F25, SP, fpr25_off * jintSize); 1.235 - __ sdc1(F26, SP, fpr26_off * jintSize); __ sdc1(F27, SP, fpr27_off * jintSize); 1.236 - __ sdc1(F28, SP, fpr28_off * jintSize); __ sdc1(F29, SP, fpr29_off * jintSize); 1.237 - __ sdc1(F30, SP, fpr30_off * jintSize); __ sdc1(F31, SP, fpr31_off * jintSize); 1.238 - __ sd(V0, SP, v0_off * jintSize); __ sd(V1, SP, v1_off * jintSize); 1.239 - __ sd(A0, SP, a0_off * jintSize); __ sd(A1, SP, a1_off * jintSize); 1.240 - __ sd(A2, SP, a2_off * jintSize); __ sd(A3, SP, a3_off * jintSize); 1.241 - __ sd(A4, SP, a4_off * jintSize); __ sd(A5, SP, a5_off * jintSize); 1.242 - __ sd(A6, SP, a6_off * jintSize); __ sd(A7, SP, a7_off * jintSize); 1.243 + __ sdc1(F6, SP, fpr6_off * jintSize); __ sdc1(F7, SP, fpr7_off * jintSize); 1.244 + __ sdc1(F8, SP, fpr8_off * jintSize); __ sdc1(F9, SP, fpr9_off * jintSize); 1.245 + __ sdc1(F10, SP, fpr10_off * jintSize); __ sdc1(F11, SP, fpr11_off * jintSize); 1.246 + __ sdc1(F12, SP, fpr12_off * jintSize); __ sdc1(F13, SP, fpr13_off * jintSize); 1.247 + __ sdc1(F14, SP, fpr14_off * jintSize); __ sdc1(F15, SP, fpr15_off * jintSize); 1.248 + __ sdc1(F16, SP, fpr16_off * jintSize); __ sdc1(F17, SP, fpr17_off * jintSize); 1.249 + __ sdc1(F18, SP, fpr18_off * jintSize); __ sdc1(F19, SP, fpr19_off * jintSize); 1.250 + __ sdc1(F20, SP, fpr20_off * jintSize); __ sdc1(F21, SP, fpr21_off * jintSize); 1.251 + __ sdc1(F22, SP, fpr22_off * jintSize); __ sdc1(F23, SP, fpr23_off * jintSize); 1.252 + __ sdc1(F24, SP, fpr24_off * jintSize); __ sdc1(F25, SP, fpr25_off * jintSize); 1.253 + __ sdc1(F26, SP, fpr26_off * jintSize); __ sdc1(F27, SP, fpr27_off * jintSize); 1.254 + __ sdc1(F28, SP, fpr28_off * jintSize); __ sdc1(F29, SP, fpr29_off * jintSize); 1.255 + __ sdc1(F30, SP, fpr30_off * jintSize); __ sdc1(F31, SP, fpr31_off * jintSize); 1.256 + __ sd(V0, SP, v0_off * jintSize); __ sd(V1, SP, v1_off * jintSize); 1.257 + __ sd(A0, SP, a0_off * jintSize); __ sd(A1, SP, a1_off * jintSize); 1.258 + __ sd(A2, SP, a2_off * jintSize); __ sd(A3, SP, a3_off * jintSize); 1.259 + __ sd(A4, SP, a4_off * jintSize); __ sd(A5, SP, a5_off * jintSize); 1.260 + __ sd(A6, SP, a6_off * jintSize); __ sd(A7, SP, a7_off * jintSize); 1.261 __ sd(T0, SP, t0_off * jintSize); 1.262 __ sd(T1, SP, t1_off * jintSize); 1.263 __ sd(T2, SP, t2_off * jintSize); 1.264 @@ -234,8 +203,8 @@ 1.265 __ daddi(FP, SP, fp_off * jintSize); 1.266 1.267 OopMapSet *oop_maps = new OopMapSet(); 1.268 - //OopMap* map = new OopMap( frame_words, 0 ); 1.269 - OopMap* map = new OopMap( frame_size_in_slots, 0 ); 1.270 + //OopMap* map = new OopMap( frame_words, 0 ); 1.271 + OopMap* map = new OopMap( frame_size_in_slots, 0 ); 1.272 1.273 1.274 //#define STACK_OFFSET(x) VMRegImpl::stack2reg((x) + additional_frame_words) 1.275 @@ -301,54 +270,6 @@ 1.276 map->set_callee_saved(STACK_OFFSET( fpr30_off), F30->as_VMReg()); 1.277 map->set_callee_saved(STACK_OFFSET( fpr31_off), F31->as_VMReg()); 1.278 1.279 -/* 1.280 - if (true) { 1.281 - map->set_callee_saved(STACK_OFFSET( v0H_off), V0->as_VMReg()->next()); 1.282 - map->set_callee_saved(STACK_OFFSET( v1H_off), V1->as_VMReg()->next()); 1.283 - map->set_callee_saved(STACK_OFFSET( a0H_off), A0->as_VMReg()->next()); 1.284 - map->set_callee_saved(STACK_OFFSET( a1H_off), A1->as_VMReg()->next()); 1.285 - map->set_callee_saved(STACK_OFFSET( a2H_off), A2->as_VMReg()->next()); 1.286 - map->set_callee_saved(STACK_OFFSET( a3H_off), A3->as_VMReg()->next()); 1.287 - map->set_callee_saved(STACK_OFFSET( a4H_off), A4->as_VMReg()->next()); 1.288 - map->set_callee_saved(STACK_OFFSET( a5H_off), A5->as_VMReg()->next()); 1.289 - map->set_callee_saved(STACK_OFFSET( a6H_off), A6->as_VMReg()->next()); 1.290 - map->set_callee_saved(STACK_OFFSET( a7H_off), A7->as_VMReg()->next()); 1.291 - map->set_callee_saved(STACK_OFFSET( t0H_off), T0->as_VMReg()->next()); 1.292 - map->set_callee_saved(STACK_OFFSET( t1H_off), T1->as_VMReg()->next()); 1.293 - map->set_callee_saved(STACK_OFFSET( t2H_off), T2->as_VMReg()->next()); 1.294 - map->set_callee_saved(STACK_OFFSET( t3H_off), T3->as_VMReg()->next()); 1.295 - map->set_callee_saved(STACK_OFFSET( s0H_off), S0->as_VMReg()->next()); 1.296 - map->set_callee_saved(STACK_OFFSET( s1H_off), S1->as_VMReg()->next()); 1.297 - map->set_callee_saved(STACK_OFFSET( s2H_off), S2->as_VMReg()->next()); 1.298 - map->set_callee_saved(STACK_OFFSET( s3H_off), S3->as_VMReg()->next()); 1.299 - map->set_callee_saved(STACK_OFFSET( s4H_off), S4->as_VMReg()->next()); 1.300 - map->set_callee_saved(STACK_OFFSET( s5H_off), S5->as_VMReg()->next()); 1.301 - map->set_callee_saved(STACK_OFFSET( s6H_off), S6->as_VMReg()->next()); 1.302 - map->set_callee_saved(STACK_OFFSET( s7H_off), S7->as_VMReg()->next()); 1.303 - map->set_callee_saved(STACK_OFFSET( t8H_off), T8->as_VMReg()->next()); 1.304 - map->set_callee_saved(STACK_OFFSET( t9H_off), T9->as_VMReg()->next()); 1.305 - map->set_callee_saved(STACK_OFFSET( gpH_off), GP->as_VMReg()->next()); 1.306 - map->set_callee_saved(STACK_OFFSET( fpH_off), FP->as_VMReg()->next()); 1.307 - map->set_callee_saved(STACK_OFFSET( returnH_off), RA->as_VMReg()->next()); 1.308 - 1.309 - map->set_callee_saved(STACK_OFFSET( fpr0H_off), F0->as_VMReg()->next()); 1.310 - map->set_callee_saved(STACK_OFFSET( fpr2H_off), F2->as_VMReg()->next()); 1.311 - map->set_callee_saved(STACK_OFFSET( fpr4H_off), F4->as_VMReg()->next()); 1.312 - map->set_callee_saved(STACK_OFFSET( fpr6H_off), F6->as_VMReg()->next()); 1.313 - map->set_callee_saved(STACK_OFFSET( fpr8H_off), F8->as_VMReg()->next()); 1.314 - map->set_callee_saved(STACK_OFFSET( fpr10H_off), F10->as_VMReg()->next()); 1.315 - map->set_callee_saved(STACK_OFFSET( fpr12H_off), F12->as_VMReg()->next()); 1.316 - map->set_callee_saved(STACK_OFFSET( fpr14H_off), F14->as_VMReg()->next()); 1.317 - map->set_callee_saved(STACK_OFFSET( fpr16H_off), F16->as_VMReg()->next()); 1.318 - map->set_callee_saved(STACK_OFFSET( fpr18H_off), F18->as_VMReg()->next()); 1.319 - map->set_callee_saved(STACK_OFFSET( fpr20H_off), F20->as_VMReg()->next()); 1.320 - map->set_callee_saved(STACK_OFFSET( fpr22H_off), F22->as_VMReg()->next()); 1.321 - map->set_callee_saved(STACK_OFFSET( fpr24H_off), F24->as_VMReg()->next()); 1.322 - map->set_callee_saved(STACK_OFFSET( fpr26H_off), F26->as_VMReg()->next()); 1.323 - map->set_callee_saved(STACK_OFFSET( fpr28H_off), F28->as_VMReg()->next()); 1.324 - map->set_callee_saved(STACK_OFFSET( fpr30H_off), F30->as_VMReg()->next()); 1.325 - } 1.326 -*/ 1.327 #undef STACK_OFFSET 1.328 return map; 1.329 } 1.330 @@ -360,25 +281,25 @@ 1.331 __ ldc1(F0, SP, fpr0_off * jintSize); __ ldc1(F1, SP, fpr1_off * jintSize); 1.332 __ ldc1(F2, SP, fpr2_off * jintSize); __ ldc1(F3, SP, fpr3_off * jintSize); 1.333 __ ldc1(F4, SP, fpr4_off * jintSize); __ ldc1(F5, SP, fpr5_off * jintSize); 1.334 - __ ldc1(F6, SP, fpr6_off * jintSize); __ ldc1(F7, SP, fpr7_off * jintSize); 1.335 - __ ldc1(F8, SP, fpr8_off * jintSize); __ ldc1(F9, SP, fpr9_off * jintSize); 1.336 - __ ldc1(F10, SP, fpr10_off * jintSize); __ ldc1(F11, SP, fpr11_off * jintSize); 1.337 - __ ldc1(F12, SP, fpr12_off * jintSize); __ ldc1(F13, SP, fpr13_off * jintSize); 1.338 - __ ldc1(F14, SP, fpr14_off * jintSize); __ ldc1(F15, SP, fpr15_off * jintSize); 1.339 - __ ldc1(F16, SP, fpr16_off * jintSize); __ ldc1(F17, SP, fpr17_off * jintSize); 1.340 - __ ldc1(F18, SP, fpr18_off * jintSize); __ ldc1(F19, SP, fpr19_off * jintSize); 1.341 - __ ldc1(F20, SP, fpr20_off * jintSize); __ ldc1(F21, SP, fpr21_off * jintSize); 1.342 - __ ldc1(F22, SP, fpr22_off * jintSize); __ ldc1(F23, SP, fpr23_off * jintSize); 1.343 - __ ldc1(F24, SP, fpr24_off * jintSize); __ ldc1(F25, SP, fpr25_off * jintSize); 1.344 - __ ldc1(F26, SP, fpr26_off * jintSize); __ ldc1(F27, SP, fpr27_off * jintSize); 1.345 - __ ldc1(F28, SP, fpr28_off * jintSize); __ ldc1(F29, SP, fpr29_off * jintSize); 1.346 - __ ldc1(F30, SP, fpr30_off * jintSize); __ ldc1(F31, SP, fpr31_off * jintSize); 1.347 - 1.348 - __ ld(V0, SP, v0_off * jintSize); __ ld(V1, SP, v1_off * jintSize); 1.349 - __ ld(A0, SP, a0_off * jintSize); __ ld(A1, SP, a1_off * jintSize); 1.350 - __ ld(A2, SP, a2_off * jintSize); __ ld(A3, SP, a3_off * jintSize); 1.351 - __ ld(A4, SP, a4_off * jintSize); __ ld(A5, SP, a5_off * jintSize); 1.352 - __ ld(A6, SP, a6_off * jintSize); __ ld(A7, SP, a7_off * jintSize); 1.353 + __ ldc1(F6, SP, fpr6_off * jintSize); __ ldc1(F7, SP, fpr7_off * jintSize); 1.354 + __ ldc1(F8, SP, fpr8_off * jintSize); __ ldc1(F9, SP, fpr9_off * jintSize); 1.355 + __ ldc1(F10, SP, fpr10_off * jintSize); __ ldc1(F11, SP, fpr11_off * jintSize); 1.356 + __ ldc1(F12, SP, fpr12_off * jintSize); __ ldc1(F13, SP, fpr13_off * jintSize); 1.357 + __ ldc1(F14, SP, fpr14_off * jintSize); __ ldc1(F15, SP, fpr15_off * jintSize); 1.358 + __ ldc1(F16, SP, fpr16_off * jintSize); __ ldc1(F17, SP, fpr17_off * jintSize); 1.359 + __ ldc1(F18, SP, fpr18_off * jintSize); __ ldc1(F19, SP, fpr19_off * jintSize); 1.360 + __ ldc1(F20, SP, fpr20_off * jintSize); __ ldc1(F21, SP, fpr21_off * jintSize); 1.361 + __ ldc1(F22, SP, fpr22_off * jintSize); __ ldc1(F23, SP, fpr23_off * jintSize); 1.362 + __ ldc1(F24, SP, fpr24_off * jintSize); __ ldc1(F25, SP, fpr25_off * jintSize); 1.363 + __ ldc1(F26, SP, fpr26_off * jintSize); __ ldc1(F27, SP, fpr27_off * jintSize); 1.364 + __ ldc1(F28, SP, fpr28_off * jintSize); __ ldc1(F29, SP, fpr29_off * jintSize); 1.365 + __ ldc1(F30, SP, fpr30_off * jintSize); __ ldc1(F31, SP, fpr31_off * jintSize); 1.366 + 1.367 + __ ld(V0, SP, v0_off * jintSize); __ ld(V1, SP, v1_off * jintSize); 1.368 + __ ld(A0, SP, a0_off * jintSize); __ ld(A1, SP, a1_off * jintSize); 1.369 + __ ld(A2, SP, a2_off * jintSize); __ ld(A3, SP, a3_off * jintSize); 1.370 + __ ld(A4, SP, a4_off * jintSize); __ ld(A5, SP, a5_off * jintSize); 1.371 + __ ld(A6, SP, a6_off * jintSize); __ ld(A7, SP, a7_off * jintSize); 1.372 __ ld(T0, SP, t0_off * jintSize); 1.373 __ ld(T1, SP, t1_off * jintSize); 1.374 __ ld(T2, SP, t2_off * jintSize); 1.375 @@ -406,36 +327,37 @@ 1.376 // a result. 1.377 // FIXME, if the result is float? 1.378 void RegisterSaver::restore_result_registers(MacroAssembler* masm) { 1.379 + 1.380 // Just restore result register. Only used by deoptimization. By 1.381 // now any callee save register that needs to be restore to a c2 1.382 // caller of the deoptee has been extracted into the vframeArray 1.383 // and will be stuffed into the c2i adapter we create for later 1.384 // restoration so only result registers need to be restored here. 1.385 - // 1.386 + 1.387 __ ld(V0, SP, v0_off * jintSize); 1.388 __ ld(V1, SP, v1_off * jintSize); 1.389 - __ addiu(SP, SP, return_off * jintSize); 1.390 + __ addiu(SP, SP, return_off * jintSize); 1.391 } 1.392 1.393 - // Is vector's size (in bytes) bigger than a size saved by default? 1.394 - // 16 bytes XMM registers are saved by default using fxsave/fxrstor instructions. 1.395 - bool SharedRuntime::is_wide_vector(int size) { 1.396 - return size > 16; 1.397 - } 1.398 +// Is vector's size (in bytes) bigger than a size saved by default? 1.399 +// 16 bytes XMM registers are saved by default using fxsave/fxrstor instructions. 1.400 +bool SharedRuntime::is_wide_vector(int size) { 1.401 + return size > 16; 1.402 +} 1.403 1.404 // The java_calling_convention describes stack locations as ideal slots on 1.405 // a frame with no abi restrictions. Since we must observe abi restrictions 1.406 // (like the placement of the register window) the slots must be biased by 1.407 // the following value. 1.408 1.409 -static int reg2offset_in(VMReg r) { 1.410 - // Account for saved ebp and return address 1.411 - // This should really be in_preserve_stack_slots 1.412 - return (r->reg2stack() + 2 * VMRegImpl::slots_per_word) * VMRegImpl::stack_slot_size; // + 2 * VMRegImpl::stack_slot_size); 1.413 +static int reg2offset_in(VMReg r) { 1.414 + // Account for saved ebp and return address 1.415 + // This should really be in_preserve_stack_slots 1.416 + return (r->reg2stack() + 2 * VMRegImpl::slots_per_word) * VMRegImpl::stack_slot_size; // + 2 * VMRegImpl::stack_slot_size); 1.417 } 1.418 1.419 -static int reg2offset_out(VMReg r) { 1.420 - return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; 1.421 +static int reg2offset_out(VMReg r) { 1.422 + return (r->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size; 1.423 } 1.424 1.425 // --------------------------------------------------------------------------- 1.426 @@ -470,10 +392,6 @@ 1.427 VMRegPair *regs, 1.428 int total_args_passed, 1.429 int is_outgoing) { 1.430 -//#define aoqi_test 1.431 -#ifdef aoqi_test 1.432 -tty->print_cr(" SharedRuntime::%s :%d, total_args_passed: %d", __func__, __LINE__, total_args_passed); 1.433 -#endif 1.434 1.435 // Create the mapping between argument positions and 1.436 // registers. 1.437 @@ -543,85 +461,9 @@ 1.438 ShouldNotReachHere(); 1.439 break; 1.440 } 1.441 -#ifdef aoqi_test 1.442 -tty->print_cr(" SharedRuntime::%s :%d, sig_bt[%d]: %d, reg[%d]:%d|%d, stk_args:%d", __func__, __LINE__, i, sig_bt[i], i, regs[i].first(), regs[i].second(), stk_args); 1.443 -#endif 1.444 } 1.445 1.446 return round_to(stk_args, 2); 1.447 -/* 1.448 - // Starting stack position for args on stack 1.449 - uint stack = 0; 1.450 - 1.451 - // Pass first five oop/int args in registers T0, A0 - A3. 1.452 - uint reg_arg0 = 9999; 1.453 - uint reg_arg1 = 9999; 1.454 - uint reg_arg2 = 9999; 1.455 - uint reg_arg3 = 9999; 1.456 - uint reg_arg4 = 9999; 1.457 - 1.458 - 1.459 - // Pass doubles & longs &float ligned on the stack. First count stack slots for doubles 1.460 - int i; 1.461 - for( i = 0; i < total_args_passed; i++) { 1.462 - if( sig_bt[i] == T_DOUBLE || sig_bt[i] == T_LONG ) { 1.463 - stack += 2; 1.464 - } 1.465 - } 1.466 - int dstack = 0; // Separate counter for placing doubles 1.467 - for( i = 0; i < total_args_passed; i++) { 1.468 - // From the type and the argument number (count) compute the location 1.469 - switch( sig_bt[i] ) { 1.470 - case T_SHORT: 1.471 - case T_CHAR: 1.472 - case T_BYTE: 1.473 - case T_BOOLEAN: 1.474 - case T_INT: 1.475 - case T_ARRAY: 1.476 - case T_OBJECT: 1.477 - case T_ADDRESS: 1.478 - if( reg_arg0 == 9999 ) { 1.479 - reg_arg0 = i; 1.480 - regs[i].set1(T0->as_VMReg()); 1.481 - } else if( reg_arg1 == 9999 ) { 1.482 - reg_arg1 = i; 1.483 - regs[i].set1(A0->as_VMReg()); 1.484 - } else if( reg_arg2 == 9999 ) { 1.485 - reg_arg2 = i; 1.486 - regs[i].set1(A1->as_VMReg()); 1.487 - }else if( reg_arg3 == 9999 ) { 1.488 - reg_arg3 = i; 1.489 - regs[i].set1(A2->as_VMReg()); 1.490 - }else if( reg_arg4 == 9999 ) { 1.491 - reg_arg4 = i; 1.492 - regs[i].set1(A3->as_VMReg()); 1.493 - } else { 1.494 - regs[i].set1(VMRegImpl::stack2reg(stack++)); 1.495 - } 1.496 - break; 1.497 - case T_FLOAT: 1.498 - regs[i].set1(VMRegImpl::stack2reg(stack++)); 1.499 - break; 1.500 - case T_LONG: 1.501 - assert(sig_bt[i+1] == T_VOID, "missing Half" ); 1.502 - regs[i].set2(VMRegImpl::stack2reg(dstack)); 1.503 - dstack += 2; 1.504 - break; 1.505 - case T_DOUBLE: 1.506 - assert(sig_bt[i+1] == T_VOID, "missing Half" ); 1.507 - regs[i].set2(VMRegImpl::stack2reg(dstack)); 1.508 - dstack += 2; 1.509 - break; 1.510 - case T_VOID: regs[i].set_bad(); break; 1.511 - break; 1.512 - default: 1.513 - ShouldNotReachHere(); 1.514 - break; 1.515 - } 1.516 - } 1.517 - // return value can be odd number of VMRegImpl stack slots make multiple of 2 1.518 - return round_to(stack, 2); 1.519 -*/ 1.520 } 1.521 1.522 // Helper class mostly to avoid passing masm everywhere, and handle store 1.523 @@ -634,7 +476,6 @@ 1.524 #endif // _LP64 1.525 1.526 void patch_callers_callsite(); 1.527 -// void tag_c2i_arg(frame::Tag t, Register base, int st_off, Register scratch); 1.528 1.529 // base+st_off points to top of argument 1.530 int arg_offset(const int st_off) { return st_off; } 1.531 @@ -684,130 +525,77 @@ 1.532 1.533 // Patch the callers callsite with entry to compiled code if it exists. 1.534 void AdapterGenerator::patch_callers_callsite() { 1.535 - Label L; 1.536 - //FIXME , what is stored in eax? 1.537 - //__ verify_oop(ebx); 1.538 - __ verify_oop(Rmethod); 1.539 - // __ cmpl(Address(ebx, in_bytes(Method::code_offset())), NULL_WORD); 1.540 - __ ld_ptr(AT, Rmethod, in_bytes(Method::code_offset())); 1.541 - //__ jcc(Assembler::equal, L); 1.542 - __ beq(AT,R0,L); 1.543 - __ delayed()->nop(); 1.544 - // Schedule the branch target address early. 1.545 - // Call into the VM to patch the caller, then jump to compiled callee 1.546 - // eax isn't live so capture return address while we easily can 1.547 - // __ movl(eax, Address(esp, 0)); 1.548 -// __ lw(T5,SP,0); 1.549 - __ move(V0, RA); 1.550 - 1.551 - __ pushad(); 1.552 - //jerome_for_debug 1.553 - // __ pushad(); 1.554 - // __ pushfd(); 1.555 + Label L; 1.556 + __ verify_oop(Rmethod); 1.557 + __ ld_ptr(AT, Rmethod, in_bytes(Method::code_offset())); 1.558 + __ beq(AT,R0,L); 1.559 + __ delayed()->nop(); 1.560 + // Schedule the branch target address early. 1.561 + // Call into the VM to patch the caller, then jump to compiled callee 1.562 + // eax isn't live so capture return address while we easily can 1.563 + __ move(V0, RA); 1.564 + 1.565 + __ pushad(); 1.566 #ifdef COMPILER2 1.567 - // C2 may leave the stack dirty if not in SSE2+ mode 1.568 - __ empty_FPU_stack(); 1.569 + // C2 may leave the stack dirty if not in SSE2+ mode 1.570 + __ empty_FPU_stack(); 1.571 #endif /* COMPILER2 */ 1.572 1.573 - // VM needs caller's callsite 1.574 - // __ pushl(eax); 1.575 - 1.576 - // VM needs target method 1.577 - // __ pushl(ebx); 1.578 - // __ push(Rmethod); 1.579 - // __ verify_oop(ebx); 1.580 - 1.581 - __ move(A0, Rmethod); 1.582 - __ move(A1, V0); 1.583 -// __ addi(SP, SP, -8); 1.584 + // VM needs caller's callsite 1.585 + // VM needs target method 1.586 + 1.587 + __ move(A0, Rmethod); 1.588 + __ move(A1, V0); 1.589 //we should preserve the return address 1.590 - __ verify_oop(Rmethod); 1.591 - __ move(S0, SP); 1.592 - __ move(AT, -(StackAlignmentInBytes)); // align the stack 1.593 - __ andr(SP, SP, AT); 1.594 - __ call(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite), 1.595 - relocInfo::runtime_call_type); 1.596 - //__ addl(esp, 2*wordSize); 1.597 - 1.598 - __ delayed()->nop(); 1.599 - // __ addi(SP, SP, 8); 1.600 - // __ popfd(); 1.601 - __ move(SP, S0); 1.602 - __ popad(); 1.603 - __ bind(L); 1.604 + __ verify_oop(Rmethod); 1.605 + __ move(S0, SP); 1.606 + __ move(AT, -(StackAlignmentInBytes)); // align the stack 1.607 + __ andr(SP, SP, AT); 1.608 + __ call(CAST_FROM_FN_PTR(address, SharedRuntime::fixup_callers_callsite), 1.609 + relocInfo::runtime_call_type); 1.610 + 1.611 + __ delayed()->nop(); 1.612 + __ move(SP, S0); 1.613 + __ popad(); 1.614 + __ bind(L); 1.615 } 1.616 -/* 1.617 -void AdapterGenerator::tag_c2i_arg(frame::Tag t, Register base, int st_off, 1.618 - Register scratch) { 1.619 - Unimplemented(); 1.620 -}*/ 1.621 1.622 #ifdef _LP64 1.623 Register AdapterGenerator::arg_slot(const int st_off) { 1.624 - Unimplemented(); 1.625 + Unimplemented(); 1.626 } 1.627 1.628 Register AdapterGenerator::next_arg_slot(const int st_off){ 1.629 - Unimplemented(); 1.630 + Unimplemented(); 1.631 } 1.632 #endif // _LP64 1.633 1.634 // Stores long into offset pointed to by base 1.635 void AdapterGenerator::store_c2i_long(Register r, Register base, 1.636 const int st_off, bool is_stack) { 1.637 - Unimplemented(); 1.638 + Unimplemented(); 1.639 } 1.640 1.641 void AdapterGenerator::store_c2i_object(Register r, Register base, 1.642 - const int st_off) { 1.643 - Unimplemented(); 1.644 + const int st_off) { 1.645 + Unimplemented(); 1.646 } 1.647 1.648 void AdapterGenerator::store_c2i_int(Register r, Register base, 1.649 - const int st_off) { 1.650 - Unimplemented(); 1.651 + const int st_off) { 1.652 + Unimplemented(); 1.653 } 1.654 1.655 // Stores into offset pointed to by base 1.656 void AdapterGenerator::store_c2i_double(VMReg r_2, 1.657 VMReg r_1, Register base, const int st_off) { 1.658 - Unimplemented(); 1.659 + Unimplemented(); 1.660 } 1.661 1.662 void AdapterGenerator::store_c2i_float(FloatRegister f, Register base, 1.663 const int st_off) { 1.664 - Unimplemented(); 1.665 + Unimplemented(); 1.666 } 1.667 -/* 1.668 -void AdapterGenerator::tag_stack(const BasicType sig, int st_off) { 1.669 - if (TaggedStackInterpreter) { 1.670 - int tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(0); 1.671 - if (sig == T_OBJECT || sig == T_ARRAY) { 1.672 - // __ movl(Address(esp, tag_offset), frame::TagReference); 1.673 - // __ addi(AT,R0, frame::TagReference); 1.674 - 1.675 - __ move(AT, frame::TagReference); 1.676 - __ sw (AT, SP, tag_offset); 1.677 - } else if (sig == T_LONG || sig == T_DOUBLE) { 1.678 - int next_tag_offset = st_off + Interpreter::expr_tag_offset_in_bytes(1); 1.679 - // __ movl(Address(esp, next_tag_offset), frame::TagValue); 1.680 - // __ addi(AT,R0, frame::TagValue); 1.681 - __ move(AT, frame::TagValue); 1.682 - __ sw (AT, SP, next_tag_offset); 1.683 - //__ movl(Address(esp, tag_offset), frame::TagValue); 1.684 - // __ addi(AT,R0, frame::TagValue); 1.685 - __ move(AT, frame::TagValue); 1.686 - __ sw (AT, SP, tag_offset); 1.687 - 1.688 - } else { 1.689 - // __ movl(Address(esp, tag_offset), frame::TagValue); 1.690 - //__ addi(AT,R0, frame::TagValue); 1.691 - __ move(AT, frame::TagValue); 1.692 - __ sw (AT, SP, tag_offset); 1.693 - 1.694 - } 1.695 - } 1.696 -}*/ 1.697 1.698 void AdapterGenerator::gen_c2i_adapter( 1.699 int total_args_passed, 1.700 @@ -834,113 +622,77 @@ 1.701 // call and not bother building another interpreter arg area. We don't 1.702 // do that at this point. 1.703 1.704 - patch_callers_callsite(); 1.705 - 1.706 - __ bind(skip_fixup); 1.707 + patch_callers_callsite(); 1.708 + 1.709 + __ bind(skip_fixup); 1.710 1.711 #ifdef COMPILER2 1.712 - __ empty_FPU_stack(); 1.713 + __ empty_FPU_stack(); 1.714 #endif /* COMPILER2 */ 1.715 - //this is for native ? 1.716 - // Since all args are passed on the stack, total_args_passed * interpreter_ 1.717 - // stack_element_size is the 1.718 - // space we need. 1.719 - int extraspace = total_args_passed * Interpreter::stackElementSize; 1.720 - 1.721 - // stack is aligned, keep it that way 1.722 - extraspace = round_to(extraspace, 2*wordSize); 1.723 - 1.724 - // Get return address 1.725 - // __ popl(eax); 1.726 - //__ pop(T4); 1.727 - __ move(V0, RA); 1.728 - // set senderSP value 1.729 - // __ movl(esi, esp); 1.730 -//refer to interpreter_mips.cpp:generate_asm_entry 1.731 - __ move(Rsender, SP); 1.732 - //__ subl(esp, extraspace); 1.733 - __ addi(SP, SP, -extraspace); 1.734 - 1.735 - // Now write the args into the outgoing interpreter space 1.736 - for (int i = 0; i < total_args_passed; i++) { 1.737 - if (sig_bt[i] == T_VOID) { 1.738 - assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), 1.739 - "missing half"); 1.740 - continue; 1.741 - } 1.742 - 1.743 - // st_off points to lowest address on stack. 1.744 - int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize; 1.745 -#ifdef aoqi_test 1.746 -tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d, st_off:%d", __func__, __LINE__, i, sig_bt[i], total_args_passed, st_off); 1.747 -#endif 1.748 - // Say 4 args: 1.749 - // i st_off 1.750 - // 0 12 T_LONG 1.751 - // 1 8 T_VOID 1.752 - // 2 4 T_OBJECT 1.753 - // 3 0 T_BOOL 1.754 - VMReg r_1 = regs[i].first(); 1.755 - VMReg r_2 = regs[i].second(); 1.756 - if (!r_1->is_valid()) { 1.757 - assert(!r_2->is_valid(), ""); 1.758 - continue; 1.759 - } 1.760 - 1.761 - if (r_1->is_stack()) { 1.762 - // memory to memory use fpu stack top 1.763 - int ld_off = r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace; 1.764 -#ifdef aoqi_test 1.765 -tty->print_cr(" AdapterGenerator::%s :%d, r_1->is_stack, ld_off:%x", __func__, __LINE__, ld_off); 1.766 -#endif 1.767 - 1.768 - if (!r_2->is_valid()) { 1.769 -#ifdef aoqi_test 1.770 -tty->print_cr(" AdapterGenerator::%s :%d, !r_2->is_valid, ld_off:%x", __func__, __LINE__, ld_off); 1.771 -#endif 1.772 - __ ld_ptr(AT, SP, ld_off); 1.773 - __ st_ptr(AT, SP, st_off); 1.774 - //tag_stack(sig_bt[i], st_off); 1.775 - } else { 1.776 -#ifdef aoqi_test 1.777 -tty->print_cr(" AdapterGenerator::%s :%d, r_2->is_valid, ld_off:%x", __func__, __LINE__, ld_off); 1.778 -#endif 1.779 - 1.780 - // ld_off == LSW, ld_off+VMRegImpl::stack_slot_size == MSW 1.781 - // st_off == MSW, st_off-wordSize == LSW 1.782 - 1.783 - int next_off = st_off - Interpreter::stackElementSize; 1.784 - /* 1.785 - __ lw(AT, SP, ld_off); 1.786 - __ sw(AT, SP, next_off); 1.787 - __ lw(AT, SP, ld_off + wordSize); 1.788 - __ sw(AT, SP, st_off); 1.789 - */ 1.790 - __ ld_ptr(AT, SP, ld_off); 1.791 - __ st_ptr(AT, SP, st_off); 1.792 - 1.793 - /* Ref to is_Register condition */ 1.794 - if(sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) 1.795 - __ st_ptr(AT,SP,st_off - 8); 1.796 - //tag_stack(sig_bt[i], next_off); 1.797 - } 1.798 - } else if (r_1->is_Register()) { 1.799 - Register r = r_1->as_Register(); 1.800 - if (!r_2->is_valid()) { 1.801 -#ifdef aoqi_test 1.802 -tty->print_cr(" AdapterGenerator::%s :%d, r_1->is_Register, !r_2->is_valid, st_off: %lx", __func__, __LINE__, st_off); 1.803 -#endif 1.804 - // __ movl(Address(esp, st_off), r); 1.805 - __ sd(r,SP, st_off); //aoqi_test FIXME 1.806 - //tag_stack(sig_bt[i], st_off); 1.807 - } else { 1.808 -#ifdef aoqi_test 1.809 -tty->print_cr(" AdapterGenerator::%s :%d, r_1->is_Register, r_2->is_valid, st_off: %lx", __func__, __LINE__, st_off); 1.810 -#endif 1.811 - //FIXME, mips will not enter here 1.812 - // long/double in gpr 1.813 - __ sd(r,SP, st_off); //aoqi_test FIXME 1.814 -/* Jin: In [java/util/zip/ZipFile.java] 1.815 + //this is for native ? 1.816 + // Since all args are passed on the stack, total_args_passed * interpreter_ 1.817 + // stack_element_size is the 1.818 + // space we need. 1.819 + int extraspace = total_args_passed * Interpreter::stackElementSize; 1.820 + 1.821 + // stack is aligned, keep it that way 1.822 + extraspace = round_to(extraspace, 2*wordSize); 1.823 + 1.824 + // Get return address 1.825 + __ move(V0, RA); 1.826 + // set senderSP value 1.827 + //refer to interpreter_mips.cpp:generate_asm_entry 1.828 + __ move(Rsender, SP); 1.829 + __ addi(SP, SP, -extraspace); 1.830 + 1.831 + // Now write the args into the outgoing interpreter space 1.832 + for (int i = 0; i < total_args_passed; i++) { 1.833 + if (sig_bt[i] == T_VOID) { 1.834 + assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half"); 1.835 + continue; 1.836 + } 1.837 + 1.838 + // st_off points to lowest address on stack. 1.839 + int st_off = ((total_args_passed - 1) - i) * Interpreter::stackElementSize; 1.840 + // Say 4 args: 1.841 + // i st_off 1.842 + // 0 12 T_LONG 1.843 + // 1 8 T_VOID 1.844 + // 2 4 T_OBJECT 1.845 + // 3 0 T_BOOL 1.846 + VMReg r_1 = regs[i].first(); 1.847 + VMReg r_2 = regs[i].second(); 1.848 + if (!r_1->is_valid()) { 1.849 + assert(!r_2->is_valid(), ""); 1.850 + continue; 1.851 + } 1.852 + if (r_1->is_stack()) { 1.853 + // memory to memory use fpu stack top 1.854 + int ld_off = r_1->reg2stack() * VMRegImpl::stack_slot_size + extraspace; 1.855 + if (!r_2->is_valid()) { 1.856 + __ ld_ptr(AT, SP, ld_off); 1.857 + __ st_ptr(AT, SP, st_off); 1.858 + 1.859 + } else { 1.860 + 1.861 + 1.862 + int next_off = st_off - Interpreter::stackElementSize; 1.863 + __ ld_ptr(AT, SP, ld_off); 1.864 + __ st_ptr(AT, SP, st_off); 1.865 + 1.866 + /* Ref to is_Register condition */ 1.867 + if(sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) 1.868 + __ st_ptr(AT,SP,st_off - 8); 1.869 + } 1.870 + } else if (r_1->is_Register()) { 1.871 + Register r = r_1->as_Register(); 1.872 + if (!r_2->is_valid()) { 1.873 + __ sd(r,SP, st_off); //aoqi_test FIXME 1.874 + } else { 1.875 + //FIXME, mips will not enter here 1.876 + // long/double in gpr 1.877 + __ sd(r,SP, st_off); //aoqi_test FIXME 1.878 +/* Jin: In [java/util/zip/ZipFile.java] 1.879 1.880 private static native long open(String name, int mode, long lastModified); 1.881 private static native int getTotal(long jzfile); 1.882 @@ -950,9 +702,9 @@ 1.883 * 1.884 * Caller -> lir_static_call -> gen_resolve_stub 1.885 -> -- resolve_static_call_C 1.886 - `- gen_c2i_adapter() [*] 1.887 + `- gen_c2i_adapter() [*] 1.888 | 1.889 - `- AdapterHandlerLibrary::get_create_apapter_index 1.890 + `- AdapterHandlerLibrary::get_create_apapter_index 1.891 -> generate_native_entry 1.892 -> InterpreterRuntime::SignatureHandlerGenerator::pass_long [**] 1.893 1.894 @@ -970,7 +722,7 @@ 1.895 | | 1.896 (low) 1.897 * 1.898 - * However, the sequence is reversed here: 1.899 + * However, the sequence is reversed here: 1.900 * 1.901 (high) 1.902 | | 1.903 @@ -986,42 +738,36 @@ 1.904 * 1.905 * So I stored another 8 bytes in the T_VOID slot. It then can be accessed from generate_native_entry(). 1.906 */ 1.907 - if (sig_bt[i] == T_LONG) 1.908 - __ sd(r,SP, st_off - 8); 1.909 - // ShouldNotReachHere(); 1.910 - // int next_off = st_off - Interpreter::stackElementSize; 1.911 - // __ sw(r_2->as_Register(),SP, st_off); 1.912 - // __ sw(r,SP, next_off); 1.913 - // tag_stack(masm, sig_bt[i], next_off); 1.914 - } 1.915 - } else if (r_1->is_FloatRegister()) { 1.916 - assert(sig_bt[i] == T_FLOAT || sig_bt[i] == T_DOUBLE, "Must be a float register"); 1.917 - 1.918 - FloatRegister fr = r_1->as_FloatRegister(); 1.919 - if (sig_bt[i] == T_FLOAT) 1.920 - __ swc1(fr,SP, st_off); 1.921 - else 1.922 - { 1.923 - __ sdc1(fr,SP, st_off); 1.924 - __ sdc1(fr,SP, st_off - 8); /* T_DOUBLE needs two slots */ 1.925 - } 1.926 - } 1.927 - } 1.928 - 1.929 - // Schedule the branch target address early. 1.930 - __ ld_ptr(AT, Rmethod,in_bytes(Method::interpreter_entry_offset()) ); 1.931 - // And repush original return address 1.932 - __ move(RA, V0); 1.933 - __ jr (AT); 1.934 - __ delayed()->nop(); 1.935 + if (sig_bt[i] == T_LONG) 1.936 + __ sd(r,SP, st_off - 8); 1.937 + } 1.938 + } else if (r_1->is_FloatRegister()) { 1.939 + assert(sig_bt[i] == T_FLOAT || sig_bt[i] == T_DOUBLE, "Must be a float register"); 1.940 + 1.941 + FloatRegister fr = r_1->as_FloatRegister(); 1.942 + if (sig_bt[i] == T_FLOAT) 1.943 + __ swc1(fr,SP, st_off); 1.944 + else { 1.945 + __ sdc1(fr,SP, st_off); 1.946 + __ sdc1(fr,SP, st_off - 8); /* T_DOUBLE needs two slots */ 1.947 + } 1.948 + } 1.949 + } 1.950 + 1.951 + // Schedule the branch target address early. 1.952 + __ ld_ptr(AT, Rmethod,in_bytes(Method::interpreter_entry_offset()) ); 1.953 + // And repush original return address 1.954 + __ move(RA, V0); 1.955 + __ jr (AT); 1.956 + __ delayed()->nop(); 1.957 } 1.958 1.959 void AdapterGenerator::gen_i2c_adapter( 1.960 - int total_args_passed, 1.961 - // VMReg max_arg, 1.962 - int comp_args_on_stack, // VMRegStackSlots 1.963 - const BasicType *sig_bt, 1.964 - const VMRegPair *regs) { 1.965 + int total_args_passed, 1.966 + // VMReg max_arg, 1.967 + int comp_args_on_stack, // VMRegStackSlots 1.968 + const BasicType *sig_bt, 1.969 + const VMRegPair *regs) { 1.970 1.971 // Generate an I2C adapter: adjust the I-frame to make space for the C-frame 1.972 // layout. Lesp was saved by the calling I-frame and will be restored on 1.973 @@ -1058,7 +804,7 @@ 1.974 1.975 // Align the outgoing SP 1.976 __ move(AT, -(StackAlignmentInBytes)); 1.977 - __ andr(SP, SP, AT); 1.978 + __ andr(SP, SP, AT); 1.979 // push the return address on the stack (note that pushing, rather 1.980 // than storing it, yields the correct frame alignment for the callee) 1.981 // Put saved SP in another register 1.982 @@ -1081,16 +827,16 @@ 1.983 continue; 1.984 } 1.985 1.986 - // Pick up 0, 1 or 2 words from SP+offset. 1.987 - 1.988 - //FIXME. aoqi. just delete the assert 1.989 + // Pick up 0, 1 or 2 words from SP+offset. 1.990 + 1.991 + //FIXME. aoqi. just delete the assert 1.992 //assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(), "scrambled load targets?"); 1.993 // Load in argument order going down. 1.994 int ld_off = (total_args_passed -1 - i)*Interpreter::stackElementSize; 1.995 // Point to interpreter value (vs. tag) 1.996 int next_off = ld_off - Interpreter::stackElementSize; 1.997 // 1.998 - // 1.999 + // 1.1000 // 1.1001 VMReg r_1 = regs[i].first(); 1.1002 VMReg r_2 = regs[i].second(); 1.1003 @@ -1098,114 +844,96 @@ 1.1004 assert(!r_2->is_valid(), ""); 1.1005 continue; 1.1006 } 1.1007 -#ifdef aoqi_test 1.1008 -tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d, ld_off:%d, next_off: %d", __func__, __LINE__, i, sig_bt[i], total_args_passed, ld_off, next_off); 1.1009 -#endif 1.1010 - if (r_1->is_stack()) { 1.1011 - // Convert stack slot to an SP offset (+ wordSize to 1.1012 + if (r_1->is_stack()) { 1.1013 + // Convert stack slot to an SP offset (+ wordSize to 1.1014 // account for return address ) 1.1015 - //NOTICE HERE!!!! I sub a wordSize here 1.1016 - int st_off = regs[i].first()->reg2stack()*VMRegImpl::stack_slot_size; 1.1017 + //NOTICE HERE!!!! I sub a wordSize here 1.1018 + int st_off = regs[i].first()->reg2stack()*VMRegImpl::stack_slot_size; 1.1019 //+ wordSize; 1.1020 1.1021 - // We can use esi as a temp here because compiled code doesn't 1.1022 + // We can use esi as a temp here because compiled code doesn't 1.1023 // need esi as an input 1.1024 - // and if we end up going thru a c2i because of a miss a reasonable 1.1025 - // value of esi 1.1026 - // we be generated. 1.1027 + // and if we end up going thru a c2i because of a miss a reasonable 1.1028 + // value of esi 1.1029 + // we be generated. 1.1030 if (!r_2->is_valid()) { 1.1031 -#ifdef aoqi_test 1.1032 -tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d r_1->is_stack() !r_2->is_valid(), st_off:%d", __func__, __LINE__, i, sig_bt[i], total_args_passed, st_off); 1.1033 -#endif 1.1034 - __ ld(AT, saved_sp, ld_off); 1.1035 - __ sd(AT, SP, st_off); 1.1036 + __ ld(AT, saved_sp, ld_off); 1.1037 + __ sd(AT, SP, st_off); 1.1038 } else { 1.1039 -#ifdef aoqi_test 1.1040 -tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d r_1->is_stack() r_2->is_valid(), st_off:%d", __func__, __LINE__, i, sig_bt[i], total_args_passed, st_off); 1.1041 -#endif 1.1042 - // Interpreter local[n] == MSW, local[n+1] == LSW however locals 1.1043 - // are accessed as negative so LSW is at LOW address 1.1044 - 1.1045 - // ld_off is MSW so get LSW 1.1046 - // st_off is LSW (i.e. reg.first()) 1.1047 - /* 1.1048 - __ ld(AT, saved_sp, next_off); 1.1049 - __ sd(AT, SP, st_off); 1.1050 - __ ld(AT, saved_sp, ld_off); 1.1051 - __ sd(AT, SP, st_off + wordSize); 1.1052 - */ 1.1053 - 1.1054 - /* 2012/4/9 Jin 1.1055 - * [./org/eclipse/swt/graphics/GC.java] 1.1056 - * void drawImageXRender(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, 1.1057 - int destX, int destY, int destWidth, int destHeight, 1.1058 - boolean simple, 1.1059 - int imgWidth, int imgHeight, 1.1060 - long maskPixmap, <-- Pass T_LONG in stack 1.1061 - int maskType); 1.1062 - * Before this modification, Eclipse displays icons with solid black background. 1.1063 - */ 1.1064 - __ ld(AT, saved_sp, ld_off); 1.1065 + // Interpreter local[n] == MSW, local[n+1] == LSW however locals 1.1066 + // are accessed as negative so LSW is at LOW address 1.1067 + 1.1068 + // ld_off is MSW so get LSW 1.1069 + // st_off is LSW (i.e. reg.first()) 1.1070 + /* 1.1071 + __ ld(AT, saved_sp, next_off); 1.1072 + __ sd(AT, SP, st_off); 1.1073 + __ ld(AT, saved_sp, ld_off); 1.1074 + __ sd(AT, SP, st_off + wordSize); 1.1075 + */ 1.1076 + 1.1077 + /* 2012/4/9 Jin 1.1078 + * [./org/eclipse/swt/graphics/GC.java] 1.1079 + * void drawImageXRender(Image srcImage, int srcX, int srcY, int srcWidth, int srcHeight, 1.1080 + int destX, int destY, int destWidth, int destHeight, 1.1081 + boolean simple, 1.1082 + int imgWidth, int imgHeight, 1.1083 + long maskPixmap, <-- Pass T_LONG in stack 1.1084 + int maskType); 1.1085 + * Before this modification, Eclipse displays icons with solid black background. 1.1086 + */ 1.1087 + __ ld(AT, saved_sp, ld_off); 1.1088 if (sig_bt[i] == T_LONG || sig_bt[i] == T_DOUBLE) 1.1089 - __ ld(AT, saved_sp, ld_off - 8); 1.1090 - __ sd(AT, SP, st_off); 1.1091 - //__ ld(AT, saved_sp, next_off); 1.1092 - //__ sd(AT, SP, st_off + wordSize); 1.1093 + __ ld(AT, saved_sp, ld_off - 8); 1.1094 + __ sd(AT, SP, st_off); 1.1095 } 1.1096 } else if (r_1->is_Register()) { // Register argument 1.1097 Register r = r_1->as_Register(); 1.1098 // assert(r != eax, "must be different"); 1.1099 if (r_2->is_valid()) { 1.1100 -#ifdef aoqi_test 1.1101 -tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d r_1->is_Register() r_2->is_valid()", __func__, __LINE__, i, sig_bt[i], total_args_passed); 1.1102 -#endif 1.1103 - // assert(r_2->as_Register() != eax, "need another temporary register"); 1.1104 - // Remember r_1 is low address (and LSB on mips) 1.1105 - // So r_2 gets loaded from high address regardless of the platform 1.1106 - //aoqi 1.1107 - assert(r_2->as_Register() == r_1->as_Register(), ""); 1.1108 - //__ ld(r_2->as_Register(), saved_sp, ld_off); 1.1109 - //__ ld(r, saved_sp, next_off); 1.1110 - __ ld(r, saved_sp, ld_off); 1.1111 - 1.1112 -/* Jin: 1.1113 - * 1.1114 - * For T_LONG type, the real layout is as below: 1.1115 - 1.1116 - (high) 1.1117 - | | 1.1118 - ----------- 1.1119 - | 8 bytes | 1.1120 - | (void) | 1.1121 - ----------- 1.1122 - | 8 bytes | 1.1123 - | (long) | 1.1124 - ----------- 1.1125 - | | 1.1126 - (low) 1.1127 - * 1.1128 - * We should load the low-8 bytes. 1.1129 - */ 1.1130 - if (sig_bt[i] == T_LONG) 1.1131 - __ ld(r, saved_sp, ld_off - 8); 1.1132 + // assert(r_2->as_Register() != eax, "need another temporary register"); 1.1133 + // Remember r_1 is low address (and LSB on mips) 1.1134 + // So r_2 gets loaded from high address regardless of the platform 1.1135 + //aoqi 1.1136 + assert(r_2->as_Register() == r_1->as_Register(), ""); 1.1137 + //__ ld(r_2->as_Register(), saved_sp, ld_off); 1.1138 + //__ ld(r, saved_sp, next_off); 1.1139 + __ ld(r, saved_sp, ld_off); 1.1140 + 1.1141 + /* Jin: 1.1142 + * 1.1143 + * For T_LONG type, the real layout is as below: 1.1144 + 1.1145 + (high) 1.1146 + | | 1.1147 + ----------- 1.1148 + | 8 bytes | 1.1149 + | (void) | 1.1150 + ----------- 1.1151 + | 8 bytes | 1.1152 + | (long) | 1.1153 + ----------- 1.1154 + | | 1.1155 + (low) 1.1156 + * 1.1157 + * We should load the low-8 bytes. 1.1158 + */ 1.1159 + if (sig_bt[i] == T_LONG) 1.1160 + __ ld(r, saved_sp, ld_off - 8); 1.1161 } else { 1.1162 -#ifdef aoqi_test 1.1163 -tty->print_cr(" AdapterGenerator::%s :%d, sig_bt[%d]:%d, total_args_passed:%d r_1->is_Register() !r_2->is_valid()", __func__, __LINE__, i, sig_bt[i], total_args_passed); 1.1164 -#endif 1.1165 - __ lw(r, saved_sp, ld_off); 1.1166 + __ lw(r, saved_sp, ld_off); 1.1167 } 1.1168 } else if (r_1->is_FloatRegister()) { // Float Register 1.1169 - assert(sig_bt[i] == T_FLOAT || sig_bt[i] == T_DOUBLE, "Must be a float register"); 1.1170 - 1.1171 - FloatRegister fr = r_1->as_FloatRegister(); 1.1172 - if (sig_bt[i] == T_FLOAT) 1.1173 - __ lwc1(fr, saved_sp, ld_off); 1.1174 - else 1.1175 - { 1.1176 - __ ldc1(fr, saved_sp, ld_off); 1.1177 - __ ldc1(fr, saved_sp, ld_off - 8); 1.1178 - } 1.1179 - } 1.1180 + assert(sig_bt[i] == T_FLOAT || sig_bt[i] == T_DOUBLE, "Must be a float register"); 1.1181 + 1.1182 + FloatRegister fr = r_1->as_FloatRegister(); 1.1183 + if (sig_bt[i] == T_FLOAT) 1.1184 + __ lwc1(fr, saved_sp, ld_off); 1.1185 + else { 1.1186 + __ ldc1(fr, saved_sp, ld_off); 1.1187 + __ ldc1(fr, saved_sp, ld_off - 8); 1.1188 + } 1.1189 + } 1.1190 } 1.1191 1.1192 // 6243940 We might end up in handle_wrong_method if 1.1193 @@ -1223,8 +951,8 @@ 1.1194 // move methodOop to eax in case we end up in an c2i adapter. 1.1195 // the c2i adapters expect methodOop in eax (c2) because c2's 1.1196 // resolve stubs return the result (the method) in eax. 1.1197 - // I'd love to fix this. 1.1198 - __ move(V0, Rmethod); 1.1199 + // I'd love to fix this. 1.1200 + __ move(V0, Rmethod); 1.1201 __ jr(T9); 1.1202 __ delayed()->nop(); 1.1203 } 1.1204 @@ -1264,33 +992,24 @@ 1.1205 Label missed; 1.1206 1.1207 __ verify_oop(holder); 1.1208 - // __ movl(temp, Address(receiver, oopDesc::klass_offset_in_bytes())); 1.1209 - //__ ld_ptr(temp, receiver, oopDesc::klass_offset_in_bytes()); 1.1210 //add for compressedoops 1.1211 __ load_klass(temp, receiver); 1.1212 __ verify_oop(temp); 1.1213 1.1214 - // __ cmpl(temp, Address(holder, CompiledICHolder::holder_klass_offset())); 1.1215 - __ ld_ptr(AT, holder, CompiledICHolder::holder_klass_offset()); 1.1216 - //__ movl(ebx, Address(holder, CompiledICHolder::holder_method_offset())); 1.1217 + __ ld_ptr(AT, holder, CompiledICHolder::holder_klass_offset()); 1.1218 __ ld_ptr(Rmethod, holder, CompiledICHolder::holder_method_offset()); 1.1219 - //__ jcc(Assembler::notEqual, missed); 1.1220 - __ bne(AT, temp, missed); 1.1221 - __ delayed()->nop(); 1.1222 + __ bne(AT, temp, missed); 1.1223 + __ delayed()->nop(); 1.1224 // Method might have been compiled since the call site was patched to 1.1225 // interpreted if that is the case treat it as a miss so we can get 1.1226 // the call site corrected. 1.1227 - //__ cmpl(Address(ebx, in_bytes(Method::code_offset())), NULL_WORD); 1.1228 - //__ jcc(Assembler::equal, skip_fixup); 1.1229 __ ld_ptr(AT, Rmethod, in_bytes(Method::code_offset())); 1.1230 - __ beq(AT, R0, skip_fixup); 1.1231 - __ delayed()->nop(); 1.1232 + __ beq(AT, R0, skip_fixup); 1.1233 + __ delayed()->nop(); 1.1234 __ bind(missed); 1.1235 - // __ move(AT, (int)&jerome7); 1.1236 - // __ sw(RA, AT, 0); 1.1237 1.1238 __ jmp(ic_miss, relocInfo::runtime_call_type); 1.1239 - __ delayed()->nop(); 1.1240 + __ delayed()->nop(); 1.1241 } 1.1242 1.1243 address c2i_entry = __ pc(); 1.1244 @@ -1299,72 +1018,34 @@ 1.1245 1.1246 __ flush(); 1.1247 return AdapterHandlerLibrary::new_entry(fingerprint,i2c_entry, c2i_entry, c2i_unverified_entry); 1.1248 - 1.1249 } 1.1250 -/* 1.1251 -// Helper function for native calling conventions 1.1252 -static VMReg int_stk_helper( int i ) { 1.1253 - // Bias any stack based VMReg we get by ignoring the window area 1.1254 - // but not the register parameter save area. 1.1255 - // 1.1256 - // This is strange for the following reasons. We'd normally expect 1.1257 - // the calling convention to return an VMReg for a stack slot 1.1258 - // completely ignoring any abi reserved area. C2 thinks of that 1.1259 - // abi area as only out_preserve_stack_slots. This does not include 1.1260 - // the area allocated by the C abi to store down integer arguments 1.1261 - // because the java calling convention does not use it. So 1.1262 - // since c2 assumes that there are only out_preserve_stack_slots 1.1263 - // to bias the optoregs (which impacts VMRegs) when actually referencing any actual stack 1.1264 - // location the c calling convention must add in this bias amount 1.1265 - // to make up for the fact that the out_preserve_stack_slots is 1.1266 - // insufficient for C calls. What a mess. I sure hope those 6 1.1267 - // stack words were worth it on every java call! 1.1268 - 1.1269 - // Another way of cleaning this up would be for out_preserve_stack_slots 1.1270 - // to take a parameter to say whether it was C or java calling conventions. 1.1271 - // Then things might look a little better (but not much). 1.1272 - 1.1273 - int mem_parm_offset = i - SPARC_ARGS_IN_REGS_NUM; 1.1274 - if( mem_parm_offset < 0 ) { 1.1275 - return as_oRegister(i)->as_VMReg(); 1.1276 - } else { 1.1277 - int actual_offset = (mem_parm_offset + frame::memory_parameter_word_sp_offset) * VMRegImpl::slots_per_word; 1.1278 - // Now return a biased offset that will be correct when out_preserve_slots is added back in 1.1279 - return VMRegImpl::stack2reg(actual_offset - SharedRuntime::out_preserve_stack_slots()); 1.1280 - } 1.1281 -} 1.1282 -*/ 1.1283 - 1.1284 1.1285 int SharedRuntime::c_calling_convention(const BasicType *sig_bt, 1.1286 VMRegPair *regs, 1.1287 VMRegPair *regs2, 1.1288 int total_args_passed) { 1.1289 - assert(regs2 == NULL, "not needed on MIPS"); 1.1290 -#ifdef aoqi_test 1.1291 -tty->print_cr(" SharedRuntime::%s :%d total_args_passed:%d", __func__, __LINE__, total_args_passed); 1.1292 -#endif 1.1293 - // Return the number of VMReg stack_slots needed for the args. 1.1294 - // This value does not include an abi space (like register window 1.1295 - // save area). 1.1296 - 1.1297 - // The native convention is V8 if !LP64 1.1298 - // The LP64 convention is the V9 convention which is slightly more sane. 1.1299 - 1.1300 - // We return the amount of VMReg stack slots we need to reserve for all 1.1301 - // the arguments NOT counting out_preserve_stack_slots. Since we always 1.1302 - // have space for storing at least 6 registers to memory we start with that. 1.1303 - // See int_stk_helper for a further discussion. 1.1304 - // We return the amount of VMRegImpl stack slots we need to reserve for all 1.1305 - // the arguments NOT counting out_preserve_stack_slots. 1.1306 + assert(regs2 == NULL, "not needed on MIPS"); 1.1307 + // Return the number of VMReg stack_slots needed for the args. 1.1308 + // This value does not include an abi space (like register window 1.1309 + // save area). 1.1310 + 1.1311 + // The native convention is V8 if !LP64 1.1312 + // The LP64 convention is the V9 convention which is slightly more sane. 1.1313 + 1.1314 + // We return the amount of VMReg stack slots we need to reserve for all 1.1315 + // the arguments NOT counting out_preserve_stack_slots. Since we always 1.1316 + // have space for storing at least 6 registers to memory we start with that. 1.1317 + // See int_stk_helper for a further discussion. 1.1318 + // We return the amount of VMRegImpl stack slots we need to reserve for all 1.1319 + // the arguments NOT counting out_preserve_stack_slots. 1.1320 static const Register INT_ArgReg[Argument::n_register_parameters] = { 1.1321 A0, A1, A2, A3, A4, A5, A6, A7 1.1322 }; 1.1323 static const FloatRegister FP_ArgReg[Argument::n_float_register_parameters] = { 1.1324 F12, F13, F14, F15, F16, F17, F18, F19 1.1325 }; 1.1326 - uint args = 0; 1.1327 - uint stk_args = 0; // inc by 2 each time 1.1328 + uint args = 0; 1.1329 + uint stk_args = 0; // inc by 2 each time 1.1330 1.1331 /* Example: 1.1332 --- n java.lang.UNIXProcess::forkAndExec 1.1333 @@ -1389,192 +1070,144 @@ 1.1334 jobject stderr_fd) 1.1335 1.1336 ::c_calling_convention 1.1337 -0: // env <-- a0 1.1338 -1: L // klass/obj <-- t0 => a1 1.1339 -2: [ // prog[] <-- a0 => a2 1.1340 -3: [ // argBlock[] <-- a1 => a3 1.1341 -4: I // argc 1.1342 -5: [ // envBlock[] <-- a3 => a5 1.1343 -6: I // envc 1.1344 -7: [ // dir[] <-- a5 => a7 1.1345 -8: Z // redirectErrorStream a6 => sp[0] 1.1346 -9: L // stdin a7 => sp[8] 1.1347 -10: L // stdout fp[16] => sp[16] 1.1348 -11: L // stderr fp[24] => sp[24] 1.1349 +0: // env <-- a0 1.1350 +1: L // klass/obj <-- t0 => a1 1.1351 +2: [ // prog[] <-- a0 => a2 1.1352 +3: [ // argBlock[] <-- a1 => a3 1.1353 +4: I // argc 1.1354 +5: [ // envBlock[] <-- a3 => a5 1.1355 +6: I // envc 1.1356 +7: [ // dir[] <-- a5 => a7 1.1357 +8: Z // redirectErrorStream a6 => sp[0] 1.1358 +9: L // stdin a7 => sp[8] 1.1359 +10: L // stdout fp[16] => sp[16] 1.1360 +11: L // stderr fp[24] => sp[24] 1.1361 */ 1.1362 - for (int i = 0; i < total_args_passed; i++) { 1.1363 - switch (sig_bt[i]) { 1.1364 - case T_VOID: // Halves of longs and doubles 1.1365 - assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half"); 1.1366 - regs[i].set_bad(); 1.1367 - break; 1.1368 - case T_BOOLEAN: 1.1369 - case T_CHAR: 1.1370 - case T_BYTE: 1.1371 - case T_SHORT: 1.1372 - case T_INT: 1.1373 - if (args < Argument::n_register_parameters) { 1.1374 - regs[i].set1(INT_ArgReg[args++]->as_VMReg()); 1.1375 - } else { 1.1376 - regs[i].set1(VMRegImpl::stack2reg(stk_args)); 1.1377 - stk_args += 2; 1.1378 - } 1.1379 - break; 1.1380 - case T_LONG: 1.1381 - assert(sig_bt[i + 1] == T_VOID, "expecting half"); 1.1382 - // fall through 1.1383 - case T_OBJECT: 1.1384 - case T_ARRAY: 1.1385 - case T_ADDRESS: 1.1386 - case T_METADATA: 1.1387 - if (args < Argument::n_register_parameters) { 1.1388 - regs[i].set2(INT_ArgReg[args++]->as_VMReg()); 1.1389 - } else { 1.1390 - regs[i].set2(VMRegImpl::stack2reg(stk_args)); 1.1391 - stk_args += 2; 1.1392 - } 1.1393 - break; 1.1394 - case T_FLOAT: 1.1395 - if (args < Argument::n_float_register_parameters) { 1.1396 - regs[i].set1(FP_ArgReg[args++]->as_VMReg()); 1.1397 - } else { 1.1398 - regs[i].set1(VMRegImpl::stack2reg(stk_args)); 1.1399 - stk_args += 2; 1.1400 - } 1.1401 - break; 1.1402 - case T_DOUBLE: 1.1403 - assert(sig_bt[i + 1] == T_VOID, "expecting half"); 1.1404 - if (args < Argument::n_float_register_parameters) { 1.1405 - regs[i].set2(FP_ArgReg[args++]->as_VMReg()); 1.1406 - } else { 1.1407 - regs[i].set2(VMRegImpl::stack2reg(stk_args)); 1.1408 - stk_args += 2; 1.1409 - } 1.1410 - break; 1.1411 - default: 1.1412 - ShouldNotReachHere(); 1.1413 - break; 1.1414 - } 1.1415 - } 1.1416 - 1.1417 - return round_to(stk_args, 2); 1.1418 -} 1.1419 -/* 1.1420 -int SharedRuntime::c_calling_convention_jni(const BasicType *sig_bt, 1.1421 - VMRegPair *regs, 1.1422 - int total_args_passed) { 1.1423 -// We return the amount of VMRegImpl stack slots we need to reserve for all 1.1424 -// the arguments NOT counting out_preserve_stack_slots. 1.1425 - bool unalign = 0; 1.1426 - uint stack = 0; // All arguments on stack 1.1427 -#ifdef aoqi_test 1.1428 -tty->print_cr(" SharedRuntime::%s :%d total_args_passed:%d", __func__, __LINE__, total_args_passed); 1.1429 -#endif 1.1430 - 1.1431 - for( int i = 0; i < total_args_passed; i++) { 1.1432 - // From the type and the argument number (count) compute the location 1.1433 - switch( sig_bt[i] ) { 1.1434 + for (int i = 0; i < total_args_passed; i++) { 1.1435 + switch (sig_bt[i]) { 1.1436 + case T_VOID: // Halves of longs and doubles 1.1437 + assert(i != 0 && (sig_bt[i - 1] == T_LONG || sig_bt[i - 1] == T_DOUBLE), "expecting half"); 1.1438 + regs[i].set_bad(); 1.1439 + break; 1.1440 case T_BOOLEAN: 1.1441 case T_CHAR: 1.1442 - case T_FLOAT: 1.1443 case T_BYTE: 1.1444 case T_SHORT: 1.1445 case T_INT: 1.1446 + if (args < Argument::n_register_parameters) { 1.1447 + regs[i].set1(INT_ArgReg[args++]->as_VMReg()); 1.1448 + } else { 1.1449 + regs[i].set1(VMRegImpl::stack2reg(stk_args)); 1.1450 + stk_args += 2; 1.1451 + } 1.1452 + break; 1.1453 + case T_LONG: 1.1454 + assert(sig_bt[i + 1] == T_VOID, "expecting half"); 1.1455 + // fall through 1.1456 case T_OBJECT: 1.1457 case T_ARRAY: 1.1458 case T_ADDRESS: 1.1459 - regs[i].set1(VMRegImpl::stack2reg(stack++)); 1.1460 - unalign = !unalign; 1.1461 + case T_METADATA: 1.1462 + if (args < Argument::n_register_parameters) { 1.1463 + regs[i].set2(INT_ArgReg[args++]->as_VMReg()); 1.1464 + } else { 1.1465 + regs[i].set2(VMRegImpl::stack2reg(stk_args)); 1.1466 + stk_args += 2; 1.1467 + } 1.1468 break; 1.1469 - case T_LONG: 1.1470 - case T_DOUBLE: // The stack numbering is reversed from Java 1.1471 - // Since C arguments do not get reversed, the ordering for 1.1472 - // doubles on the stack must be opposite the Java convention 1.1473 - assert(sig_bt[i+1] == T_VOID, "missing Half" ); 1.1474 - if(unalign){ 1.1475 - stack += 1; 1.1476 - unalign = ! unalign; 1.1477 - } 1.1478 - regs[i].set2(VMRegImpl::stack2reg(stack)); 1.1479 - stack += 2; 1.1480 + case T_FLOAT: 1.1481 + if (args < Argument::n_float_register_parameters) { 1.1482 + regs[i].set1(FP_ArgReg[args++]->as_VMReg()); 1.1483 + } else { 1.1484 + regs[i].set1(VMRegImpl::stack2reg(stk_args)); 1.1485 + stk_args += 2; 1.1486 + } 1.1487 break; 1.1488 - case T_VOID: regs[i].set_bad(); break; 1.1489 + case T_DOUBLE: 1.1490 + assert(sig_bt[i + 1] == T_VOID, "expecting half"); 1.1491 + if (args < Argument::n_float_register_parameters) { 1.1492 + regs[i].set2(FP_ArgReg[args++]->as_VMReg()); 1.1493 + } else { 1.1494 + regs[i].set2(VMRegImpl::stack2reg(stk_args)); 1.1495 + stk_args += 2; 1.1496 + } 1.1497 + break; 1.1498 default: 1.1499 ShouldNotReachHere(); 1.1500 break; 1.1501 } 1.1502 } 1.1503 - return stack; 1.1504 + 1.1505 + return round_to(stk_args, 2); 1.1506 } 1.1507 -*/ 1.1508 1.1509 // --------------------------------------------------------------------------- 1.1510 void SharedRuntime::save_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) { 1.1511 - // We always ignore the frame_slots arg and just use the space just below frame pointer 1.1512 - // which by this time is free to use 1.1513 - switch (ret_type) { 1.1514 - case T_FLOAT: 1.1515 - __ swc1(FSF, FP, -wordSize); 1.1516 - break; 1.1517 - case T_DOUBLE: 1.1518 - __ sdc1(FSF, FP, -wordSize ); 1.1519 - break; 1.1520 - case T_VOID: break; 1.1521 - case T_LONG: 1.1522 - __ sd(V0, FP, -wordSize); 1.1523 - break; 1.1524 - case T_OBJECT: 1.1525 - case T_ARRAY: 1.1526 - __ sd(V0, FP, -wordSize); 1.1527 - break; 1.1528 - default: { 1.1529 - __ sw(V0, FP, -wordSize); 1.1530 - } 1.1531 - } 1.1532 + // We always ignore the frame_slots arg and just use the space just below frame pointer 1.1533 + // which by this time is free to use 1.1534 + switch (ret_type) { 1.1535 + case T_FLOAT: 1.1536 + __ swc1(FSF, FP, -wordSize); 1.1537 + break; 1.1538 + case T_DOUBLE: 1.1539 + __ sdc1(FSF, FP, -wordSize ); 1.1540 + break; 1.1541 + case T_VOID: break; 1.1542 + case T_LONG: 1.1543 + __ sd(V0, FP, -wordSize); 1.1544 + break; 1.1545 + case T_OBJECT: 1.1546 + case T_ARRAY: 1.1547 + __ sd(V0, FP, -wordSize); 1.1548 + break; 1.1549 + default: { 1.1550 + __ sw(V0, FP, -wordSize); 1.1551 + } 1.1552 + } 1.1553 } 1.1554 1.1555 void SharedRuntime::restore_native_result(MacroAssembler *masm, BasicType ret_type, int frame_slots) { 1.1556 - // We always ignore the frame_slots arg and just use the space just below frame pointer 1.1557 - // which by this time is free to use 1.1558 - switch (ret_type) { 1.1559 - case T_FLOAT: 1.1560 - __ lwc1(FSF, FP, -wordSize); 1.1561 - break; 1.1562 - case T_DOUBLE: 1.1563 - __ ldc1(FSF, FP, -wordSize ); 1.1564 - break; 1.1565 - case T_LONG: 1.1566 - __ ld(V0, FP, -wordSize); 1.1567 - break; 1.1568 - case T_VOID: break; 1.1569 - case T_OBJECT: 1.1570 - case T_ARRAY: 1.1571 - __ ld(V0, FP, -wordSize); 1.1572 - break; 1.1573 - default: { 1.1574 - __ lw(V0, FP, -wordSize); 1.1575 - } 1.1576 - } 1.1577 + // We always ignore the frame_slots arg and just use the space just below frame pointer 1.1578 + // which by this time is free to use 1.1579 + switch (ret_type) { 1.1580 + case T_FLOAT: 1.1581 + __ lwc1(FSF, FP, -wordSize); 1.1582 + break; 1.1583 + case T_DOUBLE: 1.1584 + __ ldc1(FSF, FP, -wordSize ); 1.1585 + break; 1.1586 + case T_LONG: 1.1587 + __ ld(V0, FP, -wordSize); 1.1588 + break; 1.1589 + case T_VOID: break; 1.1590 + case T_OBJECT: 1.1591 + case T_ARRAY: 1.1592 + __ ld(V0, FP, -wordSize); 1.1593 + break; 1.1594 + default: { 1.1595 + __ lw(V0, FP, -wordSize); 1.1596 + } 1.1597 + } 1.1598 } 1.1599 1.1600 static void save_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { 1.1601 - for ( int i = first_arg ; i < arg_count ; i++ ) { 1.1602 - if (args[i].first()->is_Register()) { 1.1603 - __ push(args[i].first()->as_Register()); 1.1604 - } else if (args[i].first()->is_FloatRegister()) { 1.1605 - __ push(args[i].first()->as_FloatRegister()); 1.1606 - } 1.1607 + for ( int i = first_arg ; i < arg_count ; i++ ) { 1.1608 + if (args[i].first()->is_Register()) { 1.1609 + __ push(args[i].first()->as_Register()); 1.1610 + } else if (args[i].first()->is_FloatRegister()) { 1.1611 + __ push(args[i].first()->as_FloatRegister()); 1.1612 } 1.1613 + } 1.1614 } 1.1615 1.1616 static void restore_args(MacroAssembler *masm, int arg_count, int first_arg, VMRegPair *args) { 1.1617 - for ( int i = arg_count - 1 ; i >= first_arg ; i-- ) { 1.1618 - if (args[i].first()->is_Register()) { 1.1619 - __ pop(args[i].first()->as_Register()); 1.1620 - } else if (args[i].first()->is_FloatRegister()) { 1.1621 - __ pop(args[i].first()->as_FloatRegister()); 1.1622 - } 1.1623 + for ( int i = arg_count - 1 ; i >= first_arg ; i-- ) { 1.1624 + if (args[i].first()->is_Register()) { 1.1625 + __ pop(args[i].first()->as_Register()); 1.1626 + } else if (args[i].first()->is_FloatRegister()) { 1.1627 + __ pop(args[i].first()->as_FloatRegister()); 1.1628 } 1.1629 + } 1.1630 } 1.1631 1.1632 // A simple move of integer like type 1.1633 @@ -1582,46 +1215,21 @@ 1.1634 if (src.first()->is_stack()) { 1.1635 if (dst.first()->is_stack()) { 1.1636 // stack to stack 1.1637 - __ lw(AT, FP, reg2offset_in(src.first())); 1.1638 - __ sd(AT,SP, reg2offset_out(dst.first())); 1.1639 + __ lw(AT, FP, reg2offset_in(src.first())); 1.1640 + __ sd(AT,SP, reg2offset_out(dst.first())); 1.1641 } else { 1.1642 // stack to reg 1.1643 - //__ ld(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register()); 1.1644 - __ lw(dst.first()->as_Register(), FP, reg2offset_in(src.first())); 1.1645 + __ lw(dst.first()->as_Register(), FP, reg2offset_in(src.first())); 1.1646 } 1.1647 } else if (dst.first()->is_stack()) { 1.1648 // reg to stack 1.1649 - __ sd(src.first()->as_Register(), SP, reg2offset_out(dst.first())); 1.1650 + __ sd(src.first()->as_Register(), SP, reg2offset_out(dst.first())); 1.1651 } else { 1.1652 - //__ mov(src.first()->as_Register(), dst.first()->as_Register()); 1.1653 - if (dst.first() != src.first()){ 1.1654 - __ move(dst.first()->as_Register(), src.first()->as_Register()); // fujie error:dst.first() 1.1655 - } 1.1656 + if (dst.first() != src.first()){ 1.1657 + __ move(dst.first()->as_Register(), src.first()->as_Register()); // fujie error:dst.first() 1.1658 + } 1.1659 } 1.1660 } 1.1661 -/* 1.1662 -// On 64 bit we will store integer like items to the stack as 1.1663 -// 64 bits items (sparc abi) even though java would only store 1.1664 -// 32bits for a parameter. On 32bit it will simply be 32 bits 1.1665 -// So this routine will do 32->32 on 32bit and 32->64 on 64bit 1.1666 -static void move32_64(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { 1.1667 - if (src.first()->is_stack()) { 1.1668 - if (dst.first()->is_stack()) { 1.1669 - // stack to stack 1.1670 - __ ld(FP, reg2offset(src.first()) + STACK_BIAS, L5); 1.1671 - __ st_ptr(L5, SP, reg2offset(dst.first()) + STACK_BIAS); 1.1672 - } else { 1.1673 - // stack to reg 1.1674 - __ ld(FP, reg2offset(src.first()) + STACK_BIAS, dst.first()->as_Register()); 1.1675 - } 1.1676 - } else if (dst.first()->is_stack()) { 1.1677 - // reg to stack 1.1678 - __ st_ptr(src.first()->as_Register(), SP, reg2offset(dst.first()) + STACK_BIAS); 1.1679 - } else { 1.1680 - __ mov(src.first()->as_Register(), dst.first()->as_Register()); 1.1681 - } 1.1682 -} 1.1683 -*/ 1.1684 1.1685 // An oop arg. Must pass a handle not the oop itself 1.1686 static void object_move(MacroAssembler* masm, 1.1687 @@ -1635,181 +1243,133 @@ 1.1688 1.1689 // must pass a handle. First figure out the location we use as a handle 1.1690 1.1691 - //FIXME, for mips, dst can be register 1.1692 - if (src.first()->is_stack()) { 1.1693 - // Oop is already on the stack as an argument 1.1694 - Register rHandle = V0; 1.1695 - Label nil; 1.1696 - //__ xorl(rHandle, rHandle); 1.1697 - __ xorr(rHandle, rHandle, rHandle); 1.1698 - //__ cmpl(Address(ebp, reg2offset_in(src.first())), NULL_WORD); 1.1699 - __ ld(AT, FP, reg2offset_in(src.first())); 1.1700 - //__ jcc(Assembler::equal, nil); 1.1701 - __ beq(AT,R0, nil); 1.1702 - __ delayed()->nop(); 1.1703 - // __ leal(rHandle, Address(ebp, reg2offset_in(src.first()))); 1.1704 - __ lea(rHandle, Address(FP, reg2offset_in(src.first()))); 1.1705 - __ bind(nil); 1.1706 - //__ movl(Address(esp, reg2offset_out(dst.first())), rHandle); 1.1707 - if(dst.first()->is_stack())__ sd( rHandle, SP, reg2offset_out(dst.first())); 1.1708 - else __ move( (dst.first())->as_Register(),rHandle); 1.1709 - //if dst is register 1.1710 - //FIXME, do mips need out preserve stack slots? 1.1711 - int offset_in_older_frame = src.first()->reg2stack() 1.1712 - + SharedRuntime::out_preserve_stack_slots(); 1.1713 - map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots)); 1.1714 - if (is_receiver) { 1.1715 - *receiver_offset = (offset_in_older_frame 1.1716 - + framesize_in_slots) * VMRegImpl::stack_slot_size; 1.1717 - } 1.1718 - } else { 1.1719 - // Oop is in an a register we must store it to the space we reserve 1.1720 - // on the stack for oop_handles 1.1721 - const Register rOop = src.first()->as_Register(); 1.1722 - assert( (rOop->encoding() >= A0->encoding()) && (rOop->encoding() <= T0->encoding()),"wrong register"); 1.1723 - // const Register rHandle = eax; 1.1724 - const Register rHandle = V0; 1.1725 - //Important: refer to java_calling_convertion 1.1726 - int oop_slot = (rOop->encoding() - A0->encoding()) * VMRegImpl::slots_per_word + oop_handle_offset; 1.1727 - int offset = oop_slot*VMRegImpl::stack_slot_size; 1.1728 - Label skip; 1.1729 - // __ movl(Address(esp, offset), rOop); 1.1730 - __ sd( rOop , SP, offset ); 1.1731 - map->set_oop(VMRegImpl::stack2reg(oop_slot)); 1.1732 - // __ xorl(rHandle, rHandle); 1.1733 - __ xorr( rHandle, rHandle, rHandle); 1.1734 - //__ cmpl(rOop, NULL_WORD); 1.1735 - // __ jcc(Assembler::equal, skip); 1.1736 - __ beq(rOop, R0, skip); 1.1737 - __ delayed()->nop(); 1.1738 - // __ leal(rHandle, Address(esp, offset)); 1.1739 - __ lea(rHandle, Address(SP, offset)); 1.1740 - __ bind(skip); 1.1741 - // Store the handle parameter 1.1742 - //__ movl(Address(esp, reg2offset_out(dst.first())), rHandle); 1.1743 - if(dst.first()->is_stack())__ sd( rHandle, SP, reg2offset_out(dst.first())); 1.1744 - else __ move((dst.first())->as_Register(), rHandle); 1.1745 - //if dst is register 1.1746 - 1.1747 - if (is_receiver) { 1.1748 - *receiver_offset = offset; 1.1749 - } 1.1750 - } 1.1751 + //FIXME, for mips, dst can be register 1.1752 + if (src.first()->is_stack()) { 1.1753 + // Oop is already on the stack as an argument 1.1754 + Register rHandle = V0; 1.1755 + Label nil; 1.1756 + __ xorr(rHandle, rHandle, rHandle); 1.1757 + __ ld(AT, FP, reg2offset_in(src.first())); 1.1758 + __ beq(AT,R0, nil); 1.1759 + __ delayed()->nop(); 1.1760 + __ lea(rHandle, Address(FP, reg2offset_in(src.first()))); 1.1761 + __ bind(nil); 1.1762 + if(dst.first()->is_stack())__ sd( rHandle, SP, reg2offset_out(dst.first())); 1.1763 + else __ move( (dst.first())->as_Register(),rHandle); 1.1764 + //if dst is register 1.1765 + //FIXME, do mips need out preserve stack slots? 1.1766 + int offset_in_older_frame = src.first()->reg2stack() 1.1767 + + SharedRuntime::out_preserve_stack_slots(); 1.1768 + map->set_oop(VMRegImpl::stack2reg(offset_in_older_frame + framesize_in_slots)); 1.1769 + if (is_receiver) { 1.1770 + *receiver_offset = (offset_in_older_frame 1.1771 + + framesize_in_slots) * VMRegImpl::stack_slot_size; 1.1772 + } 1.1773 + } else { 1.1774 + // Oop is in an a register we must store it to the space we reserve 1.1775 + // on the stack for oop_handles 1.1776 + const Register rOop = src.first()->as_Register(); 1.1777 + assert( (rOop->encoding() >= A0->encoding()) && (rOop->encoding() <= T0->encoding()),"wrong register"); 1.1778 + const Register rHandle = V0; 1.1779 + //Important: refer to java_calling_convertion 1.1780 + int oop_slot = (rOop->encoding() - A0->encoding()) * VMRegImpl::slots_per_word + oop_handle_offset; 1.1781 + int offset = oop_slot*VMRegImpl::stack_slot_size; 1.1782 + Label skip; 1.1783 + __ sd( rOop , SP, offset ); 1.1784 + map->set_oop(VMRegImpl::stack2reg(oop_slot)); 1.1785 + __ xorr( rHandle, rHandle, rHandle); 1.1786 + __ beq(rOop, R0, skip); 1.1787 + __ delayed()->nop(); 1.1788 + __ lea(rHandle, Address(SP, offset)); 1.1789 + __ bind(skip); 1.1790 + // Store the handle parameter 1.1791 + if(dst.first()->is_stack())__ sd( rHandle, SP, reg2offset_out(dst.first())); 1.1792 + else __ move((dst.first())->as_Register(), rHandle); 1.1793 + //if dst is register 1.1794 + 1.1795 + if (is_receiver) { 1.1796 + *receiver_offset = offset; 1.1797 + } 1.1798 + } 1.1799 } 1.1800 1.1801 // A float arg may have to do float reg int reg conversion 1.1802 static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { 1.1803 assert(!src.second()->is_valid() && !dst.second()->is_valid(), "bad float_move"); 1.1804 1.1805 - if (src.first()->is_stack()) { 1.1806 - if(dst.first()->is_stack()){ 1.1807 - // __ movl(eax, Address(ebp, reg2offset_in(src.first()))); 1.1808 - __ lwc1(F12 , FP, reg2offset_in(src.first())); 1.1809 - // __ movl(Address(esp, reg2offset_out(dst.first())), eax); 1.1810 - __ swc1(F12 ,SP, reg2offset_out(dst.first())); 1.1811 - } 1.1812 - else 1.1813 - __ lwc1( dst.first()->as_FloatRegister(), FP, reg2offset_in(src.first())); 1.1814 - } else { 1.1815 - // reg to stack 1.1816 - // __ movss(Address(esp, reg2offset_out(dst.first())), 1.1817 - // src.first()->as_XMMRegister()); 1.1818 - // __ movl(Address(esp, reg2offset_out(dst.first())), eax); 1.1819 - if(dst.first()->is_stack()) 1.1820 - __ swc1( src.first()->as_FloatRegister(),SP, reg2offset_out(dst.first())); 1.1821 - else 1.1822 - __ mov_s( dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); 1.1823 - } 1.1824 + if (src.first()->is_stack()) { 1.1825 + if (dst.first()->is_stack()) { 1.1826 + __ lwc1(F12 , FP, reg2offset_in(src.first())); 1.1827 + __ swc1(F12 ,SP, reg2offset_out(dst.first())); 1.1828 + } 1.1829 + else 1.1830 + __ lwc1( dst.first()->as_FloatRegister(), FP, reg2offset_in(src.first())); 1.1831 + } else { 1.1832 + // reg to stack 1.1833 + if(dst.first()->is_stack()) 1.1834 + __ swc1( src.first()->as_FloatRegister(),SP, reg2offset_out(dst.first())); 1.1835 + else 1.1836 + __ mov_s( dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); 1.1837 + } 1.1838 } 1.1839 -/* 1.1840 -static void split_long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { 1.1841 - VMRegPair src_lo(src.first()); 1.1842 - VMRegPair src_hi(src.second()); 1.1843 - VMRegPair dst_lo(dst.first()); 1.1844 - VMRegPair dst_hi(dst.second()); 1.1845 - simple_move32(masm, src_lo, dst_lo); 1.1846 - simple_move32(masm, src_hi, dst_hi); 1.1847 -} 1.1848 -*/ 1.1849 + 1.1850 // A long move 1.1851 static void long_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { 1.1852 1.1853 - // The only legal possibility for a long_move VMRegPair is: 1.1854 - // 1: two stack slots (possibly unaligned) 1.1855 - // as neither the java or C calling convention will use registers 1.1856 - // for longs. 1.1857 - 1.1858 - if (src.first()->is_stack()) { 1.1859 - assert(src.second()->is_stack() && dst.second()->is_stack(), "must be all stack"); 1.1860 - // __ movl(eax, Address(ebp, reg2offset_in(src.first()))); 1.1861 - if( dst.first()->is_stack()){ 1.1862 - __ ld(AT, FP, reg2offset_in(src.first())); 1.1863 - // __ movl(ebx, address(ebp, reg2offset_in(src.second()))); 1.1864 - //__ lw(V0, FP, reg2offset_in(src.second())); 1.1865 - // __ movl(address(esp, reg2offset_out(dst.first())), eax); 1.1866 - __ sd(AT, SP, reg2offset_out(dst.first())); 1.1867 - // __ movl(address(esp, reg2offset_out(dst.second())), ebx); 1.1868 - //__ sw(V0, SP, reg2offset_out(dst.second())); 1.1869 - } else{ 1.1870 - __ ld( (dst.first())->as_Register() , FP, reg2offset_in(src.first())); 1.1871 - //__ lw( (dst.second())->as_Register(), FP, reg2offset_in(src.second())); 1.1872 - } 1.1873 - } else { 1.1874 - if( dst.first()->is_stack()){ 1.1875 - __ sd( (src.first())->as_Register(), SP, reg2offset_out(dst.first())); 1.1876 - //__ sw( (src.second())->as_Register(), SP, reg2offset_out(dst.second())); 1.1877 - } else{ 1.1878 - __ move( (dst.first())->as_Register() , (src.first())->as_Register()); 1.1879 - //__ move( (dst.second())->as_Register(), (src.second())->as_Register()); 1.1880 - } 1.1881 - } 1.1882 + // The only legal possibility for a long_move VMRegPair is: 1.1883 + // 1: two stack slots (possibly unaligned) 1.1884 + // as neither the java or C calling convention will use registers 1.1885 + // for longs. 1.1886 + 1.1887 + if (src.first()->is_stack()) { 1.1888 + assert(src.second()->is_stack() && dst.second()->is_stack(), "must be all stack"); 1.1889 + if( dst.first()->is_stack()){ 1.1890 + __ ld(AT, FP, reg2offset_in(src.first())); 1.1891 + __ sd(AT, SP, reg2offset_out(dst.first())); 1.1892 + } else { 1.1893 + __ ld( (dst.first())->as_Register() , FP, reg2offset_in(src.first())); 1.1894 + } 1.1895 + } else { 1.1896 + if( dst.first()->is_stack()){ 1.1897 + __ sd( (src.first())->as_Register(), SP, reg2offset_out(dst.first())); 1.1898 + } else{ 1.1899 + __ move( (dst.first())->as_Register() , (src.first())->as_Register()); 1.1900 + } 1.1901 + } 1.1902 } 1.1903 1.1904 // A double move 1.1905 static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { 1.1906 1.1907 - // The only legal possibilities for a double_move VMRegPair are: 1.1908 - // The painful thing here is that like long_move a VMRegPair might be 1.1909 - 1.1910 - // Because of the calling convention we know that src is either 1.1911 - // 1: a single physical register (xmm registers only) 1.1912 - // 2: two stack slots (possibly unaligned) 1.1913 - // dst can only be a pair of stack slots. 1.1914 - 1.1915 - // assert(dst.first()->is_stack() && (src.first()->is_XMMRegister() || 1.1916 - // src.first()->is_stack()), "bad args"); 1.1917 - // assert(dst.first()->is_stack() || src.first()->is_stack()), "bad args"); 1.1918 - 1.1919 - if (src.first()->is_stack()) { 1.1920 - // source is all stack 1.1921 - // __ movl(eax, Address(ebp, reg2offset_in(src.first()))); 1.1922 - if( dst.first()->is_stack()){ 1.1923 - __ ldc1(F12, FP, reg2offset_in(src.first())); 1.1924 - //__ movl(ebx, Address(ebp, reg2offset_in(src.second()))); 1.1925 - //__ lwc1(F14, FP, reg2offset_in(src.second())); 1.1926 - 1.1927 - // __ movl(Address(esp, reg2offset_out(dst.first())), eax); 1.1928 - __ sdc1(F12, SP, reg2offset_out(dst.first())); 1.1929 - // __ movl(Address(esp, reg2offset_out(dst.second())), ebx); 1.1930 - //__ swc1(F14, SP, reg2offset_out(dst.second())); 1.1931 - } else{ 1.1932 - __ ldc1( (dst.first())->as_FloatRegister(), FP, reg2offset_in(src.first())); 1.1933 - //__ lwc1( (dst.second())->as_FloatRegister(), FP, reg2offset_in(src.second())); 1.1934 - } 1.1935 - 1.1936 - } else { 1.1937 - // reg to stack 1.1938 - // No worries about stack alignment 1.1939 - // __ movsd(Address(esp, reg2offset_out(dst.first())), src.first()->as_XMMRegister()); 1.1940 - if( dst.first()->is_stack()){ 1.1941 - __ sdc1( src.first()->as_FloatRegister(),SP, reg2offset_out(dst.first())); 1.1942 - //__ swc1( src.second()->as_FloatRegister(),SP, reg2offset_out(dst.second())); 1.1943 - } 1.1944 - else 1.1945 - __ mov_d( dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); 1.1946 - //__ mov_s( dst.second()->as_FloatRegister(), src.second()->as_FloatRegister()); 1.1947 - 1.1948 - } 1.1949 + // The only legal possibilities for a double_move VMRegPair are: 1.1950 + // The painful thing here is that like long_move a VMRegPair might be 1.1951 + 1.1952 + // Because of the calling convention we know that src is either 1.1953 + // 1: a single physical register (xmm registers only) 1.1954 + // 2: two stack slots (possibly unaligned) 1.1955 + // dst can only be a pair of stack slots. 1.1956 + 1.1957 + 1.1958 + if (src.first()->is_stack()) { 1.1959 + // source is all stack 1.1960 + if( dst.first()->is_stack()){ 1.1961 + __ ldc1(F12, FP, reg2offset_in(src.first())); 1.1962 + 1.1963 + __ sdc1(F12, SP, reg2offset_out(dst.first())); 1.1964 + } else{ 1.1965 + __ ldc1( (dst.first())->as_FloatRegister(), FP, reg2offset_in(src.first())); 1.1966 + } 1.1967 + 1.1968 + } else { 1.1969 + // reg to stack 1.1970 + // No worries about stack alignment 1.1971 + if( dst.first()->is_stack()){ 1.1972 + __ sdc1( src.first()->as_FloatRegister(),SP, reg2offset_out(dst.first())); 1.1973 + } 1.1974 + else 1.1975 + __ mov_d( dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); 1.1976 + 1.1977 + } 1.1978 } 1.1979 1.1980 static void verify_oop_args(MacroAssembler* masm, 1.1981 @@ -1824,7 +1384,6 @@ 1.1982 VMReg r = regs[i].first(); 1.1983 assert(r->is_valid(), "bad oop arg"); 1.1984 if (r->is_stack()) { 1.1985 -// __ movptr(temp_reg, Address(rsp, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); 1.1986 __ ld(temp_reg, Address(SP, r->reg2stack() * VMRegImpl::stack_slot_size + wordSize)); 1.1987 __ verify_oop(temp_reg); 1.1988 } else { 1.1989 @@ -1850,7 +1409,6 @@ 1.1990 int ref_kind = MethodHandles::signature_polymorphic_intrinsic_ref_kind(iid); 1.1991 if (ref_kind != 0) { 1.1992 member_arg_pos = method->size_of_parameters() - 1; // trailing MemberName argument 1.1993 -// member_reg = rbx; // known to be free at this point 1.1994 member_reg = S3; // known to be free at this point 1.1995 has_receiver = MethodHandles::ref_kind_has_receiver(ref_kind); 1.1996 } else if (iid == vmIntrinsics::_invokeBasic) { 1.1997 @@ -1882,7 +1440,6 @@ 1.1998 // pass the receiver oop in a register. If this is not true on some 1.1999 // platform, pick a temp and load the receiver from stack. 1.2000 fatal("receiver always in a register"); 1.2001 -// receiver_reg = j_rarg0; // known to be free at this point 1.2002 receiver_reg = SSR; // known to be free at this point 1.2003 __ ld(receiver_reg, Address(SP, r->reg2stack() * VMRegImpl::stack_slot_size)); 1.2004 } else { 1.2005 @@ -1905,20 +1462,17 @@ 1.2006 nmethod *SharedRuntime::generate_native_wrapper(MacroAssembler* masm, 1.2007 methodHandle method, 1.2008 int compile_id, 1.2009 - BasicType *in_sig_bt, 1.2010 - VMRegPair *in_regs, 1.2011 + BasicType* in_sig_bt, 1.2012 + VMRegPair* in_regs, 1.2013 BasicType ret_type) { 1.2014 - 1.2015 if (method->is_method_handle_intrinsic()) { 1.2016 vmIntrinsics::ID iid = method->intrinsic_id(); 1.2017 intptr_t start = (intptr_t)__ pc(); 1.2018 int vep_offset = ((intptr_t)__ pc()) - start; 1.2019 - 1.2020 gen_special_dispatch(masm, 1.2021 method, 1.2022 in_sig_bt, 1.2023 in_regs); 1.2024 - 1.2025 int frame_complete = ((intptr_t)__ pc()) - start; // not complete, period 1.2026 __ flush(); 1.2027 int stack_slots = SharedRuntime::out_preserve_stack_slots(); // no out slots at all, actually 1.2028 @@ -1947,11 +1501,11 @@ 1.2029 // An OopMap for lock (and class if static), and one for the VM call itself 1.2030 OopMapSet *oop_maps = new OopMapSet(); 1.2031 1.2032 - // We have received a description of where all the java arg are located 1.2033 - // on entry to the wrapper. We need to convert these args to where 1.2034 - // the jni function will expect them. To figure out where they go 1.2035 - // we convert the java signature to a C signature by inserting 1.2036 - // the hidden arguments as arg[0] and possibly arg[1] (static method) 1.2037 + // We have received a description of where all the java arg are located 1.2038 + // on entry to the wrapper. We need to convert these args to where 1.2039 + // the jni function will expect them. To figure out where they go 1.2040 + // we convert the java signature to a C signature by inserting 1.2041 + // the hidden arguments as arg[0] and possibly arg[1] (static method) 1.2042 1.2043 const int total_in_args = method->size_of_parameters(); 1.2044 int total_c_args = total_in_args; 1.2045 @@ -1968,8 +1522,8 @@ 1.2046 } 1.2047 } 1.2048 1.2049 - BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); 1.2050 - VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); 1.2051 + BasicType* out_sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_c_args); 1.2052 + VMRegPair* out_regs = NEW_RESOURCE_ARRAY(VMRegPair, total_c_args); 1.2053 BasicType* in_elem_bt = NULL; 1.2054 1.2055 int argc = 0; 1.2056 @@ -2024,7 +1578,7 @@ 1.2057 // 1.2058 int out_arg_slots; 1.2059 //out_arg_slots = c_calling_convention(out_sig_bt, out_regs, total_c_args); 1.2060 - out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args); 1.2061 + out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args); 1.2062 1.2063 // Compute framesize for the wrapper. We need to handlize all oops in 1.2064 // registers. We must create space for them here that is disjoint from 1.2065 @@ -2079,16 +1633,14 @@ 1.2066 } 1.2067 1.2068 int oop_handle_offset = stack_slots; 1.2069 -// stack_slots += 9*VMRegImpl::slots_per_word; // T0, A0 ~ A7 1.2070 stack_slots += total_save_slots; 1.2071 1.2072 // Now any space we need for handlizing a klass if static method 1.2073 1.2074 - int klass_slot_offset = 0; 1.2075 - int klass_offset = -1; 1.2076 - int lock_slot_offset = 0; 1.2077 - bool is_static = false; 1.2078 - //int oop_temp_slot_offset = 0; 1.2079 + int klass_slot_offset = 0; 1.2080 + int klass_offset = -1; 1.2081 + int lock_slot_offset = 0; 1.2082 + bool is_static = false; 1.2083 1.2084 if (method->is_static()) { 1.2085 klass_slot_offset = stack_slots; 1.2086 @@ -2105,9 +1657,8 @@ 1.2087 } 1.2088 1.2089 // Now a place to save return value or as a temporary for any gpr -> fpr moves 1.2090 - // + 2 for return address (which we own) and saved ebp 1.2091 - //stack_slots += 2; 1.2092 - stack_slots += 2 + 9 * VMRegImpl::slots_per_word; // (T0, A0, A1, A2, A3, A4, A5, A6, A7) 1.2093 + // + 2 for return address (which we own) and saved ebp 1.2094 + stack_slots += 2 + 9 * VMRegImpl::slots_per_word; // (T0, A0, A1, A2, A3, A4, A5, A6, A7) 1.2095 1.2096 // Ok The space we have allocated will look like: 1.2097 // 1.2098 @@ -2140,141 +1691,137 @@ 1.2099 1.2100 int stack_size = stack_slots * VMRegImpl::stack_slot_size; 1.2101 1.2102 - intptr_t start = (intptr_t)__ pc(); 1.2103 - 1.2104 - 1.2105 - 1.2106 - // First thing make an ic check to see if we should even be here 1.2107 - address ic_miss = SharedRuntime::get_ic_miss_stub(); 1.2108 - 1.2109 - // We are free to use all registers as temps without saving them and 1.2110 - // restoring them except ebp. ebp is the only callee save register 1.2111 - // as far as the interpreter and the compiler(s) are concerned. 1.2112 + intptr_t start = (intptr_t)__ pc(); 1.2113 + 1.2114 + 1.2115 + 1.2116 + // First thing make an ic check to see if we should even be here 1.2117 + address ic_miss = SharedRuntime::get_ic_miss_stub(); 1.2118 + 1.2119 + // We are free to use all registers as temps without saving them and 1.2120 + // restoring them except ebp. ebp is the only callee save register 1.2121 + // as far as the interpreter and the compiler(s) are concerned. 1.2122 1.2123 //refer to register_mips.hpp:IC_Klass 1.2124 - const Register ic_reg = T1; 1.2125 - const Register receiver = T0; 1.2126 - Label hit; 1.2127 - Label exception_pending; 1.2128 - 1.2129 - __ verify_oop(receiver); 1.2130 - //__ lw(AT, receiver, oopDesc::klass_offset_in_bytes()); 1.2131 - //add for compressedoops 1.2132 - __ load_klass(T9, receiver); 1.2133 - __ beq(T9, ic_reg, hit); 1.2134 - __ delayed()->nop(); 1.2135 - __ jmp(ic_miss, relocInfo::runtime_call_type); 1.2136 - __ delayed()->nop(); 1.2137 - // verified entry must be aligned for code patching. 1.2138 - // and the first 5 bytes must be in the same cache line 1.2139 - // if we align at 8 then we will be sure 5 bytes are in the same line 1.2140 - __ align(8); 1.2141 - 1.2142 - __ bind(hit); 1.2143 - 1.2144 - 1.2145 - int vep_offset = ((intptr_t)__ pc()) - start; 1.2146 + const Register ic_reg = T1; 1.2147 + const Register receiver = T0; 1.2148 + 1.2149 + Label hit; 1.2150 + Label exception_pending; 1.2151 + 1.2152 + __ verify_oop(receiver); 1.2153 + //add for compressedoops 1.2154 + __ load_klass(T9, receiver); 1.2155 + __ beq(T9, ic_reg, hit); 1.2156 + __ delayed()->nop(); 1.2157 + __ jmp(ic_miss, relocInfo::runtime_call_type); 1.2158 + __ delayed()->nop(); 1.2159 + // verified entry must be aligned for code patching. 1.2160 + // and the first 5 bytes must be in the same cache line 1.2161 + // if we align at 8 then we will be sure 5 bytes are in the same line 1.2162 + __ align(8); 1.2163 + 1.2164 + __ bind(hit); 1.2165 + 1.2166 + 1.2167 + int vep_offset = ((intptr_t)__ pc()) - start; 1.2168 #ifdef COMPILER1 1.2169 - if (InlineObjectHash && method->intrinsic_id() == vmIntrinsics::_hashCode) { 1.2170 - // Object.hashCode can pull the hashCode from the header word 1.2171 - // instead of doing a full VM transition once it's been computed. 1.2172 - // Since hashCode is usually polymorphic at call sites we can't do 1.2173 - // this optimization at the call site without a lot of work. 1.2174 - Label slowCase; 1.2175 - Register receiver = T0; 1.2176 - Register result = V0; 1.2177 - __ ld ( result, receiver, oopDesc::mark_offset_in_bytes()); 1.2178 - // check if locked 1.2179 - __ andi(AT, result, markOopDesc::unlocked_value); 1.2180 - __ beq(AT, R0, slowCase); 1.2181 - __ delayed()->nop(); 1.2182 - if (UseBiasedLocking) { 1.2183 - // Check if biased and fall through to runtime if so 1.2184 - __ andi (AT, result, markOopDesc::biased_lock_bit_in_place); 1.2185 - __ bne(AT,R0, slowCase); 1.2186 - __ delayed()->nop(); 1.2187 - } 1.2188 - // get hash 1.2189 - __ li(AT, markOopDesc::hash_mask_in_place); 1.2190 - __ andr (AT, result, AT); 1.2191 - // test if hashCode exists 1.2192 - __ beq (AT, R0, slowCase); 1.2193 - __ delayed()->nop(); 1.2194 - __ shr(result, markOopDesc::hash_shift); 1.2195 - __ jr(RA); 1.2196 - __ delayed()->nop(); 1.2197 - __ bind (slowCase); 1.2198 - } 1.2199 + if (InlineObjectHash && method->intrinsic_id() == vmIntrinsics::_hashCode) { 1.2200 + // Object.hashCode can pull the hashCode from the header word 1.2201 + // instead of doing a full VM transition once it's been computed. 1.2202 + // Since hashCode is usually polymorphic at call sites we can't do 1.2203 + // this optimization at the call site without a lot of work. 1.2204 + Label slowCase; 1.2205 + Register receiver = T0; 1.2206 + Register result = V0; 1.2207 + __ ld ( result, receiver, oopDesc::mark_offset_in_bytes()); 1.2208 + // check if locked 1.2209 + __ andi(AT, result, markOopDesc::unlocked_value); 1.2210 + __ beq(AT, R0, slowCase); 1.2211 + __ delayed()->nop(); 1.2212 + if (UseBiasedLocking) { 1.2213 + // Check if biased and fall through to runtime if so 1.2214 + __ andi (AT, result, markOopDesc::biased_lock_bit_in_place); 1.2215 + __ bne(AT,R0, slowCase); 1.2216 + __ delayed()->nop(); 1.2217 + } 1.2218 + // get hash 1.2219 + __ li(AT, markOopDesc::hash_mask_in_place); 1.2220 + __ andr (AT, result, AT); 1.2221 + // test if hashCode exists 1.2222 + __ beq (AT, R0, slowCase); 1.2223 + __ delayed()->nop(); 1.2224 + __ shr(result, markOopDesc::hash_shift); 1.2225 + __ jr(RA); 1.2226 + __ delayed()->nop(); 1.2227 + __ bind (slowCase); 1.2228 + } 1.2229 #endif // COMPILER1 1.2230 1.2231 - // The instruction at the verified entry point must be 5 bytes or longer 1.2232 - // because it can be patched on the fly by make_non_entrant. The stack bang 1.2233 - // instruction fits that requirement. 1.2234 - 1.2235 - // Generate stack overflow check 1.2236 - 1.2237 - if (UseStackBanging) { 1.2238 - //this function will modify the value in A0 1.2239 - __ push(A0); 1.2240 - __ bang_stack_with_offset(StackShadowPages*os::vm_page_size()); 1.2241 - __ pop(A0); 1.2242 - } else { 1.2243 - // need a 5 byte instruction to allow MT safe patching to non-entrant 1.2244 - __ nop(); 1.2245 - __ nop(); 1.2246 - __ nop(); 1.2247 - __ nop(); 1.2248 - __ nop(); 1.2249 - } 1.2250 - // Generate a new frame for the wrapper. 1.2251 - // do mips need this ? 1.2252 + // The instruction at the verified entry point must be 5 bytes or longer 1.2253 + // because it can be patched on the fly by make_non_entrant. The stack bang 1.2254 + // instruction fits that requirement. 1.2255 + 1.2256 + // Generate stack overflow check 1.2257 + 1.2258 + if (UseStackBanging) { 1.2259 + //this function will modify the value in A0 1.2260 + __ push(A0); 1.2261 + __ bang_stack_with_offset(StackShadowPages*os::vm_page_size()); 1.2262 + __ pop(A0); 1.2263 + } else { 1.2264 + // need a 5 byte instruction to allow MT safe patching to non-entrant 1.2265 + __ nop(); 1.2266 + __ nop(); 1.2267 + __ nop(); 1.2268 + __ nop(); 1.2269 + __ nop(); 1.2270 + } 1.2271 + // Generate a new frame for the wrapper. 1.2272 + // do mips need this ? 1.2273 #ifndef OPT_THREAD 1.2274 - __ get_thread(TREG); 1.2275 + __ get_thread(TREG); 1.2276 #endif 1.2277 //FIXME here 1.2278 - __ st_ptr(SP, TREG, in_bytes(JavaThread::last_Java_sp_offset())); 1.2279 - // -2 because return address is already present and so is saved ebp 1.2280 - __ move(AT, -(StackAlignmentInBytes)); 1.2281 - __ andr(SP, SP, AT); 1.2282 - 1.2283 - __ enter(); 1.2284 - __ addiu(SP, SP, -1 * (stack_size - 2*wordSize)); 1.2285 - 1.2286 - // Frame is now completed as far a size and linkage. 1.2287 - 1.2288 - int frame_complete = ((intptr_t)__ pc()) - start; 1.2289 - 1.2290 - // Calculate the difference between esp and ebp. We need to know it 1.2291 - // after the native call because on windows Java Natives will pop 1.2292 - // the arguments and it is painful to do esp relative addressing 1.2293 - // in a platform independent way. So after the call we switch to 1.2294 - // ebp relative addressing. 1.2295 -//FIXME actually , the fp_adjustment may not be the right, because andr(sp,sp,at)may change 1.2296 -//the SP 1.2297 - int fp_adjustment = stack_size - 2*wordSize; 1.2298 + __ st_ptr(SP, TREG, in_bytes(JavaThread::last_Java_sp_offset())); 1.2299 + // -2 because return address is already present and so is saved ebp 1.2300 + __ move(AT, -(StackAlignmentInBytes)); 1.2301 + __ andr(SP, SP, AT); 1.2302 + 1.2303 + __ enter(); 1.2304 + __ addiu(SP, SP, -1 * (stack_size - 2*wordSize)); 1.2305 + 1.2306 + // Frame is now completed as far a size and linkage. 1.2307 + 1.2308 + int frame_complete = ((intptr_t)__ pc()) - start; 1.2309 + 1.2310 + // Calculate the difference between esp and ebp. We need to know it 1.2311 + // after the native call because on windows Java Natives will pop 1.2312 + // the arguments and it is painful to do esp relative addressing 1.2313 + // in a platform independent way. So after the call we switch to 1.2314 + // ebp relative addressing. 1.2315 + //FIXME actually , the fp_adjustment may not be the right, because andr(sp,sp,at)may change 1.2316 + //the SP 1.2317 + int fp_adjustment = stack_size - 2*wordSize; 1.2318 1.2319 #ifdef COMPILER2 1.2320 - // C2 may leave the stack dirty if not in SSE2+ mode 1.2321 - // if (UseSSE >= 2) { 1.2322 - // __ verify_FPU(0, "c2i transition should have clean FPU stack"); 1.2323 - //} else { 1.2324 - __ empty_FPU_stack(); 1.2325 - //} 1.2326 + // C2 may leave the stack dirty if not in SSE2+ mode 1.2327 + __ empty_FPU_stack(); 1.2328 #endif /* COMPILER2 */ 1.2329 1.2330 - // Compute the ebp offset for any slots used after the jni call 1.2331 - 1.2332 - int lock_slot_ebp_offset = (lock_slot_offset*VMRegImpl::stack_slot_size) - fp_adjustment; 1.2333 - // We use edi as a thread pointer because it is callee save and 1.2334 - // if we load it once it is usable thru the entire wrapper 1.2335 - // const Register thread = edi; 1.2336 - const Register thread = TREG; 1.2337 - 1.2338 - // We use esi as the oop handle for the receiver/klass 1.2339 - // It is callee save so it survives the call to native 1.2340 - 1.2341 - // const Register oop_handle_reg = esi; 1.2342 - const Register oop_handle_reg = S4; 1.2343 + // Compute the ebp offset for any slots used after the jni call 1.2344 + 1.2345 + int lock_slot_ebp_offset = (lock_slot_offset*VMRegImpl::stack_slot_size) - fp_adjustment; 1.2346 + // We use edi as a thread pointer because it is callee save and 1.2347 + // if we load it once it is usable thru the entire wrapper 1.2348 + // const Register thread = edi; 1.2349 + const Register thread = TREG; 1.2350 + 1.2351 + // We use esi as the oop handle for the receiver/klass 1.2352 + // It is callee save so it survives the call to native 1.2353 + 1.2354 + // const Register oop_handle_reg = esi; 1.2355 + const Register oop_handle_reg = S4; 1.2356 if (is_critical_native) { 1.2357 __ stop("generate_native_wrapper in sharedRuntime <2>"); 1.2358 //TODO:Fu 1.2359 @@ -2285,7 +1832,7 @@ 1.2360 } 1.2361 1.2362 #ifndef OPT_THREAD 1.2363 - __ get_thread(thread); 1.2364 + __ get_thread(thread); 1.2365 #endif 1.2366 1.2367 // 1.2368 @@ -2295,7 +1842,7 @@ 1.2369 // them. 1.2370 1.2371 // ----------------- 1.2372 - // The Grand Shuffle 1.2373 + // The Grand Shuffle 1.2374 // 1.2375 // Natives require 1 or 2 extra arguments over the normal ones: the JNIEnv* 1.2376 // and, if static, the class mirror instead of a receiver. This pretty much 1.2377 @@ -2308,18 +1855,18 @@ 1.2378 // vectors we have in our possession. We simply walk the java vector to 1.2379 // get the source locations and the c vector to get the destinations. 1.2380 1.2381 - int c_arg = method->is_static() ? 2 : 1 ; 1.2382 - 1.2383 - // Record esp-based slot for receiver on stack for non-static methods 1.2384 - int receiver_offset = -1; 1.2385 - 1.2386 - // This is a trick. We double the stack slots so we can claim 1.2387 - // the oops in the caller's frame. Since we are sure to have 1.2388 - // more args than the caller doubling is enough to make 1.2389 - // sure we can capture all the incoming oop args from the 1.2390 - // caller. 1.2391 - // 1.2392 - OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); 1.2393 + int c_arg = method->is_static() ? 2 : 1 ; 1.2394 + 1.2395 + // Record esp-based slot for receiver on stack for non-static methods 1.2396 + int receiver_offset = -1; 1.2397 + 1.2398 + // This is a trick. We double the stack slots so we can claim 1.2399 + // the oops in the caller's frame. Since we are sure to have 1.2400 + // more args than the caller doubling is enough to make 1.2401 + // sure we can capture all the incoming oop args from the 1.2402 + // caller. 1.2403 + // 1.2404 + OopMap* map = new OopMap(stack_slots * 2, 0 /* arg_slots*/); 1.2405 1.2406 // Mark location of rbp (someday) 1.2407 // map->set_callee_saved(VMRegImpl::stack2reg( stack_slots - 2), stack_slots * 2, 0, vmreg(rbp)); 1.2408 @@ -2341,9 +1888,9 @@ 1.2409 1.2410 #endif /* ASSERT */ 1.2411 1.2412 - // We know that we only have args in at most two integer registers (ecx, edx). So eax, ebx 1.2413 - // Are free to temporaries if we have to do stack to steck moves. 1.2414 - // All inbound args are referenced based on ebp and all outbound args via esp. 1.2415 + // We know that we only have args in at most two integer registers (ecx, edx). So eax, ebx 1.2416 + // Are free to temporaries if we have to do stack to steck moves. 1.2417 + // All inbound args are referenced based on ebp and all outbound args via esp. 1.2418 1.2419 // This may iterate in two different directions depending on the 1.2420 // kind of native it is. The reason is that for regular JNI natives 1.2421 @@ -2351,7 +1898,6 @@ 1.2422 // critical natives they are offset down. 1.2423 GrowableArray<int> arg_order(2 * total_in_args); 1.2424 VMRegPair tmp_vmreg; 1.2425 -// tmp_vmreg.set1(rbx->as_VMReg()); 1.2426 tmp_vmreg.set1(T8->as_VMReg()); 1.2427 1.2428 if (!is_critical_native) { 1.2429 @@ -2400,7 +1946,7 @@ 1.2430 switch (in_sig_bt[i]) { 1.2431 case T_ARRAY: 1.2432 if (is_critical_native) { 1.2433 - __ stop("generate_native_wrapper in sharedRuntime <2>"); 1.2434 + __ stop("generate_native_wrapper in sharedRuntime <2>"); 1.2435 //TODO:Fu 1.2436 // unpack_array_argument(masm, in_regs[i], in_elem_bt[i], out_regs[c_arg + 1], out_regs[c_arg]); 1.2437 c_arg++; 1.2438 @@ -2440,7 +1986,6 @@ 1.2439 case T_ADDRESS: assert(false, "found T_ADDRESS in java args"); 1.2440 1.2441 default: 1.2442 -// move32_64(masm, in_regs[i], out_regs[c_arg]); 1.2443 simple_move32(masm, in_regs[i], out_regs[c_arg]); 1.2444 } 1.2445 } 1.2446 @@ -2448,397 +1993,359 @@ 1.2447 // point c_arg at the first arg that is already loaded in case we 1.2448 // need to spill before we call out 1.2449 c_arg = total_c_args - total_in_args; 1.2450 - // Pre-load a static method's oop into esi. Used both by locking code and 1.2451 - // the normal JNI call code. 1.2452 - 1.2453 - __ move(oop_handle_reg, A1); 1.2454 - 1.2455 - if (method->is_static() && !is_critical_native) { 1.2456 - 1.2457 - // load opp into a register 1.2458 - int oop_index = __ oop_recorder()->find_index(JNIHandles::make_local( 1.2459 - (method->method_holder())->java_mirror())); 1.2460 - 1.2461 - 1.2462 - RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.2463 - __ relocate(rspec); 1.2464 - //__ lui(oop_handle_reg, Assembler::split_high((int)JNIHandles::make_local( 1.2465 - // Klass::cast(method->method_holder())->java_mirror()))); 1.2466 - //__ addiu(oop_handle_reg, oop_handle_reg, Assembler::split_low((int) 1.2467 - // JNIHandles::make_local(Klass::cast(method->method_holder())->java_mirror()))); 1.2468 - __ patchable_set48(oop_handle_reg, (long)JNIHandles::make_local((method->method_holder())->java_mirror())); 1.2469 - // __ verify_oop(oop_handle_reg); 1.2470 - // Now handlize the static class mirror it's known not-null. 1.2471 - __ sd( oop_handle_reg, SP, klass_offset); 1.2472 - map->set_oop(VMRegImpl::stack2reg(klass_slot_offset)); 1.2473 - 1.2474 - // Now get the handle 1.2475 - __ lea(oop_handle_reg, Address(SP, klass_offset)); 1.2476 - // store the klass handle as second argument 1.2477 - __ move(A1, oop_handle_reg); 1.2478 - // and protect the arg if we must spill 1.2479 - c_arg--; 1.2480 - } 1.2481 + // Pre-load a static method's oop into esi. Used both by locking code and 1.2482 + // the normal JNI call code. 1.2483 + 1.2484 + __ move(oop_handle_reg, A1); 1.2485 + 1.2486 + if (method->is_static() && !is_critical_native) { 1.2487 + 1.2488 + // load opp into a register 1.2489 + int oop_index = __ oop_recorder()->find_index(JNIHandles::make_local( 1.2490 + (method->method_holder())->java_mirror())); 1.2491 + 1.2492 + 1.2493 + RelocationHolder rspec = oop_Relocation::spec(oop_index); 1.2494 + __ relocate(rspec); 1.2495 + __ patchable_set48(oop_handle_reg, (long)JNIHandles::make_local((method->method_holder())->java_mirror())); 1.2496 + // Now handlize the static class mirror it's known not-null. 1.2497 + __ sd( oop_handle_reg, SP, klass_offset); 1.2498 + map->set_oop(VMRegImpl::stack2reg(klass_slot_offset)); 1.2499 + 1.2500 + // Now get the handle 1.2501 + __ lea(oop_handle_reg, Address(SP, klass_offset)); 1.2502 + // store the klass handle as second argument 1.2503 + __ move(A1, oop_handle_reg); 1.2504 + // and protect the arg if we must spill 1.2505 + c_arg--; 1.2506 + } 1.2507 + 1.2508 // Change state to native (we save the return address in the thread, since it might not 1.2509 // be pushed on the stack when we do a a stack traversal). It is enough that the pc() 1.2510 // points into the right code segment. It does not have to be the correct return pc. 1.2511 // We use the same pc/oopMap repeatedly when we call out 1.2512 1.2513 - intptr_t the_pc = (intptr_t) __ pc(); 1.2514 - 1.2515 - oop_maps->add_gc_map(the_pc - start, map); 1.2516 - 1.2517 - //__ set_last_Java_frame(thread, esp, noreg, (address)the_pc); 1.2518 - __ set_last_Java_frame(SP, noreg, NULL); 1.2519 - __ relocate(relocInfo::internal_pc_type); 1.2520 - { 1.2521 - intptr_t save_pc = (intptr_t)the_pc ; 1.2522 - __ patchable_set48(AT, save_pc); 1.2523 - } 1.2524 - __ sd(AT, thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset())); 1.2525 - 1.2526 - 1.2527 - // We have all of the arguments setup at this point. We must not touch any register 1.2528 - // argument registers at this point (what if we save/restore them there are no oop? 1.2529 - { 1.2530 - SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); 1.2531 - int metadata_index = __ oop_recorder()->find_index(method()); 1.2532 - RelocationHolder rspec = metadata_Relocation::spec(metadata_index); 1.2533 - __ relocate(rspec); 1.2534 - //__ lui(T6, Assembler::split_high((int)JNIHandles::make_local(method()))); 1.2535 - //__ addiu(T6, T6, Assembler::split_low((int)JNIHandles::make_local(method()))); 1.2536 - __ patchable_set48(AT, (long)(method())); 1.2537 - 1.2538 - __ call_VM_leaf( 1.2539 - CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), 1.2540 - thread, AT); 1.2541 - 1.2542 - } 1.2543 - 1.2544 - // These are register definitions we need for locking/unlocking 1.2545 -// const Register swap_reg = eax; // Must use eax for cmpxchg instruction 1.2546 -// const Register obj_reg = ecx; // Will contain the oop 1.2547 - // const Register lock_reg = edx; // Address of compiler lock object (BasicLock) 1.2548 -//FIXME, I hava no idea which register to use 1.2549 - const Register swap_reg = T8; // Must use eax for cmpxchg instruction 1.2550 - const Register obj_reg = T9; // Will contain the oop 1.2551 - //const Register lock_reg = T6; // Address of compiler lock object (BasicLock) 1.2552 - const Register lock_reg = c_rarg0; // Address of compiler lock object (BasicLock) 1.2553 - 1.2554 - 1.2555 - 1.2556 - Label slow_path_lock; 1.2557 - Label lock_done; 1.2558 - 1.2559 - // Lock a synchronized method 1.2560 - if (method->is_synchronized()) { 1.2561 - assert(!is_critical_native, "unhandled"); 1.2562 - 1.2563 - const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); 1.2564 - 1.2565 - // Get the handle (the 2nd argument) 1.2566 - __ move(oop_handle_reg, A1); 1.2567 - 1.2568 - // Get address of the box 1.2569 - __ lea(lock_reg, Address(FP, lock_slot_ebp_offset)); 1.2570 - 1.2571 - // Load the oop from the handle 1.2572 - __ ld(obj_reg, oop_handle_reg, 0); 1.2573 - 1.2574 - if (UseBiasedLocking) { 1.2575 - // Note that oop_handle_reg is trashed during this call 1.2576 - __ biased_locking_enter(lock_reg, obj_reg, swap_reg, A1, 1.2577 - false, lock_done, &slow_path_lock); 1.2578 - } 1.2579 - 1.2580 - // Load immediate 1 into swap_reg %eax 1.2581 - __ move(swap_reg, 1); 1.2582 - 1.2583 - __ ld(AT, obj_reg, 0); 1.2584 - __ orr(swap_reg, swap_reg, AT); 1.2585 - 1.2586 - __ sd( swap_reg, lock_reg, mark_word_offset); 1.2587 - __ cmpxchg(lock_reg, Address(obj_reg, 0), swap_reg); 1.2588 - __ bne(AT, R0, lock_done); 1.2589 - __ delayed()->nop(); 1.2590 - // Test if the oopMark is an obvious stack pointer, i.e., 1.2591 - // 1) (mark & 3) == 0, and 1.2592 - // 2) esp <= mark < mark + os::pagesize() 1.2593 - // These 3 tests can be done by evaluating the following 1.2594 - // expression: ((mark - esp) & (3 - os::vm_page_size())), 1.2595 - // assuming both stack pointer and pagesize have their 1.2596 - // least significant 2 bits clear. 1.2597 - // NOTE: the oopMark is in swap_reg %eax as the result of cmpxchg 1.2598 - 1.2599 - __ dsub(swap_reg, swap_reg,SP); 1.2600 - __ move(AT, 3 - os::vm_page_size()); 1.2601 - __ andr(swap_reg , swap_reg, AT); 1.2602 - // Save the test result, for recursive case, the result is zero 1.2603 - __ sd(swap_reg, lock_reg, mark_word_offset); 1.2604 - //FIXME here, Why notEqual? 1.2605 - __ bne(swap_reg,R0, slow_path_lock); 1.2606 - __ delayed()->nop(); 1.2607 - // Slow path will re-enter here 1.2608 - __ bind(lock_done); 1.2609 - 1.2610 - if (UseBiasedLocking) { 1.2611 - // Re-fetch oop_handle_reg as we trashed it above 1.2612 - __ move(A1, oop_handle_reg); 1.2613 - } 1.2614 - } 1.2615 - 1.2616 - 1.2617 - // Finally just about ready to make the JNI call 1.2618 - 1.2619 - 1.2620 - // get JNIEnv* which is first argument to native 1.2621 + intptr_t the_pc = (intptr_t) __ pc(); 1.2622 + oop_maps->add_gc_map(the_pc - start, map); 1.2623 + 1.2624 + __ set_last_Java_frame(SP, noreg, NULL); 1.2625 + __ relocate(relocInfo::internal_pc_type); 1.2626 + { 1.2627 + intptr_t save_pc = (intptr_t)the_pc ; 1.2628 + __ patchable_set48(AT, save_pc); 1.2629 + } 1.2630 + __ sd(AT, thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset())); 1.2631 + 1.2632 + 1.2633 + // We have all of the arguments setup at this point. We must not touch any register 1.2634 + // argument registers at this point (what if we save/restore them there are no oop? 1.2635 + { 1.2636 + SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); 1.2637 + int metadata_index = __ oop_recorder()->find_index(method()); 1.2638 + RelocationHolder rspec = metadata_Relocation::spec(metadata_index); 1.2639 + __ relocate(rspec); 1.2640 + __ patchable_set48(AT, (long)(method())); 1.2641 + 1.2642 + __ call_VM_leaf( 1.2643 + CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_entry), 1.2644 + thread, AT); 1.2645 + 1.2646 + } 1.2647 + 1.2648 + // These are register definitions we need for locking/unlocking 1.2649 + const Register swap_reg = T8; // Must use eax for cmpxchg instruction 1.2650 + const Register obj_reg = T9; // Will contain the oop 1.2651 + //const Register lock_reg = T6; // Address of compiler lock object (BasicLock) 1.2652 + const Register lock_reg = c_rarg0; // Address of compiler lock object (BasicLock) 1.2653 + 1.2654 + 1.2655 + 1.2656 + Label slow_path_lock; 1.2657 + Label lock_done; 1.2658 + 1.2659 + // Lock a synchronized method 1.2660 + if (method->is_synchronized()) { 1.2661 + assert(!is_critical_native, "unhandled"); 1.2662 + 1.2663 + const int mark_word_offset = BasicLock::displaced_header_offset_in_bytes(); 1.2664 + 1.2665 + // Get the handle (the 2nd argument) 1.2666 + __ move(oop_handle_reg, A1); 1.2667 + 1.2668 + // Get address of the box 1.2669 + __ lea(lock_reg, Address(FP, lock_slot_ebp_offset)); 1.2670 + 1.2671 + // Load the oop from the handle 1.2672 + __ ld(obj_reg, oop_handle_reg, 0); 1.2673 + 1.2674 + if (UseBiasedLocking) { 1.2675 + // Note that oop_handle_reg is trashed during this call 1.2676 + __ biased_locking_enter(lock_reg, obj_reg, swap_reg, A1, false, lock_done, &slow_path_lock); 1.2677 + } 1.2678 + 1.2679 + // Load immediate 1 into swap_reg %eax 1.2680 + __ move(swap_reg, 1); 1.2681 + 1.2682 + __ ld(AT, obj_reg, 0); 1.2683 + __ orr(swap_reg, swap_reg, AT); 1.2684 + 1.2685 + __ sd( swap_reg, lock_reg, mark_word_offset); 1.2686 + __ cmpxchg(lock_reg, Address(obj_reg, 0), swap_reg); 1.2687 + __ bne(AT, R0, lock_done); 1.2688 + __ delayed()->nop(); 1.2689 + // Test if the oopMark is an obvious stack pointer, i.e., 1.2690 + // 1) (mark & 3) == 0, and 1.2691 + // 2) esp <= mark < mark + os::pagesize() 1.2692 + // These 3 tests can be done by evaluating the following 1.2693 + // expression: ((mark - esp) & (3 - os::vm_page_size())), 1.2694 + // assuming both stack pointer and pagesize have their 1.2695 + // least significant 2 bits clear. 1.2696 + // NOTE: the oopMark is in swap_reg %eax as the result of cmpxchg 1.2697 + 1.2698 + __ dsub(swap_reg, swap_reg,SP); 1.2699 + __ move(AT, 3 - os::vm_page_size()); 1.2700 + __ andr(swap_reg , swap_reg, AT); 1.2701 + // Save the test result, for recursive case, the result is zero 1.2702 + __ sd(swap_reg, lock_reg, mark_word_offset); 1.2703 + //FIXME here, Why notEqual? 1.2704 + __ bne(swap_reg,R0, slow_path_lock); 1.2705 + __ delayed()->nop(); 1.2706 + // Slow path will re-enter here 1.2707 + __ bind(lock_done); 1.2708 + 1.2709 + if (UseBiasedLocking) { 1.2710 + // Re-fetch oop_handle_reg as we trashed it above 1.2711 + __ move(A1, oop_handle_reg); 1.2712 + } 1.2713 + } 1.2714 + 1.2715 + 1.2716 + // Finally just about ready to make the JNI call 1.2717 + 1.2718 + 1.2719 + // get JNIEnv* which is first argument to native 1.2720 if (!is_critical_native) { 1.2721 - __ addi(A0, thread, in_bytes(JavaThread::jni_environment_offset())); 1.2722 + __ addi(A0, thread, in_bytes(JavaThread::jni_environment_offset())); 1.2723 } 1.2724 1.2725 - // Example: Java_java_lang_ref_Finalizer_invokeFinalizeMethod(JNIEnv *env, jclass clazz, jobject ob) 1.2726 - /* Load the second arguments into A1 */ 1.2727 - //__ ld(A1, SP , wordSize ); // klass 1.2728 - 1.2729 - // Now set thread in native 1.2730 - __ addi(AT, R0, _thread_in_native); 1.2731 - __ sw(AT, thread, in_bytes(JavaThread::thread_state_offset())); 1.2732 - /* Jin: do the call */ 1.2733 - __ call(method->native_function(), relocInfo::runtime_call_type); 1.2734 - __ delayed()->nop(); 1.2735 - // WARNING - on Windows Java Natives use pascal calling convention and pop the 1.2736 - // arguments off of the stack. We could just re-adjust the stack pointer here 1.2737 - // and continue to do SP relative addressing but we instead switch to FP 1.2738 - // relative addressing. 1.2739 - 1.2740 - // Unpack native results. 1.2741 - switch (ret_type) { 1.2742 - case T_BOOLEAN: __ c2bool(V0); break; 1.2743 - case T_CHAR : __ andi(V0,V0, 0xFFFF); break; 1.2744 - case T_BYTE : __ sign_extend_byte (V0); break; 1.2745 - case T_SHORT : __ sign_extend_short(V0); break; 1.2746 - case T_INT : // nothing to do break; 1.2747 - case T_DOUBLE : 1.2748 - case T_FLOAT : 1.2749 - // Result is in st0 we'll save as needed 1.2750 - break; 1.2751 - case T_ARRAY: // Really a handle 1.2752 - case T_OBJECT: // Really a handle 1.2753 - break; // can't de-handlize until after safepoint check 1.2754 - case T_VOID: break; 1.2755 - case T_LONG: break; 1.2756 - default : ShouldNotReachHere(); 1.2757 - } 1.2758 - // Switch thread to "native transition" state before reading the synchronization state. 1.2759 - // This additional state is necessary because reading and testing the synchronization 1.2760 - // state is not atomic w.r.t. GC, as this scenario demonstrates: 1.2761 - // Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted. 1.2762 - // VM thread changes sync state to synchronizing and suspends threads for GC. 1.2763 - // Thread A is resumed to finish this native method, but doesn't block here since it 1.2764 - // didn't see any synchronization is progress, and escapes. 1.2765 - // __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans); 1.2766 - //__ sw(_thread_in_native_trans, thread, JavaThread::thread_state_offset()); 1.2767 - // __ move(AT, (int)_thread_in_native_trans); 1.2768 - __ addi(AT, R0, _thread_in_native_trans); 1.2769 - __ sw(AT, thread, in_bytes(JavaThread::thread_state_offset())); 1.2770 - 1.2771 + // Example: Java_java_lang_ref_Finalizer_invokeFinalizeMethod(JNIEnv *env, jclass clazz, jobject ob) 1.2772 + /* Load the second arguments into A1 */ 1.2773 + //__ ld(A1, SP , wordSize ); // klass 1.2774 + 1.2775 + // Now set thread in native 1.2776 + __ addi(AT, R0, _thread_in_native); 1.2777 + __ sw(AT, thread, in_bytes(JavaThread::thread_state_offset())); 1.2778 + /* Jin: do the call */ 1.2779 + __ call(method->native_function(), relocInfo::runtime_call_type); 1.2780 + __ delayed()->nop(); 1.2781 + // WARNING - on Windows Java Natives use pascal calling convention and pop the 1.2782 + // arguments off of the stack. We could just re-adjust the stack pointer here 1.2783 + // and continue to do SP relative addressing but we instead switch to FP 1.2784 + // relative addressing. 1.2785 + 1.2786 + // Unpack native results. 1.2787 + switch (ret_type) { 1.2788 + case T_BOOLEAN: __ c2bool(V0); break; 1.2789 + case T_CHAR : __ andi(V0,V0, 0xFFFF); break; 1.2790 + case T_BYTE : __ sign_extend_byte (V0); break; 1.2791 + case T_SHORT : __ sign_extend_short(V0); break; 1.2792 + case T_INT : // nothing to do break; 1.2793 + case T_DOUBLE : 1.2794 + case T_FLOAT : 1.2795 + // Result is in st0 we'll save as needed 1.2796 + break; 1.2797 + case T_ARRAY: // Really a handle 1.2798 + case T_OBJECT: // Really a handle 1.2799 + break; // can't de-handlize until after safepoint check 1.2800 + case T_VOID: break; 1.2801 + case T_LONG: break; 1.2802 + default : ShouldNotReachHere(); 1.2803 + } 1.2804 + // Switch thread to "native transition" state before reading the synchronization state. 1.2805 + // This additional state is necessary because reading and testing the synchronization 1.2806 + // state is not atomic w.r.t. GC, as this scenario demonstrates: 1.2807 + // Java thread A, in _thread_in_native state, loads _not_synchronized and is preempted. 1.2808 + // VM thread changes sync state to synchronizing and suspends threads for GC. 1.2809 + // Thread A is resumed to finish this native method, but doesn't block here since it 1.2810 + // didn't see any synchronization is progress, and escapes. 1.2811 + // __ movl(Address(thread, JavaThread::thread_state_offset()), _thread_in_native_trans); 1.2812 + //__ sw(_thread_in_native_trans, thread, JavaThread::thread_state_offset()); 1.2813 + // __ move(AT, (int)_thread_in_native_trans); 1.2814 + __ addi(AT, R0, _thread_in_native_trans); 1.2815 + __ sw(AT, thread, in_bytes(JavaThread::thread_state_offset())); 1.2816 + 1.2817 Label after_transition; 1.2818 1.2819 - // check for safepoint operation in progress and/or pending suspend requests 1.2820 - { Label Continue; 1.2821 + // check for safepoint operation in progress and/or pending suspend requests 1.2822 + { Label Continue; 1.2823 //FIXME here, which regiser should we use? 1.2824 - // SafepointSynchronize::_not_synchronized); 1.2825 - __ li(AT, SafepointSynchronize::address_of_state()); 1.2826 - __ lw(A0, AT, 0); 1.2827 - __ addi(AT, A0, -SafepointSynchronize::_not_synchronized); 1.2828 - Label L; 1.2829 - __ bne(AT,R0, L); 1.2830 - __ delayed()->nop(); 1.2831 - __ lw(AT, thread, in_bytes(JavaThread::suspend_flags_offset())); 1.2832 - __ beq(AT, R0, Continue); 1.2833 - __ delayed()->nop(); 1.2834 - __ bind(L); 1.2835 - 1.2836 - // Don't use call_VM as it will see a possible pending exception and forward it 1.2837 - // and never return here preventing us from clearing _last_native_pc down below. 1.2838 - // Also can't use call_VM_leaf either as it will check to see if esi & edi are 1.2839 - // preserved and correspond to the bcp/locals pointers. So we do a runtime call 1.2840 - // by hand. 1.2841 - // 1.2842 - save_native_result(masm, ret_type, stack_slots); 1.2843 - __ move (A0, thread); 1.2844 - __ addi(SP,SP, -wordSize); 1.2845 + // SafepointSynchronize::_not_synchronized); 1.2846 + __ li(AT, SafepointSynchronize::address_of_state()); 1.2847 + __ lw(A0, AT, 0); 1.2848 + __ addi(AT, A0, -SafepointSynchronize::_not_synchronized); 1.2849 + Label L; 1.2850 + __ bne(AT,R0, L); 1.2851 + __ delayed()->nop(); 1.2852 + __ lw(AT, thread, in_bytes(JavaThread::suspend_flags_offset())); 1.2853 + __ beq(AT, R0, Continue); 1.2854 + __ delayed()->nop(); 1.2855 + __ bind(L); 1.2856 + 1.2857 + // Don't use call_VM as it will see a possible pending exception and forward it 1.2858 + // and never return here preventing us from clearing _last_native_pc down below. 1.2859 + // Also can't use call_VM_leaf either as it will check to see if esi & edi are 1.2860 + // preserved and correspond to the bcp/locals pointers. So we do a runtime call 1.2861 + // by hand. 1.2862 + // 1.2863 + save_native_result(masm, ret_type, stack_slots); 1.2864 + __ move (A0, thread); 1.2865 + __ addi(SP,SP, -wordSize); 1.2866 __ push(S2); 1.2867 __ move(AT, -(StackAlignmentInBytes)); 1.2868 __ move(S2, SP); // use S2 as a sender SP holder 1.2869 __ andr(SP, SP, AT); // align stack as required by ABI 1.2870 if (!is_critical_native) { 1.2871 __ call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans), relocInfo::runtime_call_type); 1.2872 - __ delayed()->nop(); 1.2873 + __ delayed()->nop(); 1.2874 } else { 1.2875 __ call(CAST_FROM_FN_PTR(address, JavaThread::check_special_condition_for_native_trans_and_transition), relocInfo::runtime_call_type); 1.2876 - __ delayed()->nop(); 1.2877 + __ delayed()->nop(); 1.2878 } 1.2879 __ move(SP, S2); // use S2 as a sender SP holder 1.2880 __ pop(S2); 1.2881 - __ addi(SP,SP, wordSize); 1.2882 - //add for compressedoops 1.2883 - __ reinit_heapbase(); 1.2884 - // Restore any method result value 1.2885 - restore_native_result(masm, ret_type, stack_slots); 1.2886 + __ addi(SP,SP, wordSize); 1.2887 + //add for compressedoops 1.2888 + __ reinit_heapbase(); 1.2889 + // Restore any method result value 1.2890 + restore_native_result(masm, ret_type, stack_slots); 1.2891 1.2892 if (is_critical_native) { 1.2893 // The call above performed the transition to thread_in_Java so 1.2894 // skip the transition logic below. 1.2895 __ beq(R0, R0, after_transition); 1.2896 - __ delayed()->nop(); 1.2897 + __ delayed()->nop(); 1.2898 } 1.2899 1.2900 - __ bind(Continue); 1.2901 - } 1.2902 - 1.2903 - // change thread state 1.2904 - __ addi(AT, R0, _thread_in_Java); 1.2905 - __ sw(AT, thread, in_bytes(JavaThread::thread_state_offset())); 1.2906 + __ bind(Continue); 1.2907 + } 1.2908 + 1.2909 + // change thread state 1.2910 + __ addi(AT, R0, _thread_in_Java); 1.2911 + __ sw(AT, thread, in_bytes(JavaThread::thread_state_offset())); 1.2912 __ bind(after_transition); 1.2913 - Label reguard; 1.2914 - Label reguard_done; 1.2915 - __ lw(AT, thread, in_bytes(JavaThread::stack_guard_state_offset())); 1.2916 - __ addi(AT, AT, -JavaThread::stack_guard_yellow_disabled); 1.2917 - __ beq(AT, R0, reguard); 1.2918 - __ delayed()->nop(); 1.2919 - // slow path reguard re-enters here 1.2920 - __ bind(reguard_done); 1.2921 - 1.2922 - // Handle possible exception (will unlock if necessary) 1.2923 - 1.2924 - // native result if any is live 1.2925 - 1.2926 - // Unlock 1.2927 - Label slow_path_unlock; 1.2928 - Label unlock_done; 1.2929 - if (method->is_synchronized()) { 1.2930 - 1.2931 - Label done; 1.2932 - 1.2933 - // Get locked oop from the handle we passed to jni 1.2934 - __ ld( obj_reg, oop_handle_reg, 0); 1.2935 - //FIXME 1.2936 - if (UseBiasedLocking) { 1.2937 - __ biased_locking_exit(obj_reg, T8, done); 1.2938 - 1.2939 - } 1.2940 - 1.2941 - // Simple recursive lock? 1.2942 - 1.2943 - __ ld(AT, FP, lock_slot_ebp_offset); 1.2944 - __ beq(AT, R0, done); 1.2945 - __ delayed()->nop(); 1.2946 - // Must save eax if if it is live now because cmpxchg must use it 1.2947 - if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { 1.2948 - save_native_result(masm, ret_type, stack_slots); 1.2949 - } 1.2950 - 1.2951 - // get old displaced header 1.2952 - __ ld (T8, FP, lock_slot_ebp_offset); 1.2953 - // get address of the stack lock 1.2954 - //FIXME aoqi 1.2955 - //__ addi (T6, FP, lock_slot_ebp_offset); 1.2956 - __ addi (c_rarg0, FP, lock_slot_ebp_offset); 1.2957 - // Atomic swap old header if oop still contains the stack lock 1.2958 - //FIXME aoqi 1.2959 - //__ cmpxchg(T8, Address(obj_reg, 0),T6 ); 1.2960 - __ cmpxchg(T8, Address(obj_reg, 0), c_rarg0); 1.2961 - 1.2962 - __ beq(AT, R0, slow_path_unlock); 1.2963 - __ delayed()->nop(); 1.2964 - // slow path re-enters here 1.2965 - __ bind(unlock_done); 1.2966 - if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { 1.2967 - restore_native_result(masm, ret_type, stack_slots); 1.2968 - } 1.2969 - 1.2970 - __ bind(done); 1.2971 - 1.2972 - } 1.2973 - { 1.2974 - SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); 1.2975 - // Tell dtrace about this method exit 1.2976 - save_native_result(masm, ret_type, stack_slots); 1.2977 - int metadata_index = __ oop_recorder()->find_index( (method())); 1.2978 - RelocationHolder rspec = metadata_Relocation::spec(metadata_index); 1.2979 - __ relocate(rspec); 1.2980 - //__ lui(T6, Assembler::split_high((int)JNIHandles::make_local(method()))); 1.2981 - //__ addiu(T6, T6, Assembler::split_low((int)JNIHandles::make_local(method()))); 1.2982 - __ patchable_set48(AT, (long)(method())); 1.2983 - 1.2984 - __ call_VM_leaf( 1.2985 - CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), 1.2986 - thread, AT); 1.2987 - restore_native_result(masm, ret_type, stack_slots); 1.2988 - } 1.2989 - 1.2990 - // We can finally stop using that last_Java_frame we setup ages ago 1.2991 - 1.2992 - __ reset_last_Java_frame(false, true); 1.2993 - 1.2994 - // Unpack oop result 1.2995 - if (ret_type == T_OBJECT || ret_type == T_ARRAY) { 1.2996 - Label L; 1.2997 - // __ cmpl(eax, NULL_WORD); 1.2998 - // __ jcc(Assembler::equal, L); 1.2999 - __ beq(V0, R0,L ); 1.3000 - __ delayed()->nop(); 1.3001 - // __ movl(eax, Address(eax)); 1.3002 - __ ld(V0, V0, 0); 1.3003 - __ bind(L); 1.3004 - // __ verify_oop(eax); 1.3005 - __ verify_oop(V0); 1.3006 - } 1.3007 + Label reguard; 1.3008 + Label reguard_done; 1.3009 + __ lw(AT, thread, in_bytes(JavaThread::stack_guard_state_offset())); 1.3010 + __ addi(AT, AT, -JavaThread::stack_guard_yellow_disabled); 1.3011 + __ beq(AT, R0, reguard); 1.3012 + __ delayed()->nop(); 1.3013 + // slow path reguard re-enters here 1.3014 + __ bind(reguard_done); 1.3015 + 1.3016 + // Handle possible exception (will unlock if necessary) 1.3017 + 1.3018 + // native result if any is live 1.3019 + 1.3020 + // Unlock 1.3021 + Label slow_path_unlock; 1.3022 + Label unlock_done; 1.3023 + if (method->is_synchronized()) { 1.3024 + 1.3025 + Label done; 1.3026 + 1.3027 + // Get locked oop from the handle we passed to jni 1.3028 + __ ld( obj_reg, oop_handle_reg, 0); 1.3029 + //FIXME 1.3030 + if (UseBiasedLocking) { 1.3031 + __ biased_locking_exit(obj_reg, T8, done); 1.3032 + 1.3033 + } 1.3034 + 1.3035 + // Simple recursive lock? 1.3036 + 1.3037 + __ ld(AT, FP, lock_slot_ebp_offset); 1.3038 + __ beq(AT, R0, done); 1.3039 + __ delayed()->nop(); 1.3040 + // Must save eax if if it is live now because cmpxchg must use it 1.3041 + if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { 1.3042 + save_native_result(masm, ret_type, stack_slots); 1.3043 + } 1.3044 + 1.3045 + // get old displaced header 1.3046 + __ ld (T8, FP, lock_slot_ebp_offset); 1.3047 + // get address of the stack lock 1.3048 + __ addi (c_rarg0, FP, lock_slot_ebp_offset); 1.3049 + // Atomic swap old header if oop still contains the stack lock 1.3050 + __ cmpxchg(T8, Address(obj_reg, 0), c_rarg0); 1.3051 + 1.3052 + __ beq(AT, R0, slow_path_unlock); 1.3053 + __ delayed()->nop(); 1.3054 + // slow path re-enters here 1.3055 + __ bind(unlock_done); 1.3056 + if (ret_type != T_FLOAT && ret_type != T_DOUBLE && ret_type != T_VOID) { 1.3057 + restore_native_result(masm, ret_type, stack_slots); 1.3058 + } 1.3059 + 1.3060 + __ bind(done); 1.3061 + 1.3062 + } 1.3063 + { 1.3064 + SkipIfEqual skip_if(masm, &DTraceMethodProbes, 0); 1.3065 + // Tell dtrace about this method exit 1.3066 + save_native_result(masm, ret_type, stack_slots); 1.3067 + int metadata_index = __ oop_recorder()->find_index( (method())); 1.3068 + RelocationHolder rspec = metadata_Relocation::spec(metadata_index); 1.3069 + __ relocate(rspec); 1.3070 + __ patchable_set48(AT, (long)(method())); 1.3071 + 1.3072 + __ call_VM_leaf( 1.3073 + CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_method_exit), 1.3074 + thread, AT); 1.3075 + restore_native_result(masm, ret_type, stack_slots); 1.3076 + } 1.3077 + 1.3078 + // We can finally stop using that last_Java_frame we setup ages ago 1.3079 + 1.3080 + __ reset_last_Java_frame(false, true); 1.3081 + 1.3082 + // Unpack oop result 1.3083 + if (ret_type == T_OBJECT || ret_type == T_ARRAY) { 1.3084 + Label L; 1.3085 + __ beq(V0, R0,L ); 1.3086 + __ delayed()->nop(); 1.3087 + __ ld(V0, V0, 0); 1.3088 + __ bind(L); 1.3089 + __ verify_oop(V0); 1.3090 + } 1.3091 1.3092 if (!is_critical_native) { 1.3093 - // reset handle block 1.3094 - __ ld(AT, thread, in_bytes(JavaThread::active_handles_offset())); 1.3095 - __ sw(R0, AT, JNIHandleBlock::top_offset_in_bytes()); 1.3096 + // reset handle block 1.3097 + __ ld(AT, thread, in_bytes(JavaThread::active_handles_offset())); 1.3098 + __ sw(R0, AT, JNIHandleBlock::top_offset_in_bytes()); 1.3099 } 1.3100 1.3101 if (!is_critical_native) { 1.3102 - // Any exception pending? 1.3103 - __ ld(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3104 - 1.3105 - __ bne(AT, R0, exception_pending); 1.3106 - __ delayed()->nop(); 1.3107 + // Any exception pending? 1.3108 + __ ld(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3109 + 1.3110 + __ bne(AT, R0, exception_pending); 1.3111 + __ delayed()->nop(); 1.3112 } 1.3113 - // no exception, we're almost done 1.3114 - 1.3115 - // check that only result value is on FPU stack 1.3116 - __ verify_FPU(ret_type == T_FLOAT || ret_type == T_DOUBLE ? 1 : 0, "native_wrapper normal exit"); 1.3117 - 1.3118 - // Fixup floating pointer results so that result looks like a return from a compiled method 1.3119 -/* if (ret_type == T_FLOAT) { 1.3120 - if (UseSSE >= 1) { 1.3121 - // Pop st0 and store as float and reload into xmm register 1.3122 - __ fstp_s(Address(ebp, -4)); 1.3123 - __ movss(xmm0, Address(ebp, -4)); 1.3124 - } 1.3125 - } else if (ret_type == T_DOUBLE) { 1.3126 - if (UseSSE >= 2) { 1.3127 - // Pop st0 and store as double and reload into xmm register 1.3128 - __ fstp_d(Address(ebp, -8)); 1.3129 - __ movsd(xmm0, Address(ebp, -8)); 1.3130 - } 1.3131 - } 1.3132 -*/ 1.3133 + // no exception, we're almost done 1.3134 + 1.3135 + // check that only result value is on FPU stack 1.3136 + __ verify_FPU(ret_type == T_FLOAT || ret_type == T_DOUBLE ? 1 : 0, "native_wrapper normal exit"); 1.3137 + 1.3138 // Return 1.3139 #ifndef OPT_THREAD 1.3140 - __ get_thread(TREG); 1.3141 + __ get_thread(TREG); 1.3142 #endif 1.3143 - __ ld_ptr(SP, TREG, in_bytes(JavaThread::last_Java_sp_offset())); 1.3144 - __ leave(); 1.3145 - 1.3146 - __ jr(RA); 1.3147 - __ delayed()->nop(); 1.3148 - // Unexpected paths are out of line and go here 1.3149 + __ ld_ptr(SP, TREG, in_bytes(JavaThread::last_Java_sp_offset())); 1.3150 + __ leave(); 1.3151 + 1.3152 + __ jr(RA); 1.3153 + __ delayed()->nop(); 1.3154 + // Unexpected paths are out of line and go here 1.3155 /* 1.3156 if (!is_critical_native) { 1.3157 // forward the exception 1.3158 @@ -2848,152 +2355,147 @@ 1.3159 __ jump(RuntimeAddress(StubRoutines::forward_exception_entry())); 1.3160 } 1.3161 */ 1.3162 - // Slow path locking & unlocking 1.3163 - if (method->is_synchronized()) { 1.3164 - 1.3165 - // BEGIN Slow path lock 1.3166 - 1.3167 - __ bind(slow_path_lock); 1.3168 - 1.3169 - // protect the args we've loaded 1.3170 - save_args(masm, total_c_args, c_arg, out_regs); 1.3171 - 1.3172 - // has last_Java_frame setup. No exceptions so do vanilla call not call_VM 1.3173 - // args are (oop obj, BasicLock* lock, JavaThread* thread) 1.3174 - 1.3175 - __ move(A0, obj_reg); 1.3176 - __ move(A1, lock_reg); 1.3177 - __ move(A2, thread); 1.3178 - __ addi(SP, SP, - 3*wordSize); 1.3179 + // Slow path locking & unlocking 1.3180 + if (method->is_synchronized()) { 1.3181 + 1.3182 + // BEGIN Slow path lock 1.3183 + __ bind(slow_path_lock); 1.3184 + 1.3185 + // protect the args we've loaded 1.3186 + save_args(masm, total_c_args, c_arg, out_regs); 1.3187 + 1.3188 + // has last_Java_frame setup. No exceptions so do vanilla call not call_VM 1.3189 + // args are (oop obj, BasicLock* lock, JavaThread* thread) 1.3190 + 1.3191 + __ move(A0, obj_reg); 1.3192 + __ move(A1, lock_reg); 1.3193 + __ move(A2, thread); 1.3194 + __ addi(SP, SP, - 3*wordSize); 1.3195 + 1.3196 + __ move(AT, -(StackAlignmentInBytes)); 1.3197 + __ move(S2, SP); // use S2 as a sender SP holder 1.3198 + __ andr(SP, SP, AT); // align stack as required by ABI 1.3199 + 1.3200 + __ call(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), relocInfo::runtime_call_type); 1.3201 + __ delayed()->nop(); 1.3202 + __ move(SP, S2); 1.3203 + __ addi(SP, SP, 3*wordSize); 1.3204 + 1.3205 + restore_args(masm, total_c_args, c_arg, out_regs); 1.3206 + 1.3207 +#ifdef ASSERT 1.3208 + { Label L; 1.3209 + __ ld(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3210 + __ beq(AT, R0, L); 1.3211 + __ delayed()->nop(); 1.3212 + __ stop("no pending exception allowed on exit from monitorenter"); 1.3213 + __ bind(L); 1.3214 + } 1.3215 +#endif 1.3216 + __ b(lock_done); 1.3217 + __ delayed()->nop(); 1.3218 + // END Slow path lock 1.3219 + 1.3220 + // BEGIN Slow path unlock 1.3221 + __ bind(slow_path_unlock); 1.3222 + 1.3223 + // Slow path unlock 1.3224 + 1.3225 + if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { 1.3226 + save_native_result(masm, ret_type, stack_slots); 1.3227 + } 1.3228 + // Save pending exception around call to VM (which contains an EXCEPTION_MARK) 1.3229 + 1.3230 + __ ld(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3231 + __ push(AT); 1.3232 + __ sd(R0, thread, in_bytes(Thread::pending_exception_offset())); 1.3233 1.3234 __ move(AT, -(StackAlignmentInBytes)); 1.3235 __ move(S2, SP); // use S2 as a sender SP holder 1.3236 __ andr(SP, SP, AT); // align stack as required by ABI 1.3237 1.3238 - __ call(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_locking_C), relocInfo::runtime_call_type); 1.3239 - __ delayed()->nop(); 1.3240 + // should be a peal 1.3241 + // +wordSize because of the push above 1.3242 + __ addi(A1, FP, lock_slot_ebp_offset); 1.3243 + 1.3244 + __ move(A0, obj_reg); 1.3245 + __ addi(SP,SP, -2*wordSize); 1.3246 + __ call(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), 1.3247 + relocInfo::runtime_call_type); 1.3248 + __ delayed()->nop(); 1.3249 + __ addi(SP,SP, 2*wordSize); 1.3250 __ move(SP, S2); 1.3251 - __ addi(SP, SP, 3*wordSize); 1.3252 - 1.3253 - restore_args(masm, total_c_args, c_arg, out_regs); 1.3254 - 1.3255 + //add for compressedoops 1.3256 + __ reinit_heapbase(); 1.3257 #ifdef ASSERT 1.3258 - { Label L; 1.3259 - // __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), (int)NULL_WORD); 1.3260 - __ ld(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3261 - //__ jcc(Assembler::equal, L); 1.3262 - __ beq(AT, R0, L); 1.3263 - __ delayed()->nop(); 1.3264 - __ stop("no pending exception allowed on exit from monitorenter"); 1.3265 - __ bind(L); 1.3266 - } 1.3267 -#endif 1.3268 - __ b(lock_done); 1.3269 - __ delayed()->nop(); 1.3270 - // END Slow path lock 1.3271 - 1.3272 - // BEGIN Slow path unlock 1.3273 - __ bind(slow_path_unlock); 1.3274 - 1.3275 - // Slow path unlock 1.3276 - 1.3277 - if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { 1.3278 - save_native_result(masm, ret_type, stack_slots); 1.3279 - } 1.3280 - // Save pending exception around call to VM (which contains an EXCEPTION_MARK) 1.3281 - 1.3282 - __ ld(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3283 - __ push(AT); 1.3284 - __ sd(R0, thread, in_bytes(Thread::pending_exception_offset())); 1.3285 - 1.3286 - __ move(AT, -(StackAlignmentInBytes)); 1.3287 - __ move(S2, SP); // use S2 as a sender SP holder 1.3288 - __ andr(SP, SP, AT); // align stack as required by ABI 1.3289 - 1.3290 - // should be a peal 1.3291 - // +wordSize because of the push above 1.3292 - __ addi(A1, FP, lock_slot_ebp_offset); 1.3293 - 1.3294 - __ move(A0, obj_reg); 1.3295 - __ addi(SP,SP, -2*wordSize); 1.3296 - __ call(CAST_FROM_FN_PTR(address, SharedRuntime::complete_monitor_unlocking_C), 1.3297 - relocInfo::runtime_call_type); 1.3298 - __ delayed()->nop(); 1.3299 - __ addi(SP,SP, 2*wordSize); 1.3300 - __ move(SP, S2); 1.3301 - //add for compressedoops 1.3302 - __ reinit_heapbase(); 1.3303 -#ifdef ASSERT 1.3304 - { 1.3305 - Label L; 1.3306 - // __ cmpl(Address(thread, in_bytes(Thread::pending_exception_offset())), NULL_WORD); 1.3307 - __ lw( AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3308 - //__ jcc(Assembler::equal, L); 1.3309 - __ beq(AT, R0, L); 1.3310 - __ delayed()->nop(); 1.3311 - __ stop("no pending exception allowed on exit complete_monitor_unlocking_C"); 1.3312 - __ bind(L); 1.3313 - } 1.3314 + { 1.3315 + Label L; 1.3316 + __ lw( AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3317 + __ beq(AT, R0, L); 1.3318 + __ delayed()->nop(); 1.3319 + __ stop("no pending exception allowed on exit complete_monitor_unlocking_C"); 1.3320 + __ bind(L); 1.3321 + } 1.3322 #endif /* ASSERT */ 1.3323 1.3324 - __ pop(AT); 1.3325 - __ sd(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3326 - if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { 1.3327 - restore_native_result(masm, ret_type, stack_slots); 1.3328 - } 1.3329 - __ b(unlock_done); 1.3330 - __ delayed()->nop(); 1.3331 - // END Slow path unlock 1.3332 - 1.3333 - } 1.3334 - 1.3335 - // SLOW PATH Reguard the stack if needed 1.3336 - 1.3337 - __ bind(reguard); 1.3338 - save_native_result(masm, ret_type, stack_slots); 1.3339 - __ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages), 1.3340 - relocInfo::runtime_call_type); 1.3341 - __ delayed()->nop(); 1.3342 - //add for compressedoops 1.3343 - __ reinit_heapbase(); 1.3344 - restore_native_result(masm, ret_type, stack_slots); 1.3345 - __ b(reguard_done); 1.3346 - __ delayed()->nop(); 1.3347 - 1.3348 - // BEGIN EXCEPTION PROCESSING 1.3349 - if (!is_critical_native) { 1.3350 - // Forward the exception 1.3351 - __ bind(exception_pending); 1.3352 - 1.3353 - // remove possible return value from FPU register stack 1.3354 - __ empty_FPU_stack(); 1.3355 - 1.3356 - // pop our frame 1.3357 - //forward_exception_entry need return address on stack 1.3358 - __ addiu(SP, FP, wordSize); 1.3359 - __ ld(FP, SP, (-1) * wordSize); 1.3360 - 1.3361 - // and forward the exception 1.3362 - __ jmp(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); 1.3363 - __ delayed()->nop(); 1.3364 + __ pop(AT); 1.3365 + __ sd(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3366 + if (ret_type == T_FLOAT || ret_type == T_DOUBLE ) { 1.3367 + restore_native_result(masm, ret_type, stack_slots); 1.3368 } 1.3369 - __ flush(); 1.3370 - 1.3371 - nmethod *nm = nmethod::new_native_nmethod(method, 1.3372 - compile_id, 1.3373 - masm->code(), 1.3374 - vep_offset, 1.3375 - frame_complete, 1.3376 - stack_slots / VMRegImpl::slots_per_word, 1.3377 - (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)), 1.3378 - in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size), 1.3379 - oop_maps); 1.3380 + __ b(unlock_done); 1.3381 + __ delayed()->nop(); 1.3382 + // END Slow path unlock 1.3383 + 1.3384 + } 1.3385 + 1.3386 + // SLOW PATH Reguard the stack if needed 1.3387 + 1.3388 + __ bind(reguard); 1.3389 + save_native_result(masm, ret_type, stack_slots); 1.3390 + __ call(CAST_FROM_FN_PTR(address, SharedRuntime::reguard_yellow_pages), 1.3391 + relocInfo::runtime_call_type); 1.3392 + __ delayed()->nop(); 1.3393 + //add for compressedoops 1.3394 + __ reinit_heapbase(); 1.3395 + restore_native_result(masm, ret_type, stack_slots); 1.3396 + __ b(reguard_done); 1.3397 + __ delayed()->nop(); 1.3398 + 1.3399 + // BEGIN EXCEPTION PROCESSING 1.3400 + if (!is_critical_native) { 1.3401 + // Forward the exception 1.3402 + __ bind(exception_pending); 1.3403 + 1.3404 + // remove possible return value from FPU register stack 1.3405 + __ empty_FPU_stack(); 1.3406 + 1.3407 + // pop our frame 1.3408 + //forward_exception_entry need return address on stack 1.3409 + __ addiu(SP, FP, wordSize); 1.3410 + __ ld(FP, SP, (-1) * wordSize); 1.3411 + 1.3412 + // and forward the exception 1.3413 + __ jmp(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); 1.3414 + __ delayed()->nop(); 1.3415 + } 1.3416 + __ flush(); 1.3417 + 1.3418 + nmethod *nm = nmethod::new_native_nmethod(method, 1.3419 + compile_id, 1.3420 + masm->code(), 1.3421 + vep_offset, 1.3422 + frame_complete, 1.3423 + stack_slots / VMRegImpl::slots_per_word, 1.3424 + (is_static ? in_ByteSize(klass_offset) : in_ByteSize(receiver_offset)), 1.3425 + in_ByteSize(lock_slot_offset*VMRegImpl::stack_slot_size), 1.3426 + oop_maps); 1.3427 1.3428 if (is_critical_native) { 1.3429 nm->set_lazy_critical_native(true); 1.3430 } 1.3431 - return nm; 1.3432 - 1.3433 + 1.3434 + return nm; 1.3435 1.3436 } 1.3437 1.3438 @@ -3027,8 +2529,8 @@ 1.3439 } 1.3440 1.3441 1.3442 -nmethod *SharedRuntime::generate_dtrace_nmethod( 1.3443 - MacroAssembler *masm, methodHandle method) { 1.3444 +nmethod *SharedRuntime::generate_dtrace_nmethod(MacroAssembler *masm, 1.3445 + methodHandle method) { 1.3446 1.3447 1.3448 // generate_dtrace_nmethod is guarded by a mutex so we are sure to 1.3449 @@ -3111,7 +2613,7 @@ 1.3450 // Now figure out where the args must be stored and how much stack space 1.3451 // they require (neglecting out_preserve_stack_slots but space for storing 1.3452 // the 1st six register arguments). It's weird see int_stk_helper. 1.3453 - // 1.3454 + 1.3455 int out_arg_slots; 1.3456 out_arg_slots = c_calling_convention(out_sig_bt, out_regs, NULL, total_c_args); 1.3457 1.3458 @@ -3547,7 +3049,7 @@ 1.3459 // this function returns the adjust size (in number of words) to a c2i adapter 1.3460 // activation for use during deoptimization 1.3461 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) { 1.3462 - return (callee_locals - callee_parameters) * Interpreter::stackElementWords; 1.3463 + return (callee_locals - callee_parameters) * Interpreter::stackElementWords; 1.3464 } 1.3465 1.3466 // "Top of Stack" slots that may be unused by the calling convention but must 1.3467 @@ -3557,131 +3059,8 @@ 1.3468 // when an interrupt occurs. 1.3469 uint SharedRuntime::out_preserve_stack_slots() { 1.3470 //return frame::register_save_words * VMRegImpl::slots_per_word; 1.3471 - return 0; 1.3472 + return 0; 1.3473 } 1.3474 -/* 1.3475 -static void gen_new_frame(MacroAssembler* masm, bool deopt) { 1.3476 -// 1.3477 -// Common out the new frame generation for deopt and uncommon trap 1.3478 -// 1.3479 - Register G3pcs = G3_scratch; // Array of new pcs (input) 1.3480 - Register Oreturn0 = O0; 1.3481 - Register Oreturn1 = O1; 1.3482 - Register O2UnrollBlock = O2; 1.3483 - Register O3array = O3; // Array of frame sizes (input) 1.3484 - Register O4array_size = O4; // number of frames (input) 1.3485 - Register O7frame_size = O7; // number of frames (input) 1.3486 - 1.3487 - __ ld_ptr(O3array, 0, O7frame_size); 1.3488 - __ sub(G0, O7frame_size, O7frame_size); 1.3489 - __ save(SP, O7frame_size, SP); 1.3490 - __ ld_ptr(G3pcs, 0, I7); // load frame's new pc 1.3491 - 1.3492 - #ifdef ASSERT 1.3493 - // make sure that the frames are aligned properly 1.3494 -#ifndef _LP64 1.3495 - __ btst(wordSize*2-1, SP); 1.3496 - __ breakpoint_trap(Assembler::notZero); 1.3497 -#endif 1.3498 - #endif 1.3499 - 1.3500 - // Deopt needs to pass some extra live values from frame to frame 1.3501 - 1.3502 - if (deopt) { 1.3503 - __ mov(Oreturn0->after_save(), Oreturn0); 1.3504 - __ mov(Oreturn1->after_save(), Oreturn1); 1.3505 - } 1.3506 - 1.3507 - __ mov(O4array_size->after_save(), O4array_size); 1.3508 - __ sub(O4array_size, 1, O4array_size); 1.3509 - __ mov(O3array->after_save(), O3array); 1.3510 - __ mov(O2UnrollBlock->after_save(), O2UnrollBlock); 1.3511 - __ add(G3pcs, wordSize, G3pcs); // point to next pc value 1.3512 - 1.3513 - #ifdef ASSERT 1.3514 - // trash registers to show a clear pattern in backtraces 1.3515 - __ set(0xDEAD0000, I0); 1.3516 - __ add(I0, 2, I1); 1.3517 - __ add(I0, 4, I2); 1.3518 - __ add(I0, 6, I3); 1.3519 - __ add(I0, 8, I4); 1.3520 - // Don't touch I5 could have valuable savedSP 1.3521 - __ set(0xDEADBEEF, L0); 1.3522 - __ mov(L0, L1); 1.3523 - __ mov(L0, L2); 1.3524 - __ mov(L0, L3); 1.3525 - __ mov(L0, L4); 1.3526 - __ mov(L0, L5); 1.3527 - 1.3528 - // trash the return value as there is nothing to return yet 1.3529 - __ set(0xDEAD0001, O7); 1.3530 - #endif 1.3531 - 1.3532 - __ mov(SP, O5_savedSP); 1.3533 -} 1.3534 - 1.3535 - 1.3536 -static void make_new_frames(MacroAssembler* masm, bool deopt) { 1.3537 - // 1.3538 - // loop through the UnrollBlock info and create new frames 1.3539 - // 1.3540 - Register G3pcs = G3_scratch; 1.3541 - Register Oreturn0 = O0; 1.3542 - Register Oreturn1 = O1; 1.3543 - Register O2UnrollBlock = O2; 1.3544 - Register O3array = O3; 1.3545 - Register O4array_size = O4; 1.3546 - Label loop; 1.3547 - 1.3548 - // Before we make new frames, check to see if stack is available. 1.3549 - // Do this after the caller's return address is on top of stack 1.3550 - if (UseStackBanging) { 1.3551 - // Get total frame size for interpreted frames 1.3552 - __ ld(Address(O2UnrollBlock, 0, 1.3553 - Deoptimization::UnrollBlock::total_frame_sizes_offset_in_bytes()), O4); 1.3554 - __ bang_stack_size(O4, O3, G3_scratch); 1.3555 - } 1.3556 - 1.3557 - __ ld(Address(O2UnrollBlock, 0, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()), O4array_size); 1.3558 - __ ld_ptr(Address(O2UnrollBlock, 0, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()), G3pcs); 1.3559 - 1.3560 - __ ld_ptr(Address(O2UnrollBlock, 0, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()), O3array); 1.3561 - 1.3562 - // Adjust old interpreter frame to make space for new frame's extra java locals 1.3563 - // 1.3564 - // We capture the original sp for the transition frame only because it is needed in 1.3565 - // order to properly calculate interpreter_sp_adjustment. Even though in real life 1.3566 - // every interpreter frame captures a savedSP it is only needed at the transition 1.3567 - // (fortunately). If we had to have it correct everywhere then we would need to 1.3568 - // be told the sp_adjustment for each frame we create. If the frame size array 1.3569 - // were to have twice the frame count entries then we could have pairs [sp_adjustment, frame_size] 1.3570 - // for each frame we create and keep up the illusion every where. 1.3571 - // 1.3572 - 1.3573 - __ ld(Address(O2UnrollBlock, 0, Deoptimization::UnrollBlock::caller_adjustment_offset_in_bytes()), O7); 1.3574 - __ mov(SP, O5_savedSP); // remember initial sender's original sp before adjustment 1.3575 - __ sub(SP, O7, SP); 1.3576 - 1.3577 -#ifdef ASSERT 1.3578 - // make sure that there is at least one entry in the array 1.3579 - __ tst(O4array_size); 1.3580 - __ breakpoint_trap(Assembler::zero); 1.3581 -#endif 1.3582 - 1.3583 - // Now push the new interpreter frames 1.3584 - __ bind(loop); 1.3585 - 1.3586 - // allocate a new frame, filling the registers 1.3587 - 1.3588 - gen_new_frame(masm, deopt); // allocate an interpreter frame 1.3589 - 1.3590 - __ tst(O4array_size); 1.3591 - __ br(Assembler::notZero, false, Assembler::pn, loop); 1.3592 - __ delayed()->add(O3array, wordSize, O3array); 1.3593 - __ ld_ptr(G3pcs, 0, O7); // load final frame new pc 1.3594 - 1.3595 -} 1.3596 -*/ 1.3597 1.3598 //------------------------------generate_deopt_blob---------------------------- 1.3599 // Ought to generate an ideal graph & compile, but here's some SPARC ASM 1.3600 @@ -3711,7 +3090,7 @@ 1.3601 Register unroll = S7; 1.3602 // Prolog for non exception case! 1.3603 // Correct the return address we were given. 1.3604 - //FIXME, return address is on the tos or Ra? 1.3605 + //FIXME, return address is on the tos or Ra? 1.3606 __ addi(RA, RA, - (NativeCall::return_address_offset_long)); 1.3607 // Save everything in sight. 1.3608 map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words); 1.3609 @@ -3722,13 +3101,12 @@ 1.3610 1.3611 int reexecute_offset = __ pc() - start; 1.3612 1.3613 - // Reexecute case 1.3614 - // return address is the pc describes what bci to do re-execute at 1.3615 - 1.3616 - // No need to update map as each call to save_live_registers will produce identical oopmap 1.3617 - //__ addi(RA, RA, - (NativeCall::return_address_offset)); 1.3618 + // Reexecute case 1.3619 + // return address is the pc describes what bci to do re-execute at 1.3620 + 1.3621 + // No need to update map as each call to save_live_registers will produce identical oopmap 1.3622 (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words); 1.3623 - __ move(reason, Deoptimization::Unpack_reexecute); 1.3624 + __ move(reason, Deoptimization::Unpack_reexecute); 1.3625 __ b(cont); 1.3626 __ delayed()->nop(); 1.3627 1.3628 @@ -3739,9 +3117,9 @@ 1.3629 // edx which contain the exception oop and exception pc 1.3630 // respectively. Set them in TLS and fall thru to the 1.3631 // unpack_with_exception_in_tls entry point. 1.3632 - 1.3633 + 1.3634 __ get_thread(thread); 1.3635 - __ st_ptr(V1, thread, in_bytes(JavaThread::exception_pc_offset())); 1.3636 + __ st_ptr(V1, thread, in_bytes(JavaThread::exception_pc_offset())); 1.3637 __ st_ptr(V0, thread, in_bytes(JavaThread::exception_oop_offset())); 1.3638 int exception_in_tls_offset = __ pc() - start; 1.3639 // new implementation because exception oop is now passed in JavaThread 1.3640 @@ -3752,9 +3130,9 @@ 1.3641 // tos: stack at point of call to method that threw the exception (i.e. only 1.3642 // args are on the stack, no return address) 1.3643 1.3644 - // Return address will be patched later with the throwing pc. The correct value is not 1.3645 + // Return address will be patched later with the throwing pc. The correct value is not 1.3646 // available now because loading it from memory would destroy registers. 1.3647 - // Save everything in sight. 1.3648 + // Save everything in sight. 1.3649 // No need to update map as each call to save_live_registers will produce identical oopmap 1.3650 __ addi(RA, RA, - (NativeCall::return_address_offset_long)); 1.3651 (void) RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words); 1.3652 @@ -3762,7 +3140,7 @@ 1.3653 // Now it is safe to overwrite any register 1.3654 // store the correct deoptimization type 1.3655 __ move(reason, Deoptimization::Unpack_exception); 1.3656 - // load throwing pc from JavaThread and patch it as the return address 1.3657 + // load throwing pc from JavaThread and patch it as the return address 1.3658 // of the current frame. Then clear the field in JavaThread 1.3659 __ get_thread(thread); 1.3660 __ ld_ptr(V1, thread, in_bytes(JavaThread::exception_pc_offset())); 1.3661 @@ -3777,8 +3155,8 @@ 1.3662 // verify that there is no pending exception 1.3663 Label no_pending_exception; 1.3664 __ ld_ptr(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.3665 - __ beq(AT, R0, no_pending_exception); 1.3666 - __ delayed()->nop(); 1.3667 + __ beq(AT, R0, no_pending_exception); 1.3668 + __ delayed()->nop(); 1.3669 __ stop("must not have pending exception here"); 1.3670 __ bind(no_pending_exception); 1.3671 #endif 1.3672 @@ -3788,7 +3166,7 @@ 1.3673 1.3674 1.3675 // Call C code. Need thread and this frame, but NOT official VM entry 1.3676 - // crud. We cannot block on this call, no GC can happen. 1.3677 + // crud. We cannot block on this call, no GC can happen. 1.3678 #ifndef OPT_THREAD 1.3679 __ get_thread(thread); 1.3680 #endif 1.3681 @@ -3801,8 +3179,8 @@ 1.3682 // Call fetch_unroll_info(). Need thread and this frame, but NOT official VM entry - cannot block on 1.3683 // this call, no GC can happen. Call should capture return values. 1.3684 1.3685 - __ relocate(relocInfo::internal_pc_type); 1.3686 - { 1.3687 + __ relocate(relocInfo::internal_pc_type); 1.3688 + { 1.3689 intptr_t save_pc = (intptr_t)__ pc() + NativeMovConstReg::instruction_size + 28; 1.3690 __ patchable_set48(AT, save_pc); 1.3691 } 1.3692 @@ -3824,7 +3202,6 @@ 1.3693 // we are very short of registers 1.3694 1.3695 Address unpack_kind(unroll, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()); 1.3696 - //__ pop(reason); 1.3697 __ sw(reason, unpack_kind); 1.3698 // save the unpack_kind value 1.3699 // Retrieve the possible live values (return values) 1.3700 @@ -3839,13 +3216,13 @@ 1.3701 __ ld_ptr(V1, thread, in_bytes(JavaThread::exception_pc_offset())); 1.3702 __ st_ptr(R0, thread, in_bytes(JavaThread::exception_pc_offset())); 1.3703 __ st_ptr(R0, thread, in_bytes(JavaThread::exception_oop_offset())); 1.3704 - 1.3705 + 1.3706 __ verify_oop(V0); 1.3707 1.3708 // Overwrite the result registers with the exception results. 1.3709 - __ st_ptr(V0, SP, RegisterSaver::v0Offset()*wordSize); 1.3710 + __ st_ptr(V0, SP, RegisterSaver::v0Offset()*wordSize); 1.3711 __ st_ptr(V1, SP, RegisterSaver::v1Offset()*wordSize); 1.3712 - 1.3713 + 1.3714 __ bind(noException); 1.3715 1.3716 1.3717 @@ -3856,11 +3233,11 @@ 1.3718 RegisterSaver::restore_result_registers(masm); 1.3719 // All of the register save area has been popped of the stack. Only the 1.3720 // return address remains. 1.3721 - // Pop all the frames we must move/replace. 1.3722 + // Pop all the frames we must move/replace. 1.3723 // Frame picture (youngest to oldest) 1.3724 // 1: self-frame (no frame link) 1.3725 // 2: deopting frame (no frame link) 1.3726 - // 3: caller of deopting frame (could be compiled/interpreted). 1.3727 + // 3: caller of deopting frame (could be compiled/interpreted). 1.3728 // 1.3729 // Note: by leaving the return address of self-frame on the stack 1.3730 // and using the size of frame 2 to adjust the stack 1.3731 @@ -3874,19 +3251,19 @@ 1.3732 Register sizes = T1; 1.3733 // register for frame count 1.3734 Register count = T3; 1.3735 - 1.3736 + 1.3737 // Pop deoptimized frame 1.3738 __ lw(AT, unroll, Deoptimization::UnrollBlock::size_of_deoptimized_frame_offset_in_bytes()); 1.3739 __ add(SP, SP, AT); 1.3740 // sp should be pointing at the return address to the caller (3) 1.3741 - 1.3742 + 1.3743 // Load array of frame pcs into pcs 1.3744 __ ld_ptr(pcs, unroll, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()); 1.3745 __ addi(SP, SP, wordSize); // trash the old pc 1.3746 // Load array of frame sizes into T6 1.3747 __ ld_ptr(sizes, unroll, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()); 1.3748 1.3749 - 1.3750 + 1.3751 1.3752 // Load count of frams into T3 1.3753 __ lw(count, unroll, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()); 1.3754 @@ -3904,14 +3281,14 @@ 1.3755 /* 1.3756 * 1.3757 Loop: 1.3758 - 0x000000555bd82d18: lw t2, 0x0(t1) ; lw sizes[i] <--- error lw->ld 1.3759 + 0x000000555bd82d18: lw t2, 0x0(t1) ; lw sizes[i] <--- error lw->ld 1.3760 0x000000555bd82d1c: ld at, 0x0(t0) ; ld pcs[i] 1.3761 - 0x000000555bd82d20: daddi t2, t2, 0xfffffff0 ; t2 -= 16 1.3762 + 0x000000555bd82d20: daddi t2, t2, 0xfffffff0 ; t2 -= 16 1.3763 0x000000555bd82d24: daddi sp, sp, 0xfffffff0 1.3764 0x000000555bd82d28: sd fp, 0x0(sp) ; push fp 1.3765 0x000000555bd82d2c: sd at, 0x8(sp) ; push at 1.3766 - 0x000000555bd82d30: dadd fp, sp, zero ; fp <- sp 1.3767 - 0x000000555bd82d34: dsub sp, sp, t2 ; sp -= t2 1.3768 + 0x000000555bd82d30: dadd fp, sp, zero ; fp <- sp 1.3769 + 0x000000555bd82d34: dsub sp, sp, t2 ; sp -= t2 1.3770 0x000000555bd82d38: sd zero, 0xfffffff0(fp) ; __ sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize); 1.3771 0x000000555bd82d3c: sd s4, 0xfffffff8(fp) ; __ sd(sender_sp, FP, frame::interpreter_frame_sender_sp_offset * wordSize); 1.3772 0x000000555bd82d40: dadd s4, sp, zero ; move(sender_sp, SP); 1.3773 @@ -3924,26 +3301,26 @@ 1.3774 // pcs[0] = frame_pcs[0] = deopt_sender.raw_pc(); regex.split 1.3775 Label loop; 1.3776 __ bind(loop); 1.3777 - __ ld(T2, sizes, 0); // Load frame size 1.3778 - __ ld_ptr(AT, pcs, 0); // save return address 1.3779 + __ ld(T2, sizes, 0); // Load frame size 1.3780 + __ ld_ptr(AT, pcs, 0); // save return address 1.3781 __ addi(T2, T2, -2*wordSize); // we'll push pc and rbp, by hand 1.3782 - __ push2(AT, FP); 1.3783 + __ push2(AT, FP); 1.3784 __ move(FP, SP); 1.3785 - __ sub(SP, SP, T2); // Prolog! 1.3786 + __ sub(SP, SP, T2); // Prolog! 1.3787 // This value is corrected by layout_activation_impl 1.3788 - __ sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize); 1.3789 + __ sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize); 1.3790 __ sd(sender_sp, FP, frame::interpreter_frame_sender_sp_offset * wordSize);// Make it walkable 1.3791 - __ move(sender_sp, SP); // pass to next frame 1.3792 - __ addi(count, count, -1); // decrement counter 1.3793 - __ addi(sizes, sizes, wordSize); // Bump array pointer (sizes) 1.3794 + __ move(sender_sp, SP); // pass to next frame 1.3795 + __ addi(count, count, -1); // decrement counter 1.3796 + __ addi(sizes, sizes, wordSize); // Bump array pointer (sizes) 1.3797 __ bne(count, R0, loop); 1.3798 - __ delayed()->addi(pcs, pcs, wordSize); // Bump array pointer (pcs) 1.3799 - __ ld(AT, pcs, 0); // frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0); 1.3800 + __ delayed()->addi(pcs, pcs, wordSize); // Bump array pointer (pcs) 1.3801 + __ ld(AT, pcs, 0); // frame_pcs[number_of_frames] = Interpreter::deopt_entry(vtos, 0); 1.3802 // Re-push self-frame 1.3803 - __ push2(AT, FP); 1.3804 + __ push2(AT, FP); 1.3805 __ move(FP, SP); 1.3806 - __ sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize); 1.3807 - __ sd(sender_sp, FP, frame::interpreter_frame_sender_sp_offset * wordSize); 1.3808 + __ sd(R0, FP, frame::interpreter_frame_last_sp_offset * wordSize); 1.3809 + __ sd(sender_sp, FP, frame::interpreter_frame_sender_sp_offset * wordSize); 1.3810 __ addi(SP, SP, -(frame_size_in_words - 2 - additional_words) * wordSize); 1.3811 1.3812 // Restore frame locals after moving the frame 1.3813 @@ -3952,12 +3329,12 @@ 1.3814 __ sdc1(F0, SP, RegisterSaver::fpResultOffset()* wordSize);// Pop float stack and store in local 1.3815 __ sdc1(F1, SP, (RegisterSaver::fpResultOffset() + 1) * wordSize); 1.3816 1.3817 - 1.3818 + 1.3819 // Call unpack_frames(). Need thread and this frame, but NOT official VM entry - cannot block on 1.3820 // this call, no GC can happen. 1.3821 - __ move(A1, reason); // exec_mode 1.3822 + __ move(A1, reason); // exec_mode 1.3823 __ get_thread(thread); 1.3824 - __ move(A0, thread); // thread 1.3825 + __ move(A0, thread); // thread 1.3826 __ addi(SP, SP, (-additional_words) *wordSize); 1.3827 1.3828 // set last_Java_sp, last_Java_fp 1.3829 @@ -3966,14 +3343,13 @@ 1.3830 __ move(AT, -(StackAlignmentInBytes)); 1.3831 __ andr(SP, SP, AT); // Fix stack alignment as required by ABI 1.3832 1.3833 - __ relocate(relocInfo::internal_pc_type); 1.3834 - { 1.3835 + __ relocate(relocInfo::internal_pc_type); 1.3836 + { 1.3837 intptr_t save_pc = (intptr_t)__ pc() + NativeMovConstReg::instruction_size + 28; 1.3838 __ patchable_set48(AT, save_pc); 1.3839 } 1.3840 __ sd(AT, thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset())); 1.3841 - 1.3842 - //__ call(Deoptimization::unpack_frames); 1.3843 + 1.3844 __ call(CAST_FROM_FN_PTR(address, Deoptimization::unpack_frames), relocInfo::runtime_call_type); 1.3845 __ delayed()->nop(); 1.3846 // Revert SP alignment after call since we're going to do some SP relative addressing below 1.3847 @@ -3982,7 +3358,7 @@ 1.3848 oop_maps->add_gc_map(__ offset(), new OopMap( frame_size_in_words , 0)); 1.3849 1.3850 __ push(V0); 1.3851 - 1.3852 + 1.3853 __ get_thread(thread); 1.3854 __ reset_last_Java_frame(true, true); 1.3855 1.3856 @@ -3991,7 +3367,7 @@ 1.3857 __ ld(V1, SP, (RegisterSaver::v1Offset() + additional_words +1) * wordSize); 1.3858 __ ldc1(F0, SP, RegisterSaver::fpResultOffset()* wordSize);// Pop float stack and store in local 1.3859 __ ldc1(F1, SP, (RegisterSaver::fpResultOffset() + 1) * wordSize); 1.3860 - //FIXME, 1.3861 + //FIXME, 1.3862 // Clear floating point stack before returning to interpreter 1.3863 __ empty_FPU_stack(); 1.3864 //FIXME, we should consider about float and double 1.3865 @@ -4016,20 +3392,20 @@ 1.3866 // allocate space for the code 1.3867 ResourceMark rm; 1.3868 // setup code generation tools 1.3869 - CodeBuffer buffer ("uncommon_trap_blob", 512*80 , 512*40 ); 1.3870 - MacroAssembler* masm = new MacroAssembler(&buffer); 1.3871 + CodeBuffer buffer ("uncommon_trap_blob", 512*80 , 512*40 ); 1.3872 + MacroAssembler* masm = new MacroAssembler(&buffer); 1.3873 1.3874 enum frame_layout { 1.3875 - s0_off, s0_off2, 1.3876 - s1_off, s1_off2, 1.3877 - s2_off, s2_off2, 1.3878 - s3_off, s3_off2, 1.3879 - s4_off, s4_off2, 1.3880 - s5_off, s5_off2, 1.3881 - s6_off, s6_off2, 1.3882 - s7_off, s7_off2, 1.3883 - fp_off, fp_off2, 1.3884 - return_off, return_off2, // slot for return address sp + 9 1.3885 + s0_off, s0_off2, 1.3886 + s1_off, s1_off2, 1.3887 + s2_off, s2_off2, 1.3888 + s3_off, s3_off2, 1.3889 + s4_off, s4_off2, 1.3890 + s5_off, s5_off2, 1.3891 + s6_off, s6_off2, 1.3892 + s7_off, s7_off2, 1.3893 + fp_off, fp_off2, 1.3894 + return_off, return_off2, // slot for return address sp + 9 1.3895 framesize 1.3896 }; 1.3897 assert(framesize % 4 == 0, "sp not 16-byte aligned"); 1.3898 @@ -4042,7 +3418,7 @@ 1.3899 __ sd(RA, SP, return_off * BytesPerInt); 1.3900 __ sd(FP, SP, fp_off * BytesPerInt); 1.3901 1.3902 - // Save callee saved registers. None for UseSSE=0, 1.3903 + // Save callee saved registers. None for UseSSE=0, 1.3904 // floats-only for UseSSE=1, and doubles for UseSSE=2. 1.3905 __ sd(S0, SP, s0_off * BytesPerInt); 1.3906 __ sd(S1, SP, s1_off * BytesPerInt); 1.3907 @@ -4065,8 +3441,8 @@ 1.3908 #endif 1.3909 // set last_Java_sp 1.3910 __ set_last_Java_frame(NOREG, FP, NULL); 1.3911 - __ relocate(relocInfo::internal_pc_type); 1.3912 - { 1.3913 + __ relocate(relocInfo::internal_pc_type); 1.3914 + { 1.3915 long save_pc = (long)__ pc() + 52; 1.3916 __ patchable_set48(AT, (long)save_pc); 1.3917 __ sd(AT, thread, in_bytes(JavaThread::frame_anchor_offset() + JavaFrameAnchor::last_Java_pc_offset())); 1.3918 @@ -4083,7 +3459,7 @@ 1.3919 OopMapSet *oop_maps = new OopMapSet(); 1.3920 OopMap* map = new OopMap( framesize, 0 ); 1.3921 1.3922 - map->set_callee_saved( VMRegImpl::stack2reg(s0_off ), S0->as_VMReg() ); 1.3923 + map->set_callee_saved( VMRegImpl::stack2reg(s0_off ), S0->as_VMReg() ); 1.3924 map->set_callee_saved( VMRegImpl::stack2reg(s1_off ), S1->as_VMReg() ); 1.3925 map->set_callee_saved( VMRegImpl::stack2reg(s2_off ), S2->as_VMReg() ); 1.3926 map->set_callee_saved( VMRegImpl::stack2reg(s3_off ), S3->as_VMReg() ); 1.3927 @@ -4093,7 +3469,7 @@ 1.3928 map->set_callee_saved( VMRegImpl::stack2reg(s7_off ), S7->as_VMReg() ); 1.3929 1.3930 //oop_maps->add_gc_map( __ offset(), true, map); 1.3931 - oop_maps->add_gc_map( __ offset(), map); 1.3932 + oop_maps->add_gc_map( __ offset(), map); 1.3933 1.3934 #ifndef OPT_THREAD 1.3935 __ get_thread(thread); 1.3936 @@ -4104,12 +3480,12 @@ 1.3937 Register unroll = S7; 1.3938 __ move(unroll, V0); 1.3939 1.3940 - // Pop all the frames we must move/replace. 1.3941 - // 1.3942 + // Pop all the frames we must move/replace. 1.3943 + // 1.3944 // Frame picture (youngest to oldest) 1.3945 // 1: self-frame (no frame link) 1.3946 // 2: deopting frame (no frame link) 1.3947 - // 3: possible-i2c-adapter-frame 1.3948 + // 3: possible-i2c-adapter-frame 1.3949 // 4: caller of deopting frame (could be compiled/interpreted. If interpreted we will create an 1.3950 // and c2i here) 1.3951 1.3952 @@ -4133,10 +3509,6 @@ 1.3953 // Load array of frame pcs into ECX 1.3954 __ ld(pcs, unroll, Deoptimization::UnrollBlock::frame_pcs_offset_in_bytes()); 1.3955 1.3956 -/* 2012/9/7 Not needed in MIPS 1.3957 - __ addiu(SP, SP, wordSize); 1.3958 -*/ 1.3959 - 1.3960 // Load array of frame sizes into ESI 1.3961 __ ld(sizes, unroll, Deoptimization::UnrollBlock::frame_sizes_offset_in_bytes()); 1.3962 __ lwu(count, unroll, Deoptimization::UnrollBlock::number_of_frames_offset_in_bytes()); 1.3963 @@ -4176,7 +3548,7 @@ 1.3964 __ daddi(SP, SP, - 2 * wordSize); // save old & set new FP 1.3965 __ sd(FP, SP, 0 * wordSize); // save final return address 1.3966 __ sd(RA, SP, 1 * wordSize); 1.3967 - __ move(FP, SP); 1.3968 + __ move(FP, SP); 1.3969 __ daddi(SP, SP, -(framesize / 2 - 2) * wordSize); 1.3970 1.3971 // set last_Java_sp, last_Java_fp 1.3972 @@ -4185,8 +3557,8 @@ 1.3973 __ move(AT, -(StackAlignmentInBytes)); 1.3974 __ andr(SP, SP, AT); // Fix stack alignment as required by ABI 1.3975 1.3976 - __ relocate(relocInfo::internal_pc_type); 1.3977 - { 1.3978 + __ relocate(relocInfo::internal_pc_type); 1.3979 + { 1.3980 long save_pc = (long)__ pc() + 52; 1.3981 __ patchable_set48(AT, (long)save_pc); 1.3982 } 1.3983 @@ -4199,7 +3571,7 @@ 1.3984 __ move(A1, Deoptimization::Unpack_uncommon_trap); 1.3985 __ patchable_call((address)Deoptimization::unpack_frames); 1.3986 // Set an oopmap for the call site 1.3987 - //oop_maps->add_gc_map( __ offset(), true, new OopMap( framesize, 0 ) ); 1.3988 + //oop_maps->add_gc_map( __ offset(), true, new OopMap( framesize, 0 ) ); 1.3989 oop_maps->add_gc_map( __ offset(), new OopMap( framesize, 0 ) );//Fu 1.3990 1.3991 __ reset_last_Java_frame(true,true); 1.3992 @@ -4226,28 +3598,28 @@ 1.3993 // a safepoint. 1.3994 // 1.3995 // This blob is jumped to (via a breakpoint and the signal handler) from a 1.3996 -// safepoint in compiled code. 1.3997 - 1.3998 +// safepoint in compiled code. 1.3999 + 1.4000 SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int pool_type) { 1.4001 1.4002 // Account for thread arg in our frame 1.4003 - const int additional_words = 0; 1.4004 + const int additional_words = 0; 1.4005 int frame_size_in_words; 1.4006 1.4007 - assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before"); 1.4008 + assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before"); 1.4009 1.4010 ResourceMark rm; 1.4011 OopMapSet *oop_maps = new OopMapSet(); 1.4012 OopMap* map; 1.4013 1.4014 // allocate space for the code 1.4015 - // setup code generation tools 1.4016 + // setup code generation tools 1.4017 CodeBuffer buffer ("handler_blob", 2048, 512); 1.4018 MacroAssembler* masm = new MacroAssembler( &buffer); 1.4019 - 1.4020 - const Register thread = TREG; 1.4021 - address start = __ pc(); 1.4022 - address call_pc = NULL; 1.4023 + 1.4024 + const Register thread = TREG; 1.4025 + address start = __ pc(); 1.4026 + address call_pc = NULL; 1.4027 bool cause_return = (pool_type == POLL_AT_RETURN); 1.4028 bool save_vectors = (pool_type == POLL_AT_VECTOR_LOOP); 1.4029 1.4030 @@ -4264,7 +3636,7 @@ 1.4031 if(!cause_return) { 1.4032 __ ld_ptr(RA, Address(thread, JavaThread::saved_exception_pc_offset())); 1.4033 } 1.4034 - 1.4035 + 1.4036 __ pop(thread); 1.4037 map = RegisterSaver::save_live_registers(masm, additional_words, &frame_size_in_words, save_vectors); 1.4038 1.4039 @@ -4278,16 +3650,6 @@ 1.4040 __ move(A0, thread); 1.4041 __ set_last_Java_frame(NOREG, NOREG, NULL); 1.4042 1.4043 - //__ relocate(relocInfo::internal_pc_type); 1.4044 - if (!cause_return) 1.4045 - { 1.4046 -/* 1.4047 - intptr_t save_pc = (intptr_t)__ pc() + NativeMovConstReg::instruction_size + NativeCall::return_address_offset + 4; 1.4048 - __ li48(AT, save_pc); 1.4049 - __ sd(AT, thread, in_bytes(JavaThread::last_Java_pc_offset())); 1.4050 -*/ 1.4051 - } 1.4052 - 1.4053 1.4054 // do the call 1.4055 //__ lui(T9, Assembler::split_high((int)call_ptr)); 1.4056 @@ -4315,21 +3677,19 @@ 1.4057 RegisterSaver::restore_live_registers(masm, save_vectors); 1.4058 //forward_exception_entry need return address on the stack 1.4059 __ push(RA); 1.4060 - //__ lui(T9, Assembler::split_high((int)StubRoutines::forward_exception_entry())); 1.4061 - //__ addiu(T9, T9, Assembler::split_low((int)StubRoutines::forward_exception_entry())); 1.4062 __ patchable_jump((address)StubRoutines::forward_exception_entry()); 1.4063 1.4064 // No exception case 1.4065 __ bind(noException); 1.4066 - // Normal exit, register restoring and exit 1.4067 + // Normal exit, register restoring and exit 1.4068 RegisterSaver::restore_live_registers(masm, save_vectors); 1.4069 __ jr(RA); 1.4070 __ delayed()->nop(); 1.4071 - 1.4072 - masm->flush(); 1.4073 + 1.4074 + masm->flush(); 1.4075 1.4076 // Fill-out other meta info 1.4077 - return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words); 1.4078 + return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words); 1.4079 } 1.4080 1.4081 // 1.4082 @@ -4352,7 +3712,7 @@ 1.4083 MacroAssembler* masm = new MacroAssembler(&buffer); 1.4084 1.4085 int frame_size_words; 1.4086 - //we put the thread in A0 1.4087 + //we put the thread in A0 1.4088 1.4089 OopMapSet *oop_maps = new OopMapSet(); 1.4090 OopMap* map = NULL; 1.4091 @@ -4366,16 +3726,14 @@ 1.4092 const Register thread = T8; 1.4093 __ get_thread(thread); 1.4094 1.4095 - __ move(A0, thread); 1.4096 + __ move(A0, thread); 1.4097 __ set_last_Java_frame(noreg, FP, NULL); 1.4098 - //__ addi(SP, SP, -wordSize); 1.4099 - //align the stack before invoke native 1.4100 + //align the stack before invoke native 1.4101 __ move(AT, -(StackAlignmentInBytes)); 1.4102 - __ andr(SP, SP, AT); 1.4103 - __ relocate(relocInfo::internal_pc_type); 1.4104 - { 1.4105 + __ andr(SP, SP, AT); 1.4106 + __ relocate(relocInfo::internal_pc_type); 1.4107 + { 1.4108 intptr_t save_pc = (intptr_t)__ pc() + NativeMovConstReg::instruction_size + 24 + 1 * BytesPerInstWord; 1.4109 -//tty->print_cr(" %s :%d, name:%s, pc: %lx, save_pc: %lx, frame_size_words: %lx", __func__, __LINE__, name, __ pc(), save_pc, frame_size_words); //aoqi_test 1.4110 __ patchable_set48(AT, save_pc); 1.4111 } 1.4112 __ sd(AT, thread, in_bytes(JavaThread::last_Java_pc_offset())); 1.4113 @@ -4396,9 +3754,9 @@ 1.4114 Label pending; 1.4115 __ ld_ptr(AT, thread, in_bytes(Thread::pending_exception_offset())); 1.4116 __ bne(AT, R0, pending); 1.4117 - __ delayed()->nop(); 1.4118 - // get the returned Method* 1.4119 - //FIXME, do mips need this ? 1.4120 + __ delayed()->nop(); 1.4121 + // get the returned Method* 1.4122 + //FIXME, do mips need this ? 1.4123 __ get_vm_result_2(Rmethod, thread); // Refer to OpenJDK8 1.4124 __ st_ptr(Rmethod, SP, RegisterSaver::methodOffset() * wordSize); 1.4125 __ st_ptr(V0, SP, RegisterSaver::v0Offset() * wordSize); 1.4126 @@ -4414,42 +3772,21 @@ 1.4127 RegisterSaver::restore_live_registers(masm); 1.4128 1.4129 // exception pending => remove activation and forward to exception handler 1.4130 - //forward_exception_entry need return address on the stack 1.4131 + //forward_exception_entry need return address on the stack 1.4132 __ push(RA); 1.4133 __ get_thread(thread); 1.4134 - __ st_ptr(R0, thread, in_bytes(JavaThread::vm_result_offset())); 1.4135 + __ st_ptr(R0, thread, in_bytes(JavaThread::vm_result_offset())); 1.4136 __ ld_ptr(V0, thread, in_bytes(Thread::pending_exception_offset())); 1.4137 __ jmp(StubRoutines::forward_exception_entry(), relocInfo::runtime_call_type); 1.4138 __ delayed() -> nop(); 1.4139 // ------------- 1.4140 // make sure all code is generated 1.4141 - masm->flush(); 1.4142 + masm->flush(); 1.4143 1.4144 RuntimeStub* tmp= RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_words, oop_maps, true); 1.4145 return tmp; 1.4146 } 1.4147 1.4148 -/*void SharedRuntime::generate_stubs() { 1.4149 - _wrong_method_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, 1.4150 - SharedRuntime::handle_wrong_method),"wrong_method_stub"); 1.4151 - _ic_miss_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, 1.4152 - SharedRuntime::handle_wrong_method_ic_miss),"ic_miss_stub"); 1.4153 - _resolve_opt_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, 1.4154 - SharedRuntime::resolve_opt_virtual_call_C),"resolve_opt_virtual_call"); 1.4155 - _resolve_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, 1.4156 - SharedRuntime::resolve_virtual_call_C),"resolve_virtual_call"); 1.4157 - _resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, 1.4158 - SharedRuntime::resolve_static_call_C),"resolve_static_call"); 1.4159 - _polling_page_safepoint_handler_blob =generate_handler_blob(CAST_FROM_FN_PTR(address, 1.4160 - SafepointSynchronize::handle_polling_page_exception), false); 1.4161 - _polling_page_return_handler_blob =generate_handler_blob(CAST_FROM_FN_PTR(address, 1.4162 - SafepointSynchronize::handle_polling_page_exception), true); 1.4163 - generate_deopt_blob(); 1.4164 -#ifdef COMPILER2 1.4165 - generate_uncommon_trap_blob(); 1.4166 -#endif // COMPILER2 1.4167 -}*/ 1.4168 - 1.4169 extern "C" int SpinPause() {return 0;} 1.4170 // extern "C" int SafeFetch32 (int * adr, int errValue) {return 0;} ; 1.4171 // extern "C" intptr_t SafeFetchN (intptr_t * adr, intptr_t errValue) {return *adr; } ;