src/cpu/x86/vm/sharedRuntime_x86_64.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7045514 Sdiff src/cpu/x86/vm

src/cpu/x86/vm/sharedRuntime_x86_64.cpp

Print this page




  24 
  25 #include "precompiled.hpp"
  26 #include "asm/assembler.hpp"
  27 #include "assembler_x86.inline.hpp"
  28 #include "code/debugInfoRec.hpp"
  29 #include "code/icBuffer.hpp"
  30 #include "code/vtableStubs.hpp"
  31 #include "interpreter/interpreter.hpp"
  32 #include "oops/compiledICHolderOop.hpp"
  33 #include "prims/jvmtiRedefineClassesTrace.hpp"
  34 #include "runtime/sharedRuntime.hpp"
  35 #include "runtime/vframeArray.hpp"
  36 #include "vmreg_x86.inline.hpp"
  37 #ifdef COMPILER1
  38 #include "c1/c1_Runtime1.hpp"
  39 #endif
  40 #ifdef COMPILER2
  41 #include "opto/runtime.hpp"
  42 #endif
  43 
  44 DeoptimizationBlob *SharedRuntime::_deopt_blob;
  45 #ifdef COMPILER2
  46 UncommonTrapBlob   *SharedRuntime::_uncommon_trap_blob;
  47 ExceptionBlob      *OptoRuntime::_exception_blob;
  48 #endif // COMPILER2
  49 
  50 SafepointBlob      *SharedRuntime::_polling_page_safepoint_handler_blob;
  51 SafepointBlob      *SharedRuntime::_polling_page_return_handler_blob;
  52 RuntimeStub*       SharedRuntime::_wrong_method_blob;
  53 RuntimeStub*       SharedRuntime::_ic_miss_blob;
  54 RuntimeStub*       SharedRuntime::_resolve_opt_virtual_call_blob;
  55 RuntimeStub*       SharedRuntime::_resolve_virtual_call_blob;
  56 RuntimeStub*       SharedRuntime::_resolve_static_call_blob;
  57 
  58 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;
  59 
  60 #define __ masm->
  61 
  62 class SimpleRuntimeFrame {
  63 
  64   public:
  65 
  66   // Most of the runtime stubs have this simple frame layout.
  67   // This class exists to make the layout shared in one place.
  68   // Offsets are for compiler stack slots, which are jints.
  69   enum layout {
  70     // The frame sender code expects that rbp will be in the "natural" place and
  71     // will override any oopMap setting for it. We must therefore force the layout
  72     // so that it agrees with the frame sender code.
  73     rbp_off = frame::arg_reg_save_area_bytes/BytesPerInt,
  74     rbp_off2,
  75     return_off, return_off2,
  76     framesize
  77   };
  78 };
  79 
  80 class RegisterSaver {
  81   // Capture info about frame layout.  Layout offsets are in jint


2513       method, masm->code(), vep_offset, patch_offset, frame_complete,
2514       stack_slots / VMRegImpl::slots_per_word);
2515   return nm;
2516 
2517 }
2518 
2519 #endif // HAVE_DTRACE_H
2520 
2521 // this function returns the adjust size (in number of words) to a c2i adapter
2522 // activation for use during deoptimization
2523 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) {
2524   return (callee_locals - callee_parameters) * Interpreter::stackElementWords;
2525 }
2526 
2527 
2528 uint SharedRuntime::out_preserve_stack_slots() {
2529   return 0;
2530 }
2531 
2532 
2533 //----------------------------generate_ricochet_blob---------------------------
2534 void SharedRuntime::generate_ricochet_blob() {
2535   if (!EnableInvokeDynamic)  return;  // leave it as a null
2536 
2537   // allocate space for the code
2538   ResourceMark rm;
2539   // setup code generation tools
2540   CodeBuffer   buffer("ricochet_blob", 512, 512);
2541   MacroAssembler* masm = new MacroAssembler(&buffer);
2542 
2543   int frame_size_in_words = -1, bounce_offset = -1, exception_offset = -1;
2544   MethodHandles::RicochetFrame::generate_ricochet_blob(masm, &frame_size_in_words, &bounce_offset, &exception_offset);
2545 
2546   // -------------
2547   // make sure all code is generated
2548   masm->flush();
2549 
2550   // failed to generate?
2551   if (frame_size_in_words < 0 || bounce_offset < 0 || exception_offset < 0) {
2552     assert(false, "bad ricochet blob");
2553     return;
2554   }
2555 
2556   _ricochet_blob = RicochetBlob::create(&buffer, bounce_offset, exception_offset, frame_size_in_words);
2557 }
2558 
2559 //------------------------------generate_deopt_blob----------------------------
2560 void SharedRuntime::generate_deopt_blob() {
2561   // Allocate space for the code
2562   ResourceMark rm;
2563   // Setup code generation tools
2564   CodeBuffer buffer("deopt_blob", 2048, 1024);
2565   MacroAssembler* masm = new MacroAssembler(&buffer);
2566   int frame_size_in_words;
2567   OopMap* map = NULL;
2568   OopMapSet *oop_maps = new OopMapSet();
2569 
2570   // -------------
2571   // This code enters when returning to a de-optimized nmethod.  A return
2572   // address has been pushed on the the stack, and return values are in
2573   // registers.
2574   // If we are doing a normal deopt then we were called from the patched
2575   // nmethod from the point we returned to the nmethod. So the return
2576   // address on the stack is wrong by NativeCall::instruction_size
2577   // We will adjust the value so it looks like we have the original return
2578   // address on the stack (like when we eagerly deoptimized).


3029   // Pop self-frame.
3030   __ leave();                 // Epilog
3031 
3032   // Jump to interpreter
3033   __ ret(0);
3034 
3035   // Make sure all code is generated
3036   masm->flush();
3037 
3038   _uncommon_trap_blob =  UncommonTrapBlob::create(&buffer, oop_maps,
3039                                                  SimpleRuntimeFrame::framesize >> 1);
3040 }
3041 #endif // COMPILER2
3042 
3043 
3044 //------------------------------generate_handler_blob------
3045 //
3046 // Generate a special Compile2Runtime blob that saves all registers,
3047 // and setup oopmap.
3048 //
3049 static SafepointBlob* generate_handler_blob(address call_ptr, bool cause_return) {
3050   assert(StubRoutines::forward_exception_entry() != NULL,
3051          "must be generated before");
3052 
3053   ResourceMark rm;
3054   OopMapSet *oop_maps = new OopMapSet();
3055   OopMap* map;
3056 
3057   // Allocate space for the code.  Setup code generation tools.
3058   CodeBuffer buffer("handler_blob", 2048, 1024);
3059   MacroAssembler* masm = new MacroAssembler(&buffer);
3060 
3061   address start   = __ pc();
3062   address call_pc = NULL;
3063   int frame_size_in_words;
3064 
3065   // Make room for return address (or push it again)
3066   if (!cause_return) {
3067     __ push(rbx);
3068   }
3069 


3115   // Normal exit, restore registers and exit.
3116   RegisterSaver::restore_live_registers(masm);
3117 
3118   __ ret(0);
3119 
3120   // Make sure all code is generated
3121   masm->flush();
3122 
3123   // Fill-out other meta info
3124   return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words);
3125 }
3126 
3127 //
3128 // generate_resolve_blob - call resolution (static/virtual/opt-virtual/ic-miss
3129 //
3130 // Generate a stub that calls into vm to find out the proper destination
3131 // of a java call. All the argument registers are live at this point
3132 // but since this is generic code we don't know what they are and the caller
3133 // must do any gc of the args.
3134 //
3135 static RuntimeStub* generate_resolve_blob(address destination, const char* name) {
3136   assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
3137 
3138   // allocate space for the code
3139   ResourceMark rm;
3140 
3141   CodeBuffer buffer(name, 1000, 512);
3142   MacroAssembler* masm                = new MacroAssembler(&buffer);
3143 
3144   int frame_size_in_words;
3145 
3146   OopMapSet *oop_maps = new OopMapSet();
3147   OopMap* map = NULL;
3148 
3149   int start = __ offset();
3150 
3151   map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
3152 
3153   int frame_complete = __ offset();
3154 
3155   __ set_last_Java_frame(noreg, noreg, NULL);


3191   __ bind(pending);
3192 
3193   RegisterSaver::restore_live_registers(masm);
3194 
3195   // exception pending => remove activation and forward to exception handler
3196 
3197   __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), (int)NULL_WORD);
3198 
3199   __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset()));
3200   __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
3201 
3202   // -------------
3203   // make sure all code is generated
3204   masm->flush();
3205 
3206   // return the  blob
3207   // frame_size_words or bytes??
3208   return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true);
3209 }
3210 
3211 
3212 void SharedRuntime::generate_stubs() {
3213 
3214   _wrong_method_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method),
3215                                         "wrong_method_stub");
3216   _ic_miss_blob =      generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::handle_wrong_method_ic_miss),
3217                                         "ic_miss_stub");
3218   _resolve_opt_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_opt_virtual_call_C),
3219                                         "resolve_opt_virtual_call");
3220 
3221   _resolve_virtual_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_virtual_call_C),
3222                                         "resolve_virtual_call");
3223 
3224   _resolve_static_call_blob = generate_resolve_blob(CAST_FROM_FN_PTR(address, SharedRuntime::resolve_static_call_C),
3225                                         "resolve_static_call");
3226   _polling_page_safepoint_handler_blob =
3227     generate_handler_blob(CAST_FROM_FN_PTR(address,
3228                    SafepointSynchronize::handle_polling_page_exception), false);
3229 
3230   _polling_page_return_handler_blob =
3231     generate_handler_blob(CAST_FROM_FN_PTR(address,
3232                    SafepointSynchronize::handle_polling_page_exception), true);
3233 
3234   generate_ricochet_blob();
3235 
3236   generate_deopt_blob();
3237 
3238 #ifdef COMPILER2
3239   generate_uncommon_trap_blob();
3240 #endif // COMPILER2
3241 }
3242 
3243 
3244 #ifdef COMPILER2
3245 // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
3246 //
3247 //------------------------------generate_exception_blob---------------------------
3248 // creates exception blob at the end
3249 // Using exception blob, this code is jumped from a compiled method.
3250 // (see emit_exception_handler in x86_64.ad file)
3251 //
3252 // Given an exception pc at a call we call into the runtime for the
3253 // handler in this method. This handler might merely restore state
3254 // (i.e. callee save registers) unwind the frame and jump to the
3255 // exception handler for the nmethod if there is no Java level handler
3256 // for the nmethod.
3257 //
3258 // This code is entered with a jmp.
3259 //
3260 // Arguments:
3261 //   rax: exception oop
3262 //   rdx: exception pc




  24 
  25 #include "precompiled.hpp"
  26 #include "asm/assembler.hpp"
  27 #include "assembler_x86.inline.hpp"
  28 #include "code/debugInfoRec.hpp"
  29 #include "code/icBuffer.hpp"
  30 #include "code/vtableStubs.hpp"
  31 #include "interpreter/interpreter.hpp"
  32 #include "oops/compiledICHolderOop.hpp"
  33 #include "prims/jvmtiRedefineClassesTrace.hpp"
  34 #include "runtime/sharedRuntime.hpp"
  35 #include "runtime/vframeArray.hpp"
  36 #include "vmreg_x86.inline.hpp"
  37 #ifdef COMPILER1
  38 #include "c1/c1_Runtime1.hpp"
  39 #endif
  40 #ifdef COMPILER2
  41 #include "opto/runtime.hpp"
  42 #endif
  43 
  44 #define __ masm->




  45 








  46 const int StackAlignmentInSlots = StackAlignmentInBytes / VMRegImpl::stack_slot_size;
  47 


  48 class SimpleRuntimeFrame {
  49 
  50   public:
  51 
  52   // Most of the runtime stubs have this simple frame layout.
  53   // This class exists to make the layout shared in one place.
  54   // Offsets are for compiler stack slots, which are jints.
  55   enum layout {
  56     // The frame sender code expects that rbp will be in the "natural" place and
  57     // will override any oopMap setting for it. We must therefore force the layout
  58     // so that it agrees with the frame sender code.
  59     rbp_off = frame::arg_reg_save_area_bytes/BytesPerInt,
  60     rbp_off2,
  61     return_off, return_off2,
  62     framesize
  63   };
  64 };
  65 
  66 class RegisterSaver {
  67   // Capture info about frame layout.  Layout offsets are in jint


2499       method, masm->code(), vep_offset, patch_offset, frame_complete,
2500       stack_slots / VMRegImpl::slots_per_word);
2501   return nm;
2502 
2503 }
2504 
2505 #endif // HAVE_DTRACE_H
2506 
2507 // this function returns the adjust size (in number of words) to a c2i adapter
2508 // activation for use during deoptimization
2509 int Deoptimization::last_frame_adjust(int callee_parameters, int callee_locals ) {
2510   return (callee_locals - callee_parameters) * Interpreter::stackElementWords;
2511 }
2512 
2513 
2514 uint SharedRuntime::out_preserve_stack_slots() {
2515   return 0;
2516 }
2517 
2518 


























2519 //------------------------------generate_deopt_blob----------------------------
2520 void SharedRuntime::generate_deopt_blob() {
2521   // Allocate space for the code
2522   ResourceMark rm;
2523   // Setup code generation tools
2524   CodeBuffer buffer("deopt_blob", 2048, 1024);
2525   MacroAssembler* masm = new MacroAssembler(&buffer);
2526   int frame_size_in_words;
2527   OopMap* map = NULL;
2528   OopMapSet *oop_maps = new OopMapSet();
2529 
2530   // -------------
2531   // This code enters when returning to a de-optimized nmethod.  A return
2532   // address has been pushed on the the stack, and return values are in
2533   // registers.
2534   // If we are doing a normal deopt then we were called from the patched
2535   // nmethod from the point we returned to the nmethod. So the return
2536   // address on the stack is wrong by NativeCall::instruction_size
2537   // We will adjust the value so it looks like we have the original return
2538   // address on the stack (like when we eagerly deoptimized).


2989   // Pop self-frame.
2990   __ leave();                 // Epilog
2991 
2992   // Jump to interpreter
2993   __ ret(0);
2994 
2995   // Make sure all code is generated
2996   masm->flush();
2997 
2998   _uncommon_trap_blob =  UncommonTrapBlob::create(&buffer, oop_maps,
2999                                                  SimpleRuntimeFrame::framesize >> 1);
3000 }
3001 #endif // COMPILER2
3002 
3003 
3004 //------------------------------generate_handler_blob------
3005 //
3006 // Generate a special Compile2Runtime blob that saves all registers,
3007 // and setup oopmap.
3008 //
3009 SafepointBlob* SharedRuntime::generate_handler_blob(address call_ptr, bool cause_return) {
3010   assert(StubRoutines::forward_exception_entry() != NULL,
3011          "must be generated before");
3012 
3013   ResourceMark rm;
3014   OopMapSet *oop_maps = new OopMapSet();
3015   OopMap* map;
3016 
3017   // Allocate space for the code.  Setup code generation tools.
3018   CodeBuffer buffer("handler_blob", 2048, 1024);
3019   MacroAssembler* masm = new MacroAssembler(&buffer);
3020 
3021   address start   = __ pc();
3022   address call_pc = NULL;
3023   int frame_size_in_words;
3024 
3025   // Make room for return address (or push it again)
3026   if (!cause_return) {
3027     __ push(rbx);
3028   }
3029 


3075   // Normal exit, restore registers and exit.
3076   RegisterSaver::restore_live_registers(masm);
3077 
3078   __ ret(0);
3079 
3080   // Make sure all code is generated
3081   masm->flush();
3082 
3083   // Fill-out other meta info
3084   return SafepointBlob::create(&buffer, oop_maps, frame_size_in_words);
3085 }
3086 
3087 //
3088 // generate_resolve_blob - call resolution (static/virtual/opt-virtual/ic-miss
3089 //
3090 // Generate a stub that calls into vm to find out the proper destination
3091 // of a java call. All the argument registers are live at this point
3092 // but since this is generic code we don't know what they are and the caller
3093 // must do any gc of the args.
3094 //
3095 RuntimeStub* SharedRuntime::generate_resolve_blob(address destination, const char* name) {
3096   assert (StubRoutines::forward_exception_entry() != NULL, "must be generated before");
3097 
3098   // allocate space for the code
3099   ResourceMark rm;
3100 
3101   CodeBuffer buffer(name, 1000, 512);
3102   MacroAssembler* masm                = new MacroAssembler(&buffer);
3103 
3104   int frame_size_in_words;
3105 
3106   OopMapSet *oop_maps = new OopMapSet();
3107   OopMap* map = NULL;
3108 
3109   int start = __ offset();
3110 
3111   map = RegisterSaver::save_live_registers(masm, 0, &frame_size_in_words);
3112 
3113   int frame_complete = __ offset();
3114 
3115   __ set_last_Java_frame(noreg, noreg, NULL);


3151   __ bind(pending);
3152 
3153   RegisterSaver::restore_live_registers(masm);
3154 
3155   // exception pending => remove activation and forward to exception handler
3156 
3157   __ movptr(Address(r15_thread, JavaThread::vm_result_offset()), (int)NULL_WORD);
3158 
3159   __ movptr(rax, Address(r15_thread, Thread::pending_exception_offset()));
3160   __ jump(RuntimeAddress(StubRoutines::forward_exception_entry()));
3161 
3162   // -------------
3163   // make sure all code is generated
3164   masm->flush();
3165 
3166   // return the  blob
3167   // frame_size_words or bytes??
3168   return RuntimeStub::new_runtime_stub(name, &buffer, frame_complete, frame_size_in_words, oop_maps, true);
3169 }
3170 
































3171 
3172 #ifdef COMPILER2
3173 // This is here instead of runtime_x86_64.cpp because it uses SimpleRuntimeFrame
3174 //
3175 //------------------------------generate_exception_blob---------------------------
3176 // creates exception blob at the end
3177 // Using exception blob, this code is jumped from a compiled method.
3178 // (see emit_exception_handler in x86_64.ad file)
3179 //
3180 // Given an exception pc at a call we call into the runtime for the
3181 // handler in this method. This handler might merely restore state
3182 // (i.e. callee save registers) unwind the frame and jump to the
3183 // exception handler for the nmethod if there is no Java level handler
3184 // for the nmethod.
3185 //
3186 // This code is entered with a jmp.
3187 //
3188 // Arguments:
3189 //   rax: exception oop
3190 //   rdx: exception pc


src/cpu/x86/vm/sharedRuntime_x86_64.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File