1.1 --- a/src/cpu/mips/vm/c1_Runtime1_mips.cpp Sat Jan 06 16:30:58 2018 +0800 1.2 +++ b/src/cpu/mips/vm/c1_Runtime1_mips.cpp Thu May 24 19:49:50 2018 +0800 1.3 @@ -60,9 +60,7 @@ 1.4 1.5 1.6 // push java thread (becomes first argument of C function) 1.7 -#ifndef OPT_THREAD 1.8 get_thread(thread); 1.9 -#endif 1.10 move(A0, thread); 1.11 1.12 set_last_Java_frame(thread, NOREG, FP, NULL); 1.13 @@ -139,8 +137,7 @@ 1.14 } else if (_stub_id == Runtime1::forward_exception_id) { 1.15 should_not_reach_here(); 1.16 } else { 1.17 - jmp(Runtime1::entry_for(Runtime1::forward_exception_id), 1.18 - relocInfo::runtime_call_type); 1.19 + jmp(Runtime1::entry_for(Runtime1::forward_exception_id), relocInfo::runtime_call_type); 1.20 delayed()->nop(); 1.21 } 1.22 bind(L); 1.23 @@ -327,9 +324,10 @@ 1.24 static OopMap* generate_oop_map(StubAssembler* sasm, int num_rt_args, 1.25 bool save_fpu_registers = true, bool describe_fpu_registers = false) { 1.26 1.27 - /* Jin: num_rt_args is caculated by 8 bytes. */ 1.28 - int frame_size_in_slots = reg_save_frame_size + num_rt_args * wordSize / SLOT_PER_WORD; // args + thread 1.29 - sasm->set_frame_size(frame_size_in_slots / SLOT_PER_WORD); 1.30 + LP64_ONLY(num_rt_args = 0); 1.31 + LP64_ONLY(assert((reg_save_frame_size * VMRegImpl::stack_slot_size) % 16 == 0, "must be 16 byte aligned");) 1.32 + int frame_size_in_slots = reg_save_frame_size + num_rt_args * wordSize / VMRegImpl::slots_per_word; // args + thread 1.33 + sasm->set_frame_size(frame_size_in_slots / VMRegImpl::slots_per_word); 1.34 1.35 // record saved value locations in an OopMap 1.36 // locations are offsets from sp after runtime call; num_rt_args is number of arguments 1.37 @@ -407,9 +405,8 @@ 1.38 } 1.39 1.40 //FIXME, Is it enough to save this registers by yyq 1.41 -static OopMap* save_live_registers(StubAssembler* sasm, 1.42 - int num_rt_args, 1.43 - bool save_fpu_registers = true, 1.44 +static OopMap* save_live_registers(StubAssembler* sasm, int num_rt_args, 1.45 + bool save_fpu_registers = true, 1.46 bool describe_fpu_registers = false) { 1.47 //const int reg_save_frame_size = return_off + 1 + num_rt_args; 1.48 __ block_comment("save_live_registers"); 1.49 @@ -607,57 +604,59 @@ 1.50 1.51 //FIXME I do not know which reigster to use.should use T3 as real_return_addr @jerome 1.52 OopMapSet* Runtime1::generate_handle_exception(StubID id, StubAssembler *sasm) { 1.53 - __ block_comment("generate_handle_exception"); 1.54 - // incoming parameters 1.55 + __ block_comment("generate_handle_exception"); 1.56 + 1.57 + // incoming parameters 1.58 const Register exception_oop = V0; 1.59 const Register exception_pc = V1; 1.60 // other registers used in this stub 1.61 -// const Register real_return_addr = T3; 1.62 - const Register thread = T8; 1.63 + // const Register real_return_addr = T3; 1.64 + const Register thread = TREG; 1.65 +#ifndef OPT_THREAD 1.66 + __ get_thread(thread); 1.67 +#endif 1.68 // Save registers, if required. 1.69 - OopMapSet* oop_maps = new OopMapSet(); 1.70 - OopMap* oop_map = NULL; 1.71 - switch (id) { 1.72 - case forward_exception_id: 1.73 - // We're handling an exception in the context of a compiled frame. 1.74 - // The registers have been saved in the standard places. Perform 1.75 - // an exception lookup in the caller and dispatch to the handler 1.76 - // if found. Otherwise unwind and dispatch to the callers 1.77 - // exception handler. 1.78 - oop_map = generate_oop_map(sasm, 1 /*thread*/); 1.79 + OopMapSet* oop_maps = new OopMapSet(); 1.80 + OopMap* oop_map = NULL; 1.81 + switch (id) { 1.82 + case forward_exception_id: 1.83 + // We're handling an exception in the context of a compiled frame. 1.84 + // The registers have been saved in the standard places. Perform 1.85 + // an exception lookup in the caller and dispatch to the handler 1.86 + // if found. Otherwise unwind and dispatch to the callers 1.87 + // exception handler. 1.88 + oop_map = generate_oop_map(sasm, 1 /*thread*/); 1.89 1.90 - // load and clear pending exception oop into RAX 1.91 - __ ld(exception_oop, Address(thread, Thread::pending_exception_offset())); 1.92 - __ sw(R0,Address(thread, Thread::pending_exception_offset())); 1.93 + // load and clear pending exception oop into RAX 1.94 + __ ld_ptr(exception_oop, Address(thread, Thread::pending_exception_offset())); 1.95 + __ st_ptr(R0, Address(thread, Thread::pending_exception_offset())); 1.96 1.97 - // load issuing PC (the return address for this stub) into rdx 1.98 - __ ld(exception_pc, Address(FP, 1*BytesPerWord)); 1.99 + // load issuing PC (the return address for this stub) into rdx 1.100 + __ ld_ptr(exception_pc, Address(FP, 1*BytesPerWord)); 1.101 1.102 - // make sure that the vm_results are cleared (may be unnecessary) 1.103 - __ sw(R0,Address(thread, JavaThread::vm_result_offset())); 1.104 - __ sw(R0,Address(thread, JavaThread::vm_result_2_offset())); 1.105 - break; 1.106 - case handle_exception_nofpu_id: 1.107 - case handle_exception_id: 1.108 - // At this point all registers MAY be live. 1.109 - oop_map = save_live_registers(sasm, 1 /*thread*/, id == handle_exception_nofpu_id); 1.110 - break; 1.111 - case handle_exception_from_callee_id: { 1.112 - // At this point all registers except exception oop (RAX) and 1.113 - // exception pc (RDX) are dead. 1.114 - const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/) WIN64_ONLY(+ frame::arg_reg_save_area_by tes / BytesPerWord); 1.115 - oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0); 1.116 - sasm->set_frame_size(frame_size); 1.117 - WIN64_ONLY(__ subq(rsp, frame::arg_reg_save_area_bytes)); 1.118 - break; 1.119 - } 1.120 - default: ShouldNotReachHere(); 1.121 - } 1.122 + // make sure that the vm_results are cleared (may be unnecessary) 1.123 + __ st_ptr(R0, Address(thread, JavaThread::vm_result_offset())); 1.124 + __ st_ptr(R0, Address(thread, JavaThread::vm_result_2_offset())); 1.125 + break; 1.126 + case handle_exception_nofpu_id: 1.127 + case handle_exception_id: 1.128 + // At this point all registers MAY be live. 1.129 + oop_map = save_live_registers(sasm, 1 /*thread*/, id != handle_exception_nofpu_id); 1.130 + break; 1.131 + case handle_exception_from_callee_id: { 1.132 + // At this point all registers except exception oop (RAX) and 1.133 + // exception pc (RDX) are dead. 1.134 + const int frame_size = 2 /*BP, return address*/ NOT_LP64(+ 1 /*thread*/); 1.135 + oop_map = new OopMap(frame_size * VMRegImpl::slots_per_word, 0); 1.136 + sasm->set_frame_size(frame_size); 1.137 + break; 1.138 + } 1.139 + default: ShouldNotReachHere(); 1.140 + } 1.141 1.142 #ifdef TIERED 1.143 // C2 can leave the fpu stack dirty 1.144 __ empty_FPU_stack(); 1.145 - //} 1.146 #endif // TIERED 1.147 1.148 // verify that only V0 and V1 is valid at this time 1.149 @@ -689,16 +688,12 @@ 1.150 __ st_ptr(exception_oop, Address(thread, in_bytes(JavaThread::exception_oop_offset()))); 1.151 __ st_ptr(exception_pc, Address(thread, in_bytes(JavaThread::exception_pc_offset()))); 1.152 1.153 - // save real return address (pc that called this stub) 1.154 -// __ ld_ptr(real_return_addr, FP, 1*BytesPerWord); 1.155 -// __ st_ptr(real_return_addr, SP, temp_1_off * BytesPerWord / SLOT_PER_WORD); 1.156 + // patch throwing pc into return address (has bci & oop map) 1.157 + __ st_ptr(exception_pc, Address(FP, 1*BytesPerWord)); 1.158 1.159 - // patch throwing pc into return address (has bci & oop map) 1.160 - __ st_ptr(exception_pc, FP, 1*BytesPerWord); 1.161 // compute the exception handler. 1.162 // the exception oop and the throwing pc are read from the fields in JavaThread 1.163 - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, 1.164 - exception_handler_for_pc)); 1.165 + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, exception_handler_for_pc)); 1.166 oop_maps->add_gc_map(call_offset, oop_map); 1.167 // V0: handler address or NULL if no handler exists 1.168 // will be the deopt blob if nmethod was deoptimized while we looked up 1.169 @@ -707,75 +702,38 @@ 1.170 // only V0 is valid at this time, all other registers have been destroyed by the 1.171 // runtime call 1.172 1.173 - // Do we have an exception handler in the nmethod? 1.174 - /*Label no_handler; 1.175 - Label done; 1.176 - __ beq(V0, R0, no_handler); 1.177 - __ delayed()->nop(); */ 1.178 - // exception handler found 1.179 // patch the return address -> the stub will directly return to the exception handler 1.180 - __ st_ptr(V0, FP, 1 * BytesPerWord); 1.181 + __ st_ptr(V0, Address(FP, 1 * BytesPerWord)); 1.182 1.183 - // restore registers 1.184 -// restore_live_registers(sasm, save_fpu_registers); 1.185 + switch (id) { 1.186 + case forward_exception_id: 1.187 + case handle_exception_nofpu_id: 1.188 + case handle_exception_id: 1.189 + // Restore the registers that were saved at the beginning. 1.190 + restore_live_registers(sasm, id != handle_exception_nofpu_id); 1.191 + break; 1.192 + case handle_exception_from_callee_id: 1.193 + // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP 1.194 + // since we do a leave anyway. 1.195 1.196 - // return to exception handler 1.197 -// __ leave(); 1.198 -// __ jr(RA); 1.199 -// __ delayed()->nop(); 1.200 -// __ bind(no_handler); 1.201 - // no exception handler found in this method, so the exception is 1.202 - // forwarded to the caller (using the unwind code of the nmethod) 1.203 - // there is no need to restore the registers 1.204 + // Pop the return address since we are possibly changing SP (restoring from BP). 1.205 + __ leave(); 1.206 + // Restore SP from BP if the exception PC is a method handle call site. 1.207 + { 1.208 + Label done; 1.209 + __ ld(AT, Address(thread, JavaThread::is_method_handle_return_offset())); 1.210 + __ beq(AT, R0, done); 1.211 + __ delayed()->nop(); 1.212 + __ bind(done); 1.213 + } 1.214 + __ jr(RA); // jump to exception handler 1.215 + __ delayed()->nop(); 1.216 + break; 1.217 + default: ShouldNotReachHere(); 1.218 + } 1.219 1.220 - // restore the real return address that was saved before the RT-call 1.221 -// __ ld_ptr(real_return_addr, SP, temp_1_off * BytesPerWord / SLOT_PER_WORD); 1.222 -// __ st_ptr(real_return_addr, FP, 1 * BytesPerWord); 1.223 - // load address of JavaThread object for thread-local data 1.224 -// __ get_thread(thread); 1.225 - // restore exception oop into eax (convention for unwind code) 1.226 -// __ ld_ptr(exception_oop, thread, in_bytes(JavaThread::exception_oop_offset())); 1.227 - 1.228 - // clear exception fields in JavaThread because they are no longer needed 1.229 - // (fields must be cleared because they are processed by GC otherwise) 1.230 -// __ st_ptr(R0, thread, in_bytes(JavaThread::exception_oop_offset())); 1.231 -// __ st_ptr(R0,thread, in_bytes(JavaThread::exception_pc_offset())); 1.232 - // pop the stub frame off 1.233 -// __ leave(); 1.234 -// generate_unwind_exception(sasm); 1.235 -// __ stop("should not reach here"); 1.236 -//} 1.237 - switch (id) { 1.238 - case forward_exception_id: 1.239 - case handle_exception_nofpu_id: 1.240 - case handle_exception_id: 1.241 - // Restore the registers that were saved at the beginning. 1.242 - restore_live_registers(sasm, id == handle_exception_nofpu_id); 1.243 - break; 1.244 - case handle_exception_from_callee_id: 1.245 - // WIN64_ONLY: No need to add frame::arg_reg_save_area_bytes to SP 1.246 - // since we do a leave anyway. 1.247 - 1.248 - // Pop the return address since we are possibly changing SP (restoring from BP). 1.249 - __ leave(); 1.250 - // Restore SP from BP if the exception PC is a method handle call site. 1.251 - NOT_LP64(__ get_thread(thread);) 1.252 - /*__ ld(AT, Address(thread, JavaThread::is_method_handle_return_offset())); 1.253 - __ beq(AT, R0, done); 1.254 - __ move(SP, rbp_mh_SP_save); 1.255 - __ bind(done); 1.256 - __ jr(RA); // jump to exception handler 1.257 - __ delayed()->nop();*/ 1.258 -// 759 __ cmpl(Address(thread, JavaThread::is_method_handle_return_offset()), 0); 1.259 -// 760 __ cmovptr(Assembler::notEqual, rsp, rbp_mh_SP_save); 1.260 -// 761 __ jmp(rcx); // jump to exception handler 1.261 - 1.262 - break; 1.263 - default: ShouldNotReachHere(); 1.264 - } 1.265 - 1.266 - return oop_maps; 1.267 - } 1.268 + return oop_maps; 1.269 +} 1.270 1.271 1.272 1.273 @@ -784,10 +742,12 @@ 1.274 void Runtime1::generate_unwind_exception(StubAssembler *sasm) { 1.275 // incoming parameters 1.276 const Register exception_oop = V0; 1.277 + // callee-saved copy of exception_oop during runtime call 1.278 + const Register exception_oop_callee_saved = S0; 1.279 // other registers used in this stub 1.280 const Register exception_pc = V1; 1.281 const Register handler_addr = T3; 1.282 - const Register thread = T8; 1.283 + const Register thread = TREG; 1.284 1.285 // verify that only eax is valid at this time 1.286 // __ invalidate_registers(false, true, true, true, true, true); 1.287 @@ -804,7 +764,7 @@ 1.288 1.289 Label pc_empty; 1.290 __ ld_ptr(AT, thread, in_bytes(JavaThread::exception_pc_offset())); 1.291 - __ beq(AT,R0, pc_empty); 1.292 + __ beq(AT, R0, pc_empty); 1.293 __ delayed()->nop(); 1.294 __ stop("exception pc must be empty"); 1.295 __ bind(pc_empty); 1.296 @@ -812,35 +772,37 @@ 1.297 // clear the FPU stack in case any FPU results are left behind 1.298 __ empty_FPU_stack(); 1.299 1.300 - // leave activation of nmethod 1.301 - __ addi(SP, FP, wordSize); 1.302 - __ ld_ptr(FP, SP, - wordSize); 1.303 + // save exception_oop in callee-saved register to preserve it during runtime calls 1.304 + __ verify_not_null_oop(exception_oop); 1.305 + __ move(exception_oop_callee_saved, exception_oop); 1.306 + 1.307 +#ifndef OPT_THREAD 1.308 + __ get_thread(thread); 1.309 +#endif 1.310 + // Get return address (is on top of stack after leave). 1.311 // store return address (is on top of stack after leave) 1.312 + 1.313 __ ld_ptr(exception_pc, SP, 0); 1.314 - __ verify_oop(exception_oop); 1.315 1.316 - // save exception oop from eax to stack before call 1.317 - __ push(exception_oop); 1.318 // search the exception handler address of the caller (using the return address) 1.319 - __ call_VM_leaf(CAST_FROM_FN_PTR(address, 1.320 - SharedRuntime::exception_handler_for_return_address), exception_pc); 1.321 - // eax: exception handler address of the caller 1.322 + __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::exception_handler_for_return_address), thread, exception_pc); 1.323 + // V0: exception handler address of the caller 1.324 1.325 // only eax is valid at this time, all other registers have been destroyed by the call 1.326 1.327 // move result of call into correct register 1.328 __ move(handler_addr, V0); 1.329 - // restore exception oop in eax (required convention of exception handler) 1.330 - __ super_pop(exception_oop); 1.331 1.332 + // Restore exception oop to V0 (required convention of exception handler). 1.333 + __ move(exception_oop, exception_oop_callee_saved); 1.334 + 1.335 + // verify that there is really a valid exception in V0 1.336 __ verify_oop(exception_oop); 1.337 1.338 // get throwing pc (= return address). 1.339 - // edx has been destroyed by the call, so it must be set again 1.340 + // V1 has been destroyed by the call, so it must be set again 1.341 // the pop is also necessary to simulate the effect of a ret(0) 1.342 __ super_pop(exception_pc); 1.343 - // verify that that there is really a valid exception in eax 1.344 - __ verify_not_null_oop(exception_oop); 1.345 1.346 // continue at exception handler (return address removed) 1.347 // note: do *not* remove arguments when unwinding the 1.348 @@ -848,9 +810,9 @@ 1.349 // all arguments on the stack when entering the 1.350 // runtime to determine the exception handler 1.351 // (GC happens at call site with arguments!) 1.352 - // eax: exception oop 1.353 - // edx: throwing pc 1.354 - // ebx: exception handler 1.355 + // V0: exception oop 1.356 + // V1: throwing pc 1.357 + // T3: exception handler 1.358 __ jr(handler_addr); 1.359 __ delayed()->nop(); 1.360 } 1.361 @@ -867,9 +829,6 @@ 1.362 // Note: This number affects also the RT-Call in generate_handle_exception because 1.363 // the oop-map is shared for all calls. 1.364 1.365 - 1.366 - 1.367 - 1.368 DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); 1.369 assert(deopt_blob != NULL, "deoptimization blob must have been created"); 1.370 // assert(deopt_with_exception_entry_for_patch != NULL, 1.371 @@ -877,13 +836,9 @@ 1.372 1.373 //OopMap* oop_map = save_live_registers(sasm, num_rt_args); 1.374 OopMap* oop_map = save_live_registers(sasm, 0); 1.375 -#ifndef OPT_THREAD 1.376 const Register thread = T8; 1.377 // push java thread (becomes first argument of C function) 1.378 __ get_thread(thread); 1.379 -#else 1.380 - const Register thread = TREG; 1.381 -#endif 1.382 __ move(A0, thread); 1.383 1.384 1.385 @@ -922,9 +877,7 @@ 1.386 OopMapSet* oop_maps = new OopMapSet(); 1.387 oop_maps->add_gc_map(__ offset(), oop_map); 1.388 1.389 -#ifndef OPT_THREAD 1.390 __ get_thread(thread); 1.391 -#endif 1.392 1.393 __ ld_ptr (SP, thread, in_bytes(JavaThread::last_Java_sp_offset())); 1.394 __ reset_last_Java_frame(thread, true,true); 1.395 @@ -938,9 +891,8 @@ 1.396 __ delayed()->nop(); 1.397 // exception pending => remove activation and forward to exception handler 1.398 1.399 - __ bne(V0,R0, skip); 1.400 + __ bne(V0, R0, skip); 1.401 __ delayed()->nop(); 1.402 - // relocInfo::runtime_call_type); 1.403 __ jmp(Runtime1::entry_for(Runtime1::forward_exception_id), 1.404 relocInfo::runtime_call_type); 1.405 __ delayed()->nop(); 1.406 @@ -1039,40 +991,10 @@ 1.407 switch (id) { 1.408 case forward_exception_id: 1.409 { 1.410 - // we're handling an exception in the context of a compiled 1.411 - // frame. The registers have been saved in the standard 1.412 - // places. Perform an exception lookup in the caller and 1.413 - // dispatch to the handler if found. Otherwise unwind and 1.414 - // dispatch to the callers exception handler. 1.415 - 1.416 - const Register exception_oop = V0; 1.417 - const Register exception_pc = V1; 1.418 -#ifndef OPT_THREAD 1.419 - const Register thread = T8; 1.420 - __ get_thread(thread); 1.421 -#else 1.422 - const Register thread = TREG; 1.423 -#endif 1.424 - // load pending exception oop into eax 1.425 - __ ld_ptr(exception_oop, thread, in_bytes(Thread::pending_exception_offset())); 1.426 - // clear pending exception 1.427 - __ st_ptr(R0, thread, in_bytes(Thread::pending_exception_offset())); 1.428 - 1.429 - // load issuing PC (the return address for this stub) into V1 1.430 - __ ld_ptr(exception_pc, FP, 1*BytesPerWord); 1.431 - 1.432 - // make sure that the vm_results are cleared (may be unnecessary) 1.433 - __ st_ptr(R0, Address(thread, in_bytes(JavaThread::vm_result_offset()))); 1.434 - __ st_ptr(R0, Address(thread, in_bytes(JavaThread::vm_result_2_offset()))); 1.435 - 1.436 - // verify that that there is really a valid exception in eax 1.437 - __ verify_not_null_oop(exception_oop); 1.438 - 1.439 - 1.440 - oop_maps = new OopMapSet(); 1.441 - OopMap* oop_map = generate_oop_map(sasm, 0); 1.442 - generate_handle_exception(id, sasm); 1.443 - __ stop("should not reach here"); 1.444 + oop_maps = generate_handle_exception(id, sasm); 1.445 + __ leave(); 1.446 + __ jr(RA); 1.447 + __ delayed()->nop(); 1.448 } 1.449 break; 1.450 1.451 @@ -1080,12 +1002,7 @@ 1.452 case fast_new_instance_id: 1.453 case fast_new_instance_init_check_id: 1.454 { 1.455 - // i use T4 as klass register, V0 as result register. MUST accord with NewInstanceStub::emit_code 1.456 -#ifndef _LP64 1.457 - Register klass = T4; // Incoming 1.458 -#else 1.459 Register klass = A4; // Incoming 1.460 -#endif 1.461 Register obj = V0; // Result 1.462 1.463 if (id == new_instance_id) { 1.464 @@ -1106,7 +1023,7 @@ 1.465 assert_different_registers(klass, obj, obj_size, t1, t2); 1.466 if (id == fast_new_instance_init_check_id) { 1.467 // make sure the klass is initialized 1.468 - __ lw(AT, klass, in_bytes(InstanceKlass::init_state_offset())); 1.469 + __ ld_ptr(AT, Address(klass, in_bytes(InstanceKlass::init_state_offset()))); 1.470 __ move(t1, InstanceKlass::fully_initialized); 1.471 __ bne(AT, t1, slow_path); 1.472 __ delayed()->nop(); 1.473 @@ -1180,11 +1097,13 @@ 1.474 #else 1.475 Register bci = A5; 1.476 #endif 1.477 + Register method = AT; 1.478 __ enter(); 1.479 OopMap* map = save_live_registers(sasm, 0); 1.480 // Retrieve bci 1.481 __ lw(bci, Address(FP, 2*BytesPerWord));// FIXME:wuhui.ebp==?? 1.482 - int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci); 1.483 + __ ld(method, Address(FP, 3*BytesPerWord)); 1.484 + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, counter_overflow), bci, method); 1.485 oop_maps = new OopMapSet(); 1.486 oop_maps->add_gc_map(call_offset, map); 1.487 restore_live_registers(sasm); 1.488 @@ -1379,7 +1298,8 @@ 1.489 1.490 // case range_check_failed_id: 1.491 case throw_range_check_failed_id: 1.492 - { StubFrame f(sasm, "range_check_failed", dont_gc_arguments); 1.493 + { 1.494 + StubFrame f(sasm, "range_check_failed", dont_gc_arguments); 1.495 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, 1.496 throw_range_check_exception),true); 1.497 } 1.498 @@ -1402,42 +1322,40 @@ 1.499 break; 1.500 1.501 case throw_null_pointer_exception_id: 1.502 - { StubFrame f(sasm, "throw_null_pointer_exception", dont_gc_arguments); 1.503 + { 1.504 + StubFrame f(sasm, "throw_null_pointer_exception", dont_gc_arguments); 1.505 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, 1.506 throw_null_pointer_exception),false); 1.507 } 1.508 break; 1.509 1.510 - case handle_exception_nofpu_id: 1.511 + case handle_exception_nofpu_id: 1.512 save_fpu_registers = false; 1.513 // fall through 1.514 case handle_exception_id: 1.515 { 1.516 - 1.517 - 1.518 StubFrame f(sasm, "handle_exception", dont_gc_arguments); 1.519 - 1.520 //OopMap* oop_map = save_live_registers(sasm, 1, save_fpu_registers); 1.521 oop_maps = generate_handle_exception(id, sasm); 1.522 } 1.523 break; 1.524 - case handle_exception_from_callee_id: 1.525 - { 1.526 - StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments); 1.527 - oop_maps = generate_handle_exception(id, sasm); 1.528 - } 1.529 - break; 1.530 + case handle_exception_from_callee_id: 1.531 + { 1.532 + StubFrame f(sasm, "handle_exception_from_callee", dont_gc_arguments); 1.533 + oop_maps = generate_handle_exception(id, sasm); 1.534 + } 1.535 + break; 1.536 case unwind_exception_id: 1.537 { 1.538 __ set_info("unwind_exception", dont_gc_arguments); 1.539 - 1.540 generate_unwind_exception(sasm); 1.541 } 1.542 break; 1.543 1.544 1.545 case throw_array_store_exception_id: 1.546 - { StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments); 1.547 + { 1.548 + StubFrame f(sasm, "throw_array_store_exception", dont_gc_arguments); 1.549 // tos + 0: link 1.550 // + 1: return address 1.551 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, 1.552 @@ -1446,17 +1364,18 @@ 1.553 break; 1.554 1.555 case throw_class_cast_exception_id: 1.556 - { StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments); 1.557 + { 1.558 + StubFrame f(sasm, "throw_class_cast_exception", dont_gc_arguments); 1.559 oop_maps = generate_exception_throw(sasm, CAST_FROM_FN_PTR(address, 1.560 - throw_class_cast_exception), V0); 1.561 + throw_class_cast_exception), true); 1.562 } 1.563 break; 1.564 1.565 case throw_incompatible_class_change_error_id: 1.566 { 1.567 - StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments); 1.568 - oop_maps = generate_exception_throw(sasm, 1.569 - CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false); 1.570 + StubFrame f(sasm, "throw_incompatible_class_cast_exception", dont_gc_arguments); 1.571 + oop_maps = generate_exception_throw(sasm, 1.572 + CAST_FROM_FN_PTR(address, throw_incompatible_class_change_error), false); 1.573 } 1.574 break; 1.575 1.576 @@ -1600,12 +1519,21 @@ 1.577 oop_maps->add_gc_map(call_offset, map); 1.578 restore_live_registers(sasm); 1.579 }*/ 1.580 - case load_mirror_patching_id: 1.581 - { 1.582 - StubFrame f(sasm, "load_mirror_patching" , dont_gc_arguments); 1.583 - oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching)); 1.584 - } 1.585 + case load_mirror_patching_id: 1.586 + { 1.587 + StubFrame f(sasm, "load_mirror_patching" , dont_gc_arguments); 1.588 + oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_mirror_patching)); 1.589 + } 1.590 break; 1.591 + 1.592 + case load_appendix_patching_id: 1.593 + { 1.594 + StubFrame f(sasm, "load_appendix_patching", dont_gc_arguments); 1.595 + // we should set up register map 1.596 + oop_maps = generate_patching(sasm, CAST_FROM_FN_PTR(address, move_appendix_patching)); 1.597 + } 1.598 + break; 1.599 + 1.600 case dtrace_object_alloc_id: 1.601 { 1.602 // V0:object 1.603 @@ -1615,6 +1543,7 @@ 1.604 save_live_registers(sasm, 0); 1.605 1.606 __ push_reg(V0); 1.607 + __ move(A0, V0); 1.608 __ call(CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), 1.609 relocInfo::runtime_call_type); 1.610 __ super_pop(V0); 1.611 @@ -1622,12 +1551,51 @@ 1.612 restore_live_registers(sasm); 1.613 } 1.614 break; 1.615 + 1.616 case fpu2long_stub_id: 1.617 { 1.618 - //FIXME, I hava no idea how to port this 1.619 + //FIXME, I hava no idea how to port this 1.620 + //tty->print_cr("fpu2long_stub_id unimplemented yet!"); 1.621 } 1.622 + break; 1.623 + 1.624 + case deoptimize_id: 1.625 + { 1.626 + StubFrame f(sasm, "deoptimize", dont_gc_arguments); 1.627 + const int num_rt_args = 1; // thread 1.628 + OopMap* oop_map = save_live_registers(sasm, num_rt_args); 1.629 + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, deoptimize)); 1.630 + oop_maps = new OopMapSet(); 1.631 + oop_maps->add_gc_map(call_offset, oop_map); 1.632 + restore_live_registers(sasm); 1.633 + DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); 1.634 + assert(deopt_blob != NULL, "deoptimization blob must have been created"); 1.635 + __ leave(); 1.636 + __ jmp(deopt_blob->unpack_with_reexecution(), relocInfo::runtime_call_type); 1.637 + } 1.638 + break; 1.639 + 1.640 + case predicate_failed_trap_id: 1.641 + { 1.642 + StubFrame f(sasm, "predicate_failed_trap", dont_gc_arguments); 1.643 + 1.644 + OopMap* map = save_live_registers(sasm, 1); 1.645 + 1.646 + int call_offset = __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, predicate_failed_trap)); 1.647 + oop_maps = new OopMapSet(); 1.648 + oop_maps->add_gc_map(call_offset, map); 1.649 + restore_live_registers(sasm); 1.650 + __ leave(); 1.651 + DeoptimizationBlob* deopt_blob = SharedRuntime::deopt_blob(); 1.652 + assert(deopt_blob != NULL, "deoptimization blob must have been created"); 1.653 + 1.654 + __ jmp(deopt_blob->unpack_with_reexecution(), relocInfo::runtime_call_type); 1.655 + } 1.656 + break; 1.657 + 1.658 default: 1.659 - { StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); 1.660 + { 1.661 + StubFrame f(sasm, "unimplemented entry", dont_gc_arguments); 1.662 __ move(A1, (int)id); 1.663 __ call_RT(noreg, noreg, CAST_FROM_FN_PTR(address, unimplemented_entry), A1); 1.664 __ should_not_reach_here();