< prev index next >

src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp

Print this page




 542     const char* msg = "i2c adapter must return to an interpreter frame";
 543     __ block_comment(msg);
 544     __ stop(msg);
 545     __ bind(L_ok);
 546     __ block_comment("} verify_i2ce ");
 547 #endif
 548   }
 549 
 550   // Cut-out for having no stack args.
 551   int comp_words_on_stack = align_up(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord;
 552   if (comp_args_on_stack) {
 553     __ sub(rscratch1, sp, comp_words_on_stack * wordSize);
 554     __ andr(sp, rscratch1, -16);
 555   }
 556 
 557   // Will jump to the compiled code just as if compiled code was doing it.
 558   // Pre-load the register-jump target early, to schedule it better.
 559   __ ldr(rscratch1, Address(rmethod, in_bytes(Method::from_compiled_offset())));
 560 
 561 #if INCLUDE_JVMCI
 562   if (EnableJVMCI) {
 563     // check if this call should be routed towards a specific entry point
 564     __ ldr(rscratch2, Address(rthread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
 565     Label no_alternative_target;
 566     __ cbz(rscratch2, no_alternative_target);
 567     __ mov(rscratch1, rscratch2);
 568     __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
 569     __ bind(no_alternative_target);
 570   }
 571 #endif // INCLUDE_JVMCI
 572 
 573   // Now generate the shuffle code.
 574   for (int i = 0; i < total_args_passed; i++) {
 575     if (sig_bt[i] == T_VOID) {
 576       assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half");
 577       continue;
 578     }
 579 
 580     // Pick up 0, 1 or 2 words from SP+offset.
 581 
 582     assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(),


2282 // this function returns the adjust size (in number of words) to a c2i adapter
2283 // activation for use during deoptimization
2284 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) {
2285   assert(callee_locals >= callee_parameters,
2286           "test and remove; got more parms than locals");
2287   if (callee_locals < callee_parameters)
2288     return 0;                   // No adjustment for negative locals
2289   int diff = (callee_locals - callee_parameters) * Interpreter::stackElementWords;
2290   // diff is counted in stack words
2291   return align_up(diff, 2);
2292 }
2293 
2294 
2295 //------------------------------generate_deopt_blob----------------------------
2296 void SharedRuntime::generate_deopt_blob() {
2297   // Allocate space for the code
2298   ResourceMark rm;
2299   // Setup code generation tools
2300   int pad = 0;
2301 #if INCLUDE_JVMCI
2302   if (EnableJVMCI) {
2303     pad += 512; // Increase the buffer size when compiling for JVMCI
2304   }
2305 #endif
2306   CodeBuffer buffer("deopt_blob", 2048+pad, 1024);
2307   MacroAssembler* masm = new MacroAssembler(&buffer);
2308   int frame_size_in_words;
2309   OopMap* map = NULL;
2310   OopMapSet *oop_maps = new OopMapSet();
2311 
2312 #ifdef BUILTIN_SIM
2313   AArch64Simulator *simulator;
2314   if (NotifySimulator) {
2315     simulator = AArch64Simulator::get_current(UseSimulatorCache, DisableBCCheck);
2316     simulator->notifyCompile(const_cast<char*>("SharedRuntime::deopt_blob"), __ pc());
2317   }
2318 #endif
2319 
2320   // -------------
2321   // This code enters when returning to a de-optimized nmethod.  A return
2322   // address has been pushed on the the stack, and return values are in


2364   if (EnableJVMCI && UseJVMCICompiler) {
2365     // JVMCI does not use this kind of deoptimization
2366     __ should_not_reach_here();
2367   }
2368 #endif
2369 
2370   // Reexecute case
2371   // return address is the pc describes what bci to do re-execute at
2372 
2373   // No need to update map as each call to save_live_registers will produce identical oopmap
2374   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2375 
2376   __ movw(rcpool, Deoptimization::Unpack_reexecute); // callee-saved
2377   __ b(cont);
2378 
2379 #if INCLUDE_JVMCI
2380   Label after_fetch_unroll_info_call;
2381   int implicit_exception_uncommon_trap_offset = 0;
2382   int uncommon_trap_offset = 0;
2383 
2384   if (EnableJVMCI) {
2385     implicit_exception_uncommon_trap_offset = __ pc() - start;
2386 
2387     __ ldr(lr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2388     __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2389 
2390     uncommon_trap_offset = __ pc() - start;
2391 
2392     // Save everything in sight.
2393     RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2394     // fetch_unroll_info needs to call last_java_frame()
2395     Label retaddr;
2396     __ set_last_Java_frame(sp, noreg, retaddr, rscratch1);
2397 
2398     __ ldrw(c_rarg1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
2399     __ movw(rscratch1, -1);
2400     __ strw(rscratch1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
2401 
2402     __ movw(rcpool, (int32_t)Deoptimization::Unpack_reexecute);
2403     __ mov(c_rarg0, rthread);
2404     __ movw(c_rarg2, rcpool); // exec mode


2490     __ ldr(rscratch1, Address(rthread,
2491                               JavaThread::last_Java_fp_offset()));
2492     __ cbz(rscratch1, L);
2493     __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared");
2494     __ bind(L);
2495   }
2496 #endif // ASSERT
2497   __ mov(c_rarg0, rthread);
2498   __ mov(c_rarg1, rcpool);
2499   __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)));
2500   __ blrt(rscratch1, 1, 0, 1);
2501   __ bind(retaddr);
2502 
2503   // Need to have an oopmap that tells fetch_unroll_info where to
2504   // find any register it might need.
2505   oop_maps->add_gc_map(__ pc() - start, map);
2506 
2507   __ reset_last_Java_frame(false);
2508 
2509 #if INCLUDE_JVMCI
2510   if (EnableJVMCI) {
2511     __ bind(after_fetch_unroll_info_call);
2512   }
2513 #endif
2514 
2515   // Load UnrollBlock* into r5
2516   __ mov(r5, r0);
2517 
2518   __ ldrw(rcpool, Address(r5, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()));
2519    Label noException;
2520   __ cmpw(rcpool, Deoptimization::Unpack_exception);   // Was exception pending?
2521   __ br(Assembler::NE, noException);
2522   __ ldr(r0, Address(rthread, JavaThread::exception_oop_offset()));
2523   // QQQ this is useless it was NULL above
2524   __ ldr(r3, Address(rthread, JavaThread::exception_pc_offset()));
2525   __ str(zr, Address(rthread, JavaThread::exception_oop_offset()));
2526   __ str(zr, Address(rthread, JavaThread::exception_pc_offset()));
2527 
2528   __ verify_oop(r0);
2529 
2530   // Overwrite the result registers with the exception results.


2648   __ reset_last_Java_frame(true);
2649 
2650   // Collect return values
2651   __ ldrd(v0, Address(sp, RegisterSaver::v0_offset_in_bytes()));
2652   __ ldr(r0, Address(sp, RegisterSaver::r0_offset_in_bytes()));
2653   // I think this is useless (throwing pc?)
2654   // __ ldr(r3, Address(sp, RegisterSaver::r3_offset_in_bytes()));
2655 
2656   // Pop self-frame.
2657   __ leave();                           // Epilog
2658 
2659   // Jump to interpreter
2660   __ ret(lr);
2661 
2662   // Make sure all code is generated
2663   masm->flush();
2664 
2665   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
2666   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
2667 #if INCLUDE_JVMCI
2668   if (EnableJVMCI) {
2669     _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
2670     _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
2671   }
2672 #endif
2673 #ifdef BUILTIN_SIM
2674   if (NotifySimulator) {
2675     unsigned char *base = _deopt_blob->code_begin();
2676     simulator->notifyRelocate(start, base - start);
2677   }
2678 #endif
2679 }
2680 
2681 uint SharedRuntime::out_preserve_stack_slots() {
2682   return 0;
2683 }
2684 
2685 #if COMPILER2_OR_JVMCI
2686 //------------------------------generate_uncommon_trap_blob--------------------
2687 void SharedRuntime::generate_uncommon_trap_blob() {
2688   // Allocate space for the code




 542     const char* msg = "i2c adapter must return to an interpreter frame";
 543     __ block_comment(msg);
 544     __ stop(msg);
 545     __ bind(L_ok);
 546     __ block_comment("} verify_i2ce ");
 547 #endif
 548   }
 549 
 550   // Cut-out for having no stack args.
 551   int comp_words_on_stack = align_up(comp_args_on_stack*VMRegImpl::stack_slot_size, wordSize)>>LogBytesPerWord;
 552   if (comp_args_on_stack) {
 553     __ sub(rscratch1, sp, comp_words_on_stack * wordSize);
 554     __ andr(sp, rscratch1, -16);
 555   }
 556 
 557   // Will jump to the compiled code just as if compiled code was doing it.
 558   // Pre-load the register-jump target early, to schedule it better.
 559   __ ldr(rscratch1, Address(rmethod, in_bytes(Method::from_compiled_offset())));
 560 
 561 #if INCLUDE_JVMCI
 562   if (EnableJVMCI || UseAOT) {
 563     // check if this call should be routed towards a specific entry point
 564     __ ldr(rscratch2, Address(rthread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
 565     Label no_alternative_target;
 566     __ cbz(rscratch2, no_alternative_target);
 567     __ mov(rscratch1, rscratch2);
 568     __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_alternate_call_target_offset())));
 569     __ bind(no_alternative_target);
 570   }
 571 #endif // INCLUDE_JVMCI
 572 
 573   // Now generate the shuffle code.
 574   for (int i = 0; i < total_args_passed; i++) {
 575     if (sig_bt[i] == T_VOID) {
 576       assert(i > 0 && (sig_bt[i-1] == T_LONG || sig_bt[i-1] == T_DOUBLE), "missing half");
 577       continue;
 578     }
 579 
 580     // Pick up 0, 1 or 2 words from SP+offset.
 581 
 582     assert(!regs[i].second()->is_valid() || regs[i].first()->next() == regs[i].second(),


2282 // this function returns the adjust size (in number of words) to a c2i adapter
2283 // activation for use during deoptimization
2284 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) {
2285   assert(callee_locals >= callee_parameters,
2286           "test and remove; got more parms than locals");
2287   if (callee_locals < callee_parameters)
2288     return 0;                   // No adjustment for negative locals
2289   int diff = (callee_locals - callee_parameters) * Interpreter::stackElementWords;
2290   // diff is counted in stack words
2291   return align_up(diff, 2);
2292 }
2293 
2294 
2295 //------------------------------generate_deopt_blob----------------------------
2296 void SharedRuntime::generate_deopt_blob() {
2297   // Allocate space for the code
2298   ResourceMark rm;
2299   // Setup code generation tools
2300   int pad = 0;
2301 #if INCLUDE_JVMCI
2302   if (EnableJVMCI || UseAOT) {
2303     pad += 512; // Increase the buffer size when compiling for JVMCI
2304   }
2305 #endif
2306   CodeBuffer buffer("deopt_blob", 2048+pad, 1024);
2307   MacroAssembler* masm = new MacroAssembler(&buffer);
2308   int frame_size_in_words;
2309   OopMap* map = NULL;
2310   OopMapSet *oop_maps = new OopMapSet();
2311 
2312 #ifdef BUILTIN_SIM
2313   AArch64Simulator *simulator;
2314   if (NotifySimulator) {
2315     simulator = AArch64Simulator::get_current(UseSimulatorCache, DisableBCCheck);
2316     simulator->notifyCompile(const_cast<char*>("SharedRuntime::deopt_blob"), __ pc());
2317   }
2318 #endif
2319 
2320   // -------------
2321   // This code enters when returning to a de-optimized nmethod.  A return
2322   // address has been pushed on the the stack, and return values are in


2364   if (EnableJVMCI && UseJVMCICompiler) {
2365     // JVMCI does not use this kind of deoptimization
2366     __ should_not_reach_here();
2367   }
2368 #endif
2369 
2370   // Reexecute case
2371   // return address is the pc describes what bci to do re-execute at
2372 
2373   // No need to update map as each call to save_live_registers will produce identical oopmap
2374   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2375 
2376   __ movw(rcpool, Deoptimization::Unpack_reexecute); // callee-saved
2377   __ b(cont);
2378 
2379 #if INCLUDE_JVMCI
2380   Label after_fetch_unroll_info_call;
2381   int implicit_exception_uncommon_trap_offset = 0;
2382   int uncommon_trap_offset = 0;
2383 
2384   if (EnableJVMCI || UseAOT) {
2385     implicit_exception_uncommon_trap_offset = __ pc() - start;
2386 
2387     __ ldr(lr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2388     __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2389 
2390     uncommon_trap_offset = __ pc() - start;
2391 
2392     // Save everything in sight.
2393     RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2394     // fetch_unroll_info needs to call last_java_frame()
2395     Label retaddr;
2396     __ set_last_Java_frame(sp, noreg, retaddr, rscratch1);
2397 
2398     __ ldrw(c_rarg1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
2399     __ movw(rscratch1, -1);
2400     __ strw(rscratch1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
2401 
2402     __ movw(rcpool, (int32_t)Deoptimization::Unpack_reexecute);
2403     __ mov(c_rarg0, rthread);
2404     __ movw(c_rarg2, rcpool); // exec mode


2490     __ ldr(rscratch1, Address(rthread,
2491                               JavaThread::last_Java_fp_offset()));
2492     __ cbz(rscratch1, L);
2493     __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared");
2494     __ bind(L);
2495   }
2496 #endif // ASSERT
2497   __ mov(c_rarg0, rthread);
2498   __ mov(c_rarg1, rcpool);
2499   __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)));
2500   __ blrt(rscratch1, 1, 0, 1);
2501   __ bind(retaddr);
2502 
2503   // Need to have an oopmap that tells fetch_unroll_info where to
2504   // find any register it might need.
2505   oop_maps->add_gc_map(__ pc() - start, map);
2506 
2507   __ reset_last_Java_frame(false);
2508 
2509 #if INCLUDE_JVMCI
2510   if (EnableJVMCI || UseAOT) {
2511     __ bind(after_fetch_unroll_info_call);
2512   }
2513 #endif
2514 
2515   // Load UnrollBlock* into r5
2516   __ mov(r5, r0);
2517 
2518   __ ldrw(rcpool, Address(r5, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()));
2519    Label noException;
2520   __ cmpw(rcpool, Deoptimization::Unpack_exception);   // Was exception pending?
2521   __ br(Assembler::NE, noException);
2522   __ ldr(r0, Address(rthread, JavaThread::exception_oop_offset()));
2523   // QQQ this is useless it was NULL above
2524   __ ldr(r3, Address(rthread, JavaThread::exception_pc_offset()));
2525   __ str(zr, Address(rthread, JavaThread::exception_oop_offset()));
2526   __ str(zr, Address(rthread, JavaThread::exception_pc_offset()));
2527 
2528   __ verify_oop(r0);
2529 
2530   // Overwrite the result registers with the exception results.


2648   __ reset_last_Java_frame(true);
2649 
2650   // Collect return values
2651   __ ldrd(v0, Address(sp, RegisterSaver::v0_offset_in_bytes()));
2652   __ ldr(r0, Address(sp, RegisterSaver::r0_offset_in_bytes()));
2653   // I think this is useless (throwing pc?)
2654   // __ ldr(r3, Address(sp, RegisterSaver::r3_offset_in_bytes()));
2655 
2656   // Pop self-frame.
2657   __ leave();                           // Epilog
2658 
2659   // Jump to interpreter
2660   __ ret(lr);
2661 
2662   // Make sure all code is generated
2663   masm->flush();
2664 
2665   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
2666   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
2667 #if INCLUDE_JVMCI
2668   if (EnableJVMCI || UseAOT) {
2669     _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
2670     _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
2671   }
2672 #endif
2673 #ifdef BUILTIN_SIM
2674   if (NotifySimulator) {
2675     unsigned char *base = _deopt_blob->code_begin();
2676     simulator->notifyRelocate(start, base - start);
2677   }
2678 #endif
2679 }
2680 
2681 uint SharedRuntime::out_preserve_stack_slots() {
2682   return 0;
2683 }
2684 
2685 #if COMPILER2_OR_JVMCI
2686 //------------------------------generate_uncommon_trap_blob--------------------
2687 void SharedRuntime::generate_uncommon_trap_blob() {
2688   // Allocate space for the code


< prev index next >