< prev index next >

src/hotspot/cpu/aarch64/sharedRuntime_aarch64.cpp

Print this page




  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "asm/macroAssembler.hpp"
  28 #include "asm/macroAssembler.inline.hpp"
  29 #include "code/debugInfoRec.hpp"
  30 #include "code/icBuffer.hpp"
  31 #include "code/vtableStubs.hpp"
  32 #include "interpreter/interpreter.hpp"
  33 #include "interpreter/interp_masm.hpp"
  34 #include "logging/log.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "oops/compiledICHolder.hpp"
  37 #include "runtime/sharedRuntime.hpp"
  38 #include "runtime/vframeArray.hpp"
  39 #include "utilities/align.hpp"
  40 #include "vmreg_aarch64.inline.hpp"
  41 #ifdef COMPILER1
  42 #include "c1/c1_Runtime1.hpp"
  43 #endif
  44 #if defined(COMPILER2) || INCLUDE_JVMCI
  45 #include "adfiles/ad_aarch64.hpp"
  46 #include "opto/runtime.hpp"
  47 #endif
  48 #if INCLUDE_JVMCI
  49 #include "jvmci/jvmciJavaClasses.hpp"
  50 #endif
  51 
  52 #ifdef BUILTIN_SIM
  53 #include "../../../../../../simulator/simulator.hpp"
  54 #endif
  55 
  56 #define __ masm->
  57 
  58 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;
  59 
  60 class SimpleRuntimeFrame {
  61 
  62   public:
  63 
  64   // Most of the runtime stubs have this simple frame layout.


  97   // During deoptimization only the result registers need to be restored,
  98   // all the other values have already been extracted.
  99   static void restore_result_registers(MacroAssembler* masm);
 100 
 101     // Capture info about frame layout
 102   enum layout {
 103                 fpu_state_off = 0,
 104                 fpu_state_end = fpu_state_off+FPUStateSizeInWords-1,
 105                 // The frame sender code expects that rfp will be in
 106                 // the "natural" place and will override any oopMap
 107                 // setting for it. We must therefore force the layout
 108                 // so that it agrees with the frame sender code.
 109                 r0_off = fpu_state_off+FPUStateSizeInWords,
 110                 rfp_off = r0_off + 30 * 2,
 111                 return_off = rfp_off + 2,      // slot for return address
 112                 reg_save_size = return_off + 2};
 113 
 114 };
 115 
 116 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
 117 #if defined(COMPILER2) || INCLUDE_JVMCI
 118   if (save_vectors) {
 119     // Save upper half of vector registers
 120     int vect_words = 32 * 8 / wordSize;
 121     additional_frame_words += vect_words;
 122   }
 123 #else
 124   assert(!save_vectors, "vectors are generated only by C2 and JVMCI");
 125 #endif
 126 
 127   int frame_size_in_bytes = align_up(additional_frame_words*wordSize +
 128                                      reg_save_size*BytesPerInt, 16);
 129   // OopMap frame size is in compiler stack slots (jint's) not bytes or words
 130   int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
 131   // The caller will allocate additional_frame_words
 132   int additional_frame_slots = additional_frame_words*wordSize / BytesPerInt;
 133   // CodeBlob frame size is in words.
 134   int frame_size_in_words = frame_size_in_bytes / wordSize;
 135   *total_frame_words = frame_size_in_words;
 136 
 137   // Save registers, fpu state, and flags.


2671   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
2672   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
2673 #if INCLUDE_JVMCI
2674   if (EnableJVMCI) {
2675     _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
2676     _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
2677   }
2678 #endif
2679 #ifdef BUILTIN_SIM
2680   if (NotifySimulator) {
2681     unsigned char *base = _deopt_blob->code_begin();
2682     simulator->notifyRelocate(start, base - start);
2683   }
2684 #endif
2685 }
2686 
2687 uint SharedRuntime::out_preserve_stack_slots() {
2688   return 0;
2689 }
2690 
2691 #if defined(COMPILER2) || INCLUDE_JVMCI
2692 //------------------------------generate_uncommon_trap_blob--------------------
2693 void SharedRuntime::generate_uncommon_trap_blob() {
2694   // Allocate space for the code
2695   ResourceMark rm;
2696   // Setup code generation tools
2697   CodeBuffer buffer("uncommon_trap_blob", 2048, 1024);
2698   MacroAssembler* masm = new MacroAssembler(&buffer);
2699 
2700 #ifdef BUILTIN_SIM
2701   AArch64Simulator *simulator;
2702   if (NotifySimulator) {
2703     simulator = AArch64Simulator::get_current(UseSimulatorCache, DisableBCCheck);
2704     simulator->notifyCompile(const_cast<char*>("SharedRuntime:uncommon_trap_blob"), __ pc());
2705   }
2706 #endif
2707 
2708   assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned");
2709 
2710   address start = __ pc();
2711 


2877 
2878   // Pop self-frame.
2879   __ leave();                 // Epilog
2880 
2881   // Jump to interpreter
2882   __ ret(lr);
2883 
2884   // Make sure all code is generated
2885   masm->flush();
2886 
2887   _uncommon_trap_blob =  UncommonTrapBlob::create(&buffer, oop_maps,
2888                                                  SimpleRuntimeFrame::framesize >> 1);
2889 
2890 #ifdef BUILTIN_SIM
2891   if (NotifySimulator) {
2892     unsigned char *base = _deopt_blob->code_begin();
2893     simulator->notifyRelocate(start, base - start);
2894   }
2895 #endif
2896 }
2897 #endif // COMPILER2
2898 
2899 
2900 //------------------------------generate_handler_blob------
2901 //
2902 // Generate a special Compile2Runtime blob that saves all registers,
2903 // and setup oopmap.
2904 //
2905 SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) {
2906   ResourceMark rm;
2907   OopMapSet *oop_maps = new OopMapSet();
2908   OopMap* map;
2909 
2910   // Allocate space for the code.  Setup code generation tools.
2911   CodeBuffer buffer("handler_blob", 2048, 1024);
2912   MacroAssembler* masm = new MacroAssembler(&buffer);
2913 
2914   address start   = __ pc();
2915   address call_pc = NULL;
2916   int frame_size_in_words;
2917   bool cause_return = (poll_type == POLL_AT_RETURN);


3053   __ bind(pending);
3054 
3055   RegisterSaver::restore_live_registers(masm);
3056 
3057   // exception pending => remove activation and forward to exception handler
3058 
3059   __ str(zr, Address(rthread, JavaThread::vm_result_offset()));
3060 
3061   __ ldr(r0, Address(rthread, Thread::pending_exception_offset()));
3062   __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
3063 
3064   // -------------
3065   // make sure all code is generated
3066   masm->flush();
3067 
3068   // return the  blob
3069   // frame_size_words or bytes??
3070   return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true);
3071 }
3072 
3073 
3074 #if defined(COMPILER2) || INCLUDE_JVMCI
3075 // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
3076 //
3077 //------------------------------generate_exception_blob---------------------------
3078 // creates exception blob at the end
3079 // Using exception blob, this code is jumped from a compiled method.
3080 // (see emit_exception_handler in x86_64.ad file)
3081 //
3082 // Given an exception pc at a call we call into the runtime for the
3083 // handler in this method. This handler might merely restore state
3084 // (i.e. callee save registers) unwind the frame and jump to the
3085 // exception handler for the nmethod if there is no Java level handler
3086 // for the nmethod.
3087 //
3088 // This code is entered with a jmp.
3089 //
3090 // Arguments:
3091 //   r0: exception oop
3092 //   r3: exception pc
3093 //
3094 // Results:


3183 #ifdef ASSERT
3184   __ str(zr, Address(rthread, JavaThread::exception_handler_pc_offset()));
3185   __ str(zr, Address(rthread, JavaThread::exception_pc_offset()));
3186 #endif
3187   // Clear the exception oop so GC no longer processes it as a root.
3188   __ str(zr, Address(rthread, JavaThread::exception_oop_offset()));
3189 
3190   // r0: exception oop
3191   // r8:  exception handler
3192   // r4: exception pc
3193   // Jump to handler
3194 
3195   __ br(r8);
3196 
3197   // Make sure all code is generated
3198   masm->flush();
3199 
3200   // Set exception blob
3201   _exception_blob =  ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1);
3202 }
3203 #endif // COMPILER2


  24  */
  25 
  26 #include "precompiled.hpp"
  27 #include "asm/macroAssembler.hpp"
  28 #include "asm/macroAssembler.inline.hpp"
  29 #include "code/debugInfoRec.hpp"
  30 #include "code/icBuffer.hpp"
  31 #include "code/vtableStubs.hpp"
  32 #include "interpreter/interpreter.hpp"
  33 #include "interpreter/interp_masm.hpp"
  34 #include "logging/log.hpp"
  35 #include "memory/resourceArea.hpp"
  36 #include "oops/compiledICHolder.hpp"
  37 #include "runtime/sharedRuntime.hpp"
  38 #include "runtime/vframeArray.hpp"
  39 #include "utilities/align.hpp"
  40 #include "vmreg_aarch64.inline.hpp"
  41 #ifdef COMPILER1
  42 #include "c1/c1_Runtime1.hpp"
  43 #endif
  44 #if COMPILER2_OR_JVMCI
  45 #include "adfiles/ad_aarch64.hpp"
  46 #include "opto/runtime.hpp"
  47 #endif
  48 #if INCLUDE_JVMCI
  49 #include "jvmci/jvmciJavaClasses.hpp"
  50 #endif
  51 
  52 #ifdef BUILTIN_SIM
  53 #include "../../../../../../simulator/simulator.hpp"
  54 #endif
  55 
  56 #define __ masm->
  57 
  58 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;
  59 
  60 class SimpleRuntimeFrame {
  61 
  62   public:
  63 
  64   // Most of the runtime stubs have this simple frame layout.


  97   // During deoptimization only the result registers need to be restored,
  98   // all the other values have already been extracted.
  99   static void restore_result_registers(MacroAssembler* masm);
 100 
 101     // Capture info about frame layout
 102   enum layout {
 103                 fpu_state_off = 0,
 104                 fpu_state_end = fpu_state_off+FPUStateSizeInWords-1,
 105                 // The frame sender code expects that rfp will be in
 106                 // the "natural" place and will override any oopMap
 107                 // setting for it. We must therefore force the layout
 108                 // so that it agrees with the frame sender code.
 109                 r0_off = fpu_state_off+FPUStateSizeInWords,
 110                 rfp_off = r0_off + 30 * 2,
 111                 return_off = rfp_off + 2,      // slot for return address
 112                 reg_save_size = return_off + 2};
 113 
 114 };
 115 
 116 OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, int additional_frame_words, int* total_frame_words, bool save_vectors) {
 117 #if COMPILER2_OR_JVMCI
 118   if (save_vectors) {
 119     // Save upper half of vector registers
 120     int vect_words = 32 * 8 / wordSize;
 121     additional_frame_words += vect_words;
 122   }
 123 #else
 124   assert(!save_vectors, "vectors are generated only by C2 and JVMCI");
 125 #endif
 126 
 127   int frame_size_in_bytes = align_up(additional_frame_words*wordSize +
 128                                      reg_save_size*BytesPerInt, 16);
 129   // OopMap frame size is in compiler stack slots (jint's) not bytes or words
 130   int frame_size_in_slots = frame_size_in_bytes / BytesPerInt;
 131   // The caller will allocate additional_frame_words
 132   int additional_frame_slots = additional_frame_words*wordSize / BytesPerInt;
 133   // CodeBlob frame size is in words.
 134   int frame_size_in_words = frame_size_in_bytes / wordSize;
 135   *total_frame_words = frame_size_in_words;
 136 
 137   // Save registers, fpu state, and flags.


2671   _deopt_blob = DeoptimizationBlob::create(&buffer, oop_maps, 0, exception_offset, reexecute_offset, frame_size_in_words);
2672   _deopt_blob->set_unpack_with_exception_in_tls_offset(exception_in_tls_offset);
2673 #if INCLUDE_JVMCI
2674   if (EnableJVMCI) {
2675     _deopt_blob->set_uncommon_trap_offset(uncommon_trap_offset);
2676     _deopt_blob->set_implicit_exception_uncommon_trap_offset(implicit_exception_uncommon_trap_offset);
2677   }
2678 #endif
2679 #ifdef BUILTIN_SIM
2680   if (NotifySimulator) {
2681     unsigned char *base = _deopt_blob->code_begin();
2682     simulator->notifyRelocate(start, base - start);
2683   }
2684 #endif
2685 }
2686 
2687 uint SharedRuntime::out_preserve_stack_slots() {
2688   return 0;
2689 }
2690 
2691 #if COMPILER2_OR_JVMCI
2692 //------------------------------generate_uncommon_trap_blob--------------------
2693 void SharedRuntime::generate_uncommon_trap_blob() {
2694   // Allocate space for the code
2695   ResourceMark rm;
2696   // Setup code generation tools
2697   CodeBuffer buffer("uncommon_trap_blob", 2048, 1024);
2698   MacroAssembler* masm = new MacroAssembler(&buffer);
2699 
2700 #ifdef BUILTIN_SIM
2701   AArch64Simulator *simulator;
2702   if (NotifySimulator) {
2703     simulator = AArch64Simulator::get_current(UseSimulatorCache, DisableBCCheck);
2704     simulator->notifyCompile(const_cast<char*>("SharedRuntime:uncommon_trap_blob"), __ pc());
2705   }
2706 #endif
2707 
2708   assert(SimpleRuntimeFrame::framesize % 4 == 0, "sp not 16-byte aligned");
2709 
2710   address start = __ pc();
2711 


2877 
2878   // Pop self-frame.
2879   __ leave();                 // Epilog
2880 
2881   // Jump to interpreter
2882   __ ret(lr);
2883 
2884   // Make sure all code is generated
2885   masm->flush();
2886 
2887   _uncommon_trap_blob =  UncommonTrapBlob::create(&buffer, oop_maps,
2888                                                  SimpleRuntimeFrame::framesize >> 1);
2889 
2890 #ifdef BUILTIN_SIM
2891   if (NotifySimulator) {
2892     unsigned char *base = _deopt_blob->code_begin();
2893     simulator->notifyRelocate(start, base - start);
2894   }
2895 #endif
2896 }
2897 #endif // COMPILER2_OR_JVMCI
2898 
2899 
2900 //------------------------------generate_handler_blob------
2901 //
2902 // Generate a special Compile2Runtime blob that saves all registers,
2903 // and setup oopmap.
2904 //
2905 SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, int poll_type) {
2906   ResourceMark rm;
2907   OopMapSet *oop_maps = new OopMapSet();
2908   OopMap* map;
2909 
2910   // Allocate space for the code.  Setup code generation tools.
2911   CodeBuffer buffer("handler_blob", 2048, 1024);
2912   MacroAssembler* masm = new MacroAssembler(&buffer);
2913 
2914   address start   = __ pc();
2915   address call_pc = NULL;
2916   int frame_size_in_words;
2917   bool cause_return = (poll_type == POLL_AT_RETURN);


3053   __ bind(pending);
3054 
3055   RegisterSaver::restore_live_registers(masm);
3056 
3057   // exception pending => remove activation and forward to exception handler
3058 
3059   __ str(zr, Address(rthread, JavaThread::vm_result_offset()));
3060 
3061   __ ldr(r0, Address(rthread, Thread::pending_exception_offset()));
3062   __ far_jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
3063 
3064   // -------------
3065   // make sure all code is generated
3066   masm->flush();
3067 
3068   // return the  blob
3069   // frame_size_words or bytes??
3070   return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true);
3071 }
3072 
3073 #if COMPILER2_OR_JVMCI

3074 // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
3075 //
3076 //------------------------------generate_exception_blob---------------------------
3077 // creates exception blob at the end
3078 // Using exception blob, this code is jumped from a compiled method.
3079 // (see emit_exception_handler in x86_64.ad file)
3080 //
3081 // Given an exception pc at a call we call into the runtime for the
3082 // handler in this method. This handler might merely restore state
3083 // (i.e. callee save registers) unwind the frame and jump to the
3084 // exception handler for the nmethod if there is no Java level handler
3085 // for the nmethod.
3086 //
3087 // This code is entered with a jmp.
3088 //
3089 // Arguments:
3090 //   r0: exception oop
3091 //   r3: exception pc
3092 //
3093 // Results:


3182 #ifdef ASSERT
3183   __ str(zr, Address(rthread, JavaThread::exception_handler_pc_offset()));
3184   __ str(zr, Address(rthread, JavaThread::exception_pc_offset()));
3185 #endif
3186   // Clear the exception oop so GC no longer processes it as a root.
3187   __ str(zr, Address(rthread, JavaThread::exception_oop_offset()));
3188 
3189   // r0: exception oop
3190   // r8:  exception handler
3191   // r4: exception pc
3192   // Jump to handler
3193 
3194   __ br(r8);
3195 
3196   // Make sure all code is generated
3197   masm->flush();
3198 
3199   // Set exception blob
3200   _exception_blob =  ExceptionBlob::create(&buffer, oop_maps, SimpleRuntimeFrame::framesize >> 1);
3201 }
3202 #endif // COMPILER2_OR_JVMCI
< prev index next >