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
|