< prev index next >

src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp

Print this page
rev 49736 : 8185505: AArch64: Port AOT to AArch64
Reviewed-by: duke
   1 /*
   2  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2014, 2015, Red Hat Inc. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *


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


2261 // this function returns the adjust size (in number of words) to a c2i adapter
2262 // activation for use during deoptimization
2263 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) {
2264   assert(callee_locals >= callee_parameters,
2265           "test and remove; got more parms than locals");
2266   if (callee_locals < callee_parameters)
2267     return 0;                   // No adjustment for negative locals
2268   int diff = (callee_locals - callee_parameters) * Interpreter::stackElementWords;
2269   // diff is counted in stack words
2270   return align_up(diff, 2);
2271 }
2272 
2273 
2274 //------------------------------generate_deopt_blob----------------------------
2275 void SharedRuntime::generate_deopt_blob() {
2276   // Allocate space for the code
2277   ResourceMark rm;
2278   // Setup code generation tools
2279   int pad = 0;
2280 #if INCLUDE_JVMCI
2281   if (EnableJVMCI) {
2282     pad += 512; // Increase the buffer size when compiling for JVMCI
2283   }
2284 #endif
2285   CodeBuffer buffer("deopt_blob", 2048+pad, 1024);
2286   MacroAssembler* masm = new MacroAssembler(&buffer);
2287   int frame_size_in_words;
2288   OopMap* map = NULL;
2289   OopMapSet *oop_maps = new OopMapSet();
2290 
2291 #ifdef BUILTIN_SIM
2292   AArch64Simulator *simulator;
2293   if (NotifySimulator) {
2294     simulator = AArch64Simulator::get_current(UseSimulatorCache, DisableBCCheck);
2295     simulator->notifyCompile(const_cast<char*>("SharedRuntime::deopt_blob"), __ pc());
2296   }
2297 #endif
2298 
2299   // -------------
2300   // This code enters when returning to a de-optimized nmethod.  A return
2301   // address has been pushed on the the stack, and return values are in


2343   if (EnableJVMCI && UseJVMCICompiler) {
2344     // JVMCI does not use this kind of deoptimization
2345     __ should_not_reach_here();
2346   }
2347 #endif
2348 
2349   // Reexecute case
2350   // return address is the pc describes what bci to do re-execute at
2351 
2352   // No need to update map as each call to save_live_registers will produce identical oopmap
2353   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2354 
2355   __ movw(rcpool, Deoptimization::Unpack_reexecute); // callee-saved
2356   __ b(cont);
2357 
2358 #if INCLUDE_JVMCI
2359   Label after_fetch_unroll_info_call;
2360   int implicit_exception_uncommon_trap_offset = 0;
2361   int uncommon_trap_offset = 0;
2362 
2363   if (EnableJVMCI) {
2364     implicit_exception_uncommon_trap_offset = __ pc() - start;
2365 
2366     __ ldr(lr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2367     __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2368 
2369     uncommon_trap_offset = __ pc() - start;
2370 
2371     // Save everything in sight.
2372     RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2373     // fetch_unroll_info needs to call last_java_frame()
2374     Label retaddr;
2375     __ set_last_Java_frame(sp, noreg, retaddr, rscratch1);
2376 
2377     __ ldrw(c_rarg1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
2378     __ movw(rscratch1, -1);
2379     __ strw(rscratch1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
2380 
2381     __ movw(rcpool, (int32_t)Deoptimization::Unpack_reexecute);
2382     __ mov(c_rarg0, rthread);
2383     __ movw(c_rarg2, rcpool); // exec mode


2469     __ ldr(rscratch1, Address(rthread,
2470                               JavaThread::last_Java_fp_offset()));
2471     __ cbz(rscratch1, L);
2472     __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared");
2473     __ bind(L);
2474   }
2475 #endif // ASSERT
2476   __ mov(c_rarg0, rthread);
2477   __ mov(c_rarg1, rcpool);
2478   __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)));
2479   __ blrt(rscratch1, 1, 0, 1);
2480   __ bind(retaddr);
2481 
2482   // Need to have an oopmap that tells fetch_unroll_info where to
2483   // find any register it might need.
2484   oop_maps->add_gc_map(__ pc() - start, map);
2485 
2486   __ reset_last_Java_frame(false);
2487 
2488 #if INCLUDE_JVMCI
2489   if (EnableJVMCI) {
2490     __ bind(after_fetch_unroll_info_call);
2491   }
2492 #endif
2493 
2494   // Load UnrollBlock* into r5
2495   __ mov(r5, r0);
2496 
2497   __ ldrw(rcpool, Address(r5, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()));
2498    Label noException;
2499   __ cmpw(rcpool, Deoptimization::Unpack_exception);   // Was exception pending?
2500   __ br(Assembler::NE, noException);
2501   __ ldr(r0, Address(rthread, JavaThread::exception_oop_offset()));
2502   // QQQ this is useless it was NULL above
2503   __ ldr(r3, Address(rthread, JavaThread::exception_pc_offset()));
2504   __ str(zr, Address(rthread, JavaThread::exception_oop_offset()));
2505   __ str(zr, Address(rthread, JavaThread::exception_pc_offset()));
2506 
2507   __ verify_oop(r0);
2508 
2509   // Overwrite the result registers with the exception results.


2627   __ reset_last_Java_frame(true);
2628 
2629   // Collect return values
2630   __ ldrd(v0, Address(sp, RegisterSaver::v0_offset_in_bytes()));
2631   __ ldr(r0, Address(sp, RegisterSaver::r0_offset_in_bytes()));
2632   // I think this is useless (throwing pc?)
2633   // __ ldr(r3, Address(sp, RegisterSaver::r3_offset_in_bytes()));
2634 
2635   // Pop self-frame.
2636   __ leave();                           // Epilog
2637 
2638   // Jump to interpreter
2639   __ ret(lr);
2640 
2641   // Make sure all code is generated
2642   masm->flush();
2643 
2644   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
2645   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
2646 #if INCLUDE_JVMCI
2647   if (EnableJVMCI) {
2648     _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
2649     _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
2650   }
2651 #endif
2652 #ifdef BUILTIN_SIM
2653   if (NotifySimulator) {
2654     unsigned char *base = _deopt_blob->code_begin();
2655     simulator->notifyRelocate(start, base - start);
2656   }
2657 #endif
2658 }
2659 
2660 uint SharedRuntime::out_preserve_stack_slots() {
2661   return 0;
2662 }
2663 
2664 #if COMPILER2_OR_JVMCI
2665 //------------------------------generate_uncommon_trap_blob--------------------
2666 void SharedRuntime::generate_uncommon_trap_blob() {
2667   // Allocate space for the code


   1 /*
   2  * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright (c) 2014, 2018, Red Hat Inc. All rights reserved.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *


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


2261 // this function returns the adjust size (in number of words) to a c2i adapter
2262 // activation for use during deoptimization
2263 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals) {
2264   assert(callee_locals >= callee_parameters,
2265           "test and remove; got more parms than locals");
2266   if (callee_locals < callee_parameters)
2267     return 0;                   // No adjustment for negative locals
2268   int diff = (callee_locals - callee_parameters) * Interpreter::stackElementWords;
2269   // diff is counted in stack words
2270   return align_up(diff, 2);
2271 }
2272 
2273 
2274 //------------------------------generate_deopt_blob----------------------------
2275 void SharedRuntime::generate_deopt_blob() {
2276   // Allocate space for the code
2277   ResourceMark rm;
2278   // Setup code generation tools
2279   int pad = 0;
2280 #if INCLUDE_JVMCI
2281   if (EnableJVMCI || UseAOT) {
2282     pad += 512; // Increase the buffer size when compiling for JVMCI
2283   }
2284 #endif
2285   CodeBuffer buffer("deopt_blob", 2048+pad, 1024);
2286   MacroAssembler* masm = new MacroAssembler(&buffer);
2287   int frame_size_in_words;
2288   OopMap* map = NULL;
2289   OopMapSet *oop_maps = new OopMapSet();
2290 
2291 #ifdef BUILTIN_SIM
2292   AArch64Simulator *simulator;
2293   if (NotifySimulator) {
2294     simulator = AArch64Simulator::get_current(UseSimulatorCache, DisableBCCheck);
2295     simulator->notifyCompile(const_cast<char*>("SharedRuntime::deopt_blob"), __ pc());
2296   }
2297 #endif
2298 
2299   // -------------
2300   // This code enters when returning to a de-optimized nmethod.  A return
2301   // address has been pushed on the the stack, and return values are in


2343   if (EnableJVMCI && UseJVMCICompiler) {
2344     // JVMCI does not use this kind of deoptimization
2345     __ should_not_reach_here();
2346   }
2347 #endif
2348 
2349   // Reexecute case
2350   // return address is the pc describes what bci to do re-execute at
2351 
2352   // No need to update map as each call to save_live_registers will produce identical oopmap
2353   (void) RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2354 
2355   __ movw(rcpool, Deoptimization::Unpack_reexecute); // callee-saved
2356   __ b(cont);
2357 
2358 #if INCLUDE_JVMCI
2359   Label after_fetch_unroll_info_call;
2360   int implicit_exception_uncommon_trap_offset = 0;
2361   int uncommon_trap_offset = 0;
2362 
2363   if (EnableJVMCI || UseAOT) {
2364     implicit_exception_uncommon_trap_offset = __ pc() - start;
2365 
2366     __ ldr(lr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2367     __ str(zr, Address(rthread, in_bytes(JavaThread::jvmci_implicit_exception_pc_offset())));
2368 
2369     uncommon_trap_offset = __ pc() - start;
2370 
2371     // Save everything in sight.
2372     RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
2373     // fetch_unroll_info needs to call last_java_frame()
2374     Label retaddr;
2375     __ set_last_Java_frame(sp, noreg, retaddr, rscratch1);
2376 
2377     __ ldrw(c_rarg1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
2378     __ movw(rscratch1, -1);
2379     __ strw(rscratch1, Address(rthread, in_bytes(JavaThread::pending_deoptimization_offset())));
2380 
2381     __ movw(rcpool, (int32_t)Deoptimization::Unpack_reexecute);
2382     __ mov(c_rarg0, rthread);
2383     __ movw(c_rarg2, rcpool); // exec mode


2469     __ ldr(rscratch1, Address(rthread,
2470                               JavaThread::last_Java_fp_offset()));
2471     __ cbz(rscratch1, L);
2472     __ stop("SharedRuntime::generate_deopt_blob: last_Java_fp not cleared");
2473     __ bind(L);
2474   }
2475 #endif // ASSERT
2476   __ mov(c_rarg0, rthread);
2477   __ mov(c_rarg1, rcpool);
2478   __ lea(rscratch1, RuntimeAddress(CAST_FROM_FN_PTR(address, Deoptimization::fetch_unroll_info)));
2479   __ blrt(rscratch1, 1, 0, 1);
2480   __ bind(retaddr);
2481 
2482   // Need to have an oopmap that tells fetch_unroll_info where to
2483   // find any register it might need.
2484   oop_maps->add_gc_map(__ pc() - start, map);
2485 
2486   __ reset_last_Java_frame(false);
2487 
2488 #if INCLUDE_JVMCI
2489   if (EnableJVMCI || UseAOT) {
2490     __ bind(after_fetch_unroll_info_call);
2491   }
2492 #endif
2493 
2494   // Load UnrollBlock* into r5
2495   __ mov(r5, r0);
2496 
2497   __ ldrw(rcpool, Address(r5, Deoptimization::UnrollBlock::unpack_kind_offset_in_bytes()));
2498    Label noException;
2499   __ cmpw(rcpool, Deoptimization::Unpack_exception);   // Was exception pending?
2500   __ br(Assembler::NE, noException);
2501   __ ldr(r0, Address(rthread, JavaThread::exception_oop_offset()));
2502   // QQQ this is useless it was NULL above
2503   __ ldr(r3, Address(rthread, JavaThread::exception_pc_offset()));
2504   __ str(zr, Address(rthread, JavaThread::exception_oop_offset()));
2505   __ str(zr, Address(rthread, JavaThread::exception_pc_offset()));
2506 
2507   __ verify_oop(r0);
2508 
2509   // Overwrite the result registers with the exception results.


2627   __ reset_last_Java_frame(true);
2628 
2629   // Collect return values
2630   __ ldrd(v0, Address(sp, RegisterSaver::v0_offset_in_bytes()));
2631   __ ldr(r0, Address(sp, RegisterSaver::r0_offset_in_bytes()));
2632   // I think this is useless (throwing pc?)
2633   // __ ldr(r3, Address(sp, RegisterSaver::r3_offset_in_bytes()));
2634 
2635   // Pop self-frame.
2636   __ leave();                           // Epilog
2637 
2638   // Jump to interpreter
2639   __ ret(lr);
2640 
2641   // Make sure all code is generated
2642   masm->flush();
2643 
2644   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
2645   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
2646 #if INCLUDE_JVMCI
2647   if (EnableJVMCI || UseAOT) {
2648     _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
2649     _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
2650   }
2651 #endif
2652 #ifdef BUILTIN_SIM
2653   if (NotifySimulator) {
2654     unsigned char *base = _deopt_blob->code_begin();
2655     simulator->notifyRelocate(start, base - start);
2656   }
2657 #endif
2658 }
2659 
2660 uint SharedRuntime::out_preserve_stack_slots() {
2661   return 0;
2662 }
2663 
2664 #if COMPILER2_OR_JVMCI
2665 //------------------------------generate_uncommon_trap_blob--------------------
2666 void SharedRuntime::generate_uncommon_trap_blob() {
2667   // Allocate space for the code


< prev index next >