OpenJDK / loom / loom
changeset 52081:a79d08d7b440 cont
imported patch excbarrier
author | rpressler |
---|---|
date | Thu, 18 Oct 2018 10:27:43 +0100 |
parents | 01a6d46edf39 |
children | f9ed3c3e6c19 |
files | src/hotspot/cpu/x86/frame_x86.hpp src/hotspot/cpu/x86/frame_x86.inline.hpp src/hotspot/cpu/x86/stubGenerator_x86_64.cpp src/hotspot/share/aot/aotCompiledMethod.cpp src/hotspot/share/aot/aotCompiledMethod.hpp src/hotspot/share/code/compiledMethod.hpp src/hotspot/share/code/nmethod.cpp src/hotspot/share/code/nmethod.hpp src/hotspot/share/opto/library_call.cpp src/hotspot/share/runtime/continuation.cpp src/hotspot/share/runtime/continuation.hpp src/hotspot/share/runtime/sharedRuntime.cpp src/hotspot/share/runtime/stubRoutines.cpp src/hotspot/share/runtime/stubRoutines.hpp |
diffstat | 14 files changed, 107 insertions(+), 47 deletions(-) [+] |
line wrap: on
line diff
--- a/src/hotspot/cpu/x86/frame_x86.hpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/cpu/x86/frame_x86.hpp Thu Oct 18 10:27:43 2018 +0100 @@ -139,6 +139,8 @@ frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb); + frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, bool deopt); + frame(intptr_t* sp, intptr_t* fp); void init(intptr_t* sp, intptr_t* fp, address pc);
--- a/src/hotspot/cpu/x86/frame_x86.inline.hpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/cpu/x86/frame_x86.inline.hpp Thu Oct 18 10:27:43 2018 +0100 @@ -73,6 +73,7 @@ _pc = pc; assert(pc != NULL, "no pc?"); _cb = cb; + _oop_map = NULL; setup(pc); } @@ -83,28 +84,27 @@ _pc = pc; assert(pc != NULL, "no pc?"); _cb = CodeCache::find_blob(pc); + _oop_map = NULL; setup(pc); } inline void frame::setup(address pc) { adjust_unextended_sp(); + assert(_cb != NULL, ""); address original_pc = CompiledMethod::get_deopt_original_pc(this); if (original_pc != NULL) { - assert(_cb != NULL, "no cb 1 pc: " INTPTR_FORMAT " orig_pc: " INTPTR_FORMAT, p2i(pc), p2i(original_pc)); _pc = original_pc; assert(_cb->as_compiled_method()->insts_contains_inclusive(_pc), "original PC must be in the main code section of the the compiled method (or must be immediately following it)"); _deopt_state = is_deoptimized; } else { - assert(_cb != NULL, "no cb 2 sp: " INTPTR_FORMAT " usp: " INTPTR_FORMAT " fp: " INTPTR_FORMAT " pc: " INTPTR_FORMAT " orig_pc: " INTPTR_FORMAT, p2i(_sp), p2i(_unextended_sp), p2i(_fp), p2i(pc), p2i(original_pc)); if (_cb->is_deoptimization_stub()) { _deopt_state = is_deoptimized; } else { _deopt_state = not_deoptimized; } } - _oop_map = NULL; } inline frame::frame(intptr_t* sp, intptr_t* fp) { @@ -137,6 +137,16 @@ } } +inline frame::frame(intptr_t* sp, intptr_t* unextended_sp, intptr_t* fp, address pc, CodeBlob* cb, bool deopt) { + _sp = sp; + _unextended_sp = unextended_sp; + _fp = fp; + _pc = pc; + assert(pc != NULL, "no pc?"); + _cb = cb; + _deopt_state = deopt ? is_deoptimized : not_deoptimized; +} + // Accessors inline bool frame::equal(frame other) const {
--- a/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/cpu/x86/stubGenerator_x86_64.cpp Thu Oct 18 10:27:43 2018 +0100 @@ -5633,7 +5633,7 @@ return start; } - address generate_cont_thaw(bool return_barrier) { + address generate_cont_thaw(bool return_barrier, bool exception) { address start = __ pc(); // TODO: Handle Valhalla return types. May require generating different return barriers. @@ -5650,9 +5650,9 @@ if (return_barrier) { __ push(rax); __ push_d(xmm0); // preserve possible return value from a method returning to the return barrier } - __ movl(c_rarg2, return_barrier); + __ movl(c_rarg1, return_barrier); push_FrameInfo(_masm, fi, fi, rbp, c_rarg3); - __ call_VM_leaf(CAST_FROM_FN_PTR(address, Continuation::prepare_thaw), fi, c_rarg2); + __ call_VM_leaf(CAST_FROM_FN_PTR(address, Continuation::prepare_thaw), fi, c_rarg1); __ testq(rax, rax); // rax contains the size of the frames to thaw, 0 if overflow or no more frames __ jcc(Assembler::zero, thaw_fail); @@ -5665,19 +5665,23 @@ if (return_barrier) { __ push(rdx); __ push_d(xmm0); // save original return value -- again } - __ movl(c_rarg2, return_barrier); push_FrameInfo(_masm, fi, fi, rbp, c_rarg3); - __ call_VM_leaf(CAST_FROM_FN_PTR(address, Continuation::thaw), fi, c_rarg2); + __ movl(c_rarg1, return_barrier); + __ movl(c_rarg2, exception); + __ call_VM_leaf(CAST_FROM_FN_PTR(address, Continuation::thaw), fi, c_rarg1, c_rarg2); if (!return_barrier) { __ movl(rax, 0); // return 0 (success) from doYield + } + if (exception) { + __ movptr(rdx, rax); // rdx must contain the original pc in the case of exception } __ bind(thaw_fail); - pop_FrameInfo(_masm, fi, rbp, rdx); + pop_FrameInfo(_masm, fi, rbp, rbx); if (return_barrier) { __ pop_d(xmm0); __ pop(rax); // restore return value (no safepoint in the call to thaw, so even an oop return value should be OK) } __ movptr(rsp, fi); // we're now on the yield frame (which is above us b/c rsp has been pushed down) - __ jmp(rdx); + __ jmp(rbx); return start; } @@ -5685,7 +5689,7 @@ address generate_cont_thaw() { StubCodeMark mark(this, "StubRoutines", "Cont thaw"); address start = __ pc(); - generate_cont_thaw(false); + generate_cont_thaw(false, false); return start; } @@ -5697,7 +5701,19 @@ if (CONT_FULL_STACK) __ stop("RETURN BARRIER -- UNREACHABLE 0"); - generate_cont_thaw(true); + generate_cont_thaw(true, false); + + return start; + } + + address generate_cont_returnBarrier_exception() { + StubCodeMark mark(this, "StubRoutines", "cont return barrier exception handler"); + address start = __ pc(); + + if (CONT_FULL_STACK) + __ stop("RETURN BARRIER -- UNREACHABLE 0"); + + generate_cont_thaw(true, true); return start; } @@ -5968,6 +5984,7 @@ // Continuation stubs: StubRoutines::_cont_thaw = generate_cont_thaw(); StubRoutines::_cont_returnBarrier = generate_cont_returnBarrier(); + StubRoutines::_cont_returnBarrierExc = generate_cont_returnBarrier_exception(); StubRoutines::_cont_doYield = generate_cont_doYield(); StubRoutines::_cont_jump = generate_cont_jump(); StubRoutines::_cont_getSP = generate_cont_getSP();
--- a/src/hotspot/share/aot/aotCompiledMethod.cpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/aot/aotCompiledMethod.cpp Thu Oct 18 10:27:43 2018 +0100 @@ -71,10 +71,6 @@ } #endif -address* AOTCompiledMethod::orig_pc_addr(const frame* fr) { - return (address*) ((address)fr->unextended_sp() + _meta->orig_pc_offset()); -} - bool AOTCompiledMethod::do_unloading_oops(address low_boundary, BoolObjectClosure* is_alive) { return false; }
--- a/src/hotspot/share/aot/aotCompiledMethod.hpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/aot/aotCompiledMethod.hpp Thu Oct 18 10:27:43 2018 +0100 @@ -117,7 +117,6 @@ const int _method_index; oop _oop; // method()->method_holder()->klass_holder() - address* orig_pc_addr(const frame* fr); bool make_not_entrant_helper(int new_state); public: @@ -234,12 +233,10 @@ virtual oop* oop_addr_at(int index) const { ShouldNotReachHere(); return NULL; } virtual Metadata** metadata_addr_at(int index) const { ShouldNotReachHere(); return NULL; } - // Accessor/mutator for the original pc of a frame before a frame was deopted. - address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); } - void set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; } - virtual void metadata_do(void f(Metadata*)); + int orig_pc_offset() { return _meta->orig_pc_offset(); } + bool metadata_got_contains(Metadata **p) { return p >= &_metadata_got[0] && p < &_metadata_got[_metadata_size]; }
--- a/src/hotspot/share/code/compiledMethod.hpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/code/compiledMethod.hpp Thu Oct 18 10:27:43 2018 +0100 @@ -304,7 +304,6 @@ virtual oop* oop_addr_at(int index) const = 0; virtual Metadata** metadata_addr_at(int index) const = 0; - virtual void set_original_pc(const frame* fr, address pc) = 0; // Exception cache support // Note: _exception_cache may be read concurrently. We rely on memory_order_consume here. @@ -323,13 +322,21 @@ address deopt_mh_handler_begin() const { return _deopt_mh_handler_begin; } address deopt_handler_begin() const { return _deopt_handler_begin; } - virtual address get_original_pc(const frame* fr) = 0; // Deopt // Return true is the PC is one would expect if the frame is being deopted. inline bool is_deopt_pc(address pc); bool is_deopt_mh_entry(address pc) { return pc == deopt_mh_handler_begin(); } inline bool is_deopt_entry(address pc); + // Accessor/mutator for the original pc of a frame before a frame was deopted. + address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); } + void set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; } + + virtual int orig_pc_offset() = 0; +private: + address* orig_pc_addr(const frame* fr) { return (address*) ((address)fr->unextended_sp() + orig_pc_offset()); }; + +public: virtual bool can_convert_to_zombie() = 0; virtual const char* compile_kind() const = 0; virtual int get_state() const = 0;
--- a/src/hotspot/share/code/nmethod.cpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/code/nmethod.cpp Thu Oct 18 10:27:43 2018 +0100 @@ -387,10 +387,6 @@ nul_chk_table_size(); } -address* nmethod::orig_pc_addr(const frame* fr) { - return (address*) ((address)fr->unextended_sp() + _orig_pc_offset); -} - const char* nmethod::compile_kind() const { if (is_osr_method()) return "osr"; if (method() != NULL && is_native_method()) return "c2n";
--- a/src/hotspot/share/code/nmethod.hpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/code/nmethod.hpp Thu Oct 18 10:27:43 2018 +0100 @@ -512,16 +512,12 @@ private: ScopeDesc* scope_desc_in(address begin, address end); - address* orig_pc_addr(const frame* fr); - public: // copying of debugging information void copy_scopes_pcs(PcDesc* pcs, int count); void copy_scopes_data(address buffer, int size); - // Accessor/mutator for the original pc of a frame before a frame was deopted. - address get_original_pc(const frame* fr) { return *orig_pc_addr(fr); } - void set_original_pc(const frame* fr, address pc) { *orig_pc_addr(fr) = pc; } + int orig_pc_offset() { return _orig_pc_offset; } // jvmti support: void post_compiled_method_load_event();
--- a/src/hotspot/share/opto/library_call.cpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/opto/library_call.cpp Thu Oct 18 10:27:43 2018 +0100 @@ -6586,6 +6586,8 @@ address call_addr = StubRoutines::cont_thaw(); const TypeFunc* tf = OptoRuntime::void_void_Type(); Node* call = make_runtime_call(RC_NO_LEAF, tf, call_addr, "doContinue", TypeRawPtr::BOTTOM); + assert (call->is_CallJava(), ""); + Node* result = set_results_for_java_call((CallJavaNode*)call, false, /* deoptimize */ false); return true; }
--- a/src/hotspot/share/runtime/continuation.cpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/runtime/continuation.cpp Thu Oct 18 10:27:43 2018 +0100 @@ -48,6 +48,7 @@ #include "runtime/frame.inline.hpp" #include "runtime/javaCalls.hpp" #include "runtime/jniHandles.inline.hpp" +#include "runtime/sharedRuntime.hpp" #include "runtime/vframe_hp.hpp" #include "utilities/copy.hpp" #include "utilities/exceptions.hpp" @@ -287,7 +288,7 @@ Method* method(ContMirror& cont); - inline frame to_frame(); + inline frame to_frame(ContMirror& cont); void print_on(ContMirror& cont, outputStream* st); void print(ContMirror& cont) { print_on(cont, tty); } @@ -518,9 +519,25 @@ template<typename Event> void post_jfr_event(Event *e); }; -inline frame hframe::to_frame() { - return frame(reinterpret_cast<intptr_t*>(_sp), reinterpret_cast<intptr_t*>(_sp), reinterpret_cast<intptr_t*>(_fp), _pc, - _cb != NULL ? _cb : (_cb = CodeCache::find_blob(_pc))); +inline frame hframe::to_frame(ContMirror& cont) { + bool deopt = false; + address pc = _pc; + if (!is_interpreted_frame()) { + CompiledMethod* cm = cb()->as_compiled_method_or_null(); + if (cm != NULL && cm->is_deopt_pc(pc)) { + intptr_t* hsp = cont.stack_address(sp()); + address orig_pc = *(address*) ((address)hsp + cm->orig_pc_offset()); + assert (orig_pc != pc, ""); + assert (orig_pc != NULL, ""); + + pc = orig_pc; + deopt = true; + } + } + + return frame(reinterpret_cast<intptr_t*>(_sp), reinterpret_cast<intptr_t*>(_sp), reinterpret_cast<intptr_t*>(_fp), pc, + _cb != NULL ? _cb : (_cb = CodeCache::find_blob(_pc)), + deopt); } void hframe::print_on(outputStream* st) { @@ -2556,7 +2573,7 @@ // fi->sp is the top of the stack after thaw // fi->fp current rbp // called after preparations (stack overflow check and making room) -static inline void thaw1(JavaThread* thread, FrameInfo* fi, const bool return_barrier) { +static inline void thaw1(JavaThread* thread, FrameInfo* fi, const bool return_barrier, const bool exception) { EventContinuationThaw event; ResourceMark rm(thread); @@ -2594,7 +2611,7 @@ // ResourceMark rm(cont.thread()); // apparently, oop-mapping may require resource allocation - + // const address orig_top_pc = cont.pc(); hframe hf = cont.last_frame(); log_trace(jvmcont)("top_hframe before (thaw):"); if (log_is_enabled(Trace, jvmcont)) hf.print_on(cont, tty); @@ -2602,7 +2619,7 @@ RegisterMap map(thread, false, false, false); map.set_include_argument_oops(false); map.set_update_link(true); - assert (map.update_map(), "RegisterMap not set to update"); + // assert (map.update_map(), "RegisterMap not set to update"); DEBUG_ONLY(int orig_num_frames = cont.num_frames();) int frame_count = 0; @@ -2624,9 +2641,12 @@ assert (cont.is_empty() <= (cont.num_interpreted_frames() == 0), "cont.is_empty: %d num_interpreted_frames: %d", cont.is_empty(), cont.num_interpreted_frames()); assert (cont.num_frames() == orig_num_frames - frame_count, "cont.is_empty: %d num_frames: %d orig_num_frames: %d frame_count: %d", cont.is_empty(), cont.num_frames(), orig_num_frames, frame_count); + assert (!top.is_compiled_frame() || top.is_deoptimized_frame() == top.cb()->as_compiled_method()->is_deopt_pc(top.raw_pc()), ""); + assert (!top.is_compiled_frame() || top.is_deoptimized_frame() == (top.pc() != top.raw_pc()), ""); + fi->sp = top.sp(); fi->fp = top.fp(); - fi->pc = top.pc(); // we'll jump to the current continuation pc // Interpreter::return_entry(vtos, 0, Bytecodes::_invokestatic, true); // + fi->pc = top.raw_pc(); // we'll jump to the current continuation pc // Interpreter::return_entry(vtos, 0, Bytecodes::_invokestatic, true); // log_trace(jvmcont)("thawed %d frames", frame_count); @@ -2759,8 +2779,17 @@ // fi->fp = the FP " ... // fi->pc = the PC " ... // JRT_ENTRY(void, Continuation::thaw(JavaThread* thread, FrameInfo* fi, int num_frames)) -JRT_LEAF(void, Continuation::thaw(FrameInfo* fi, bool return_barrier)) - thaw1(JavaThread::current(), fi, return_barrier); +JRT_LEAF(address, Continuation::thaw(FrameInfo* fi, bool return_barrier, bool exception)) + thaw1(JavaThread::current(), fi, return_barrier, exception); + + if (exception) { + // TODO: handle deopt. see TemplateInterpreterGenerator::generate_throw_exception, OptoRuntime::handle_exception_C, OptoRuntime::handle_exception_helper + // assert (!top.is_deoptimized_frame(), ""); -- seems to be handled + address ret = fi->pc; + fi->pc = SharedRuntime::raw_exception_handler_for_return_address(JavaThread::current(), fi->pc); + return ret; + } else + return NULL; JRT_END bool Continuation::is_continuation_entry_frame(const frame& f, const RegisterMap* map) { @@ -2841,7 +2870,7 @@ // tty->print_cr("continuation_top_frame"); map->set_cont(map->thread(), contOop); - return hf.to_frame(); + return hf.to_frame(cont); } static frame continuation_parent_frame(ContMirror& cont, RegisterMap* map) { @@ -2872,7 +2901,7 @@ hframe sender = hfcallee.sender(cont); if (!sender.is_empty()) - return sender.to_frame(); + return sender.to_frame(cont); return continuation_parent_frame(cont, map); }
--- a/src/hotspot/share/runtime/continuation.hpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/runtime/continuation.hpp Thu Oct 18 10:27:43 2018 +0100 @@ -57,7 +57,7 @@ public: static int freeze(JavaThread* thread, FrameInfo* fi); static int prepare_thaw(FrameInfo* fi, bool return_barrier); - static void thaw(FrameInfo* fi, bool return_barrier); + static address thaw(FrameInfo* fi, bool return_barrier, bool exception); static bool is_continuation_entry_frame(const frame& f, const RegisterMap* map); static bool is_cont_bottom_frame(const frame& f);
--- a/src/hotspot/share/runtime/sharedRuntime.cpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/runtime/sharedRuntime.cpp Thu Oct 18 10:27:43 2018 +0100 @@ -465,6 +465,10 @@ thread->set_exception_pc(NULL); #endif // INCLUDE_JVMCI + if (Continuation::is_return_barrier_entry(return_address)) { + return StubRoutines::cont_returnBarrierExc(); + } + // The fastest case first CodeBlob* blob = CodeCache::find_blob(return_address); CompiledMethod* nm = (blob != NULL) ? blob->as_compiled_method_or_null() : NULL; @@ -699,13 +703,14 @@ if (t == NULL) { ttyLocker ttyl; - tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", p2i(ret_pc), handler_bci); + tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d, catch_pco: %d", p2i(ret_pc), handler_bci, catch_pco); tty->print_cr(" Exception:"); exception->print(); tty->cr(); tty->print_cr(" Compiled exception table :"); table.print(); - nm->print_code(); + nm->print(); + // nm->print_code(); guarantee(false, "missing exception handler"); return NULL; }
--- a/src/hotspot/share/runtime/stubRoutines.cpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/runtime/stubRoutines.cpp Thu Oct 18 10:27:43 2018 +0100 @@ -181,6 +181,7 @@ address StubRoutines::_cont_jump = NULL; address StubRoutines::_cont_thaw = NULL; address StubRoutines::_cont_returnBarrier = NULL; +address StubRoutines::_cont_returnBarrierExc = NULL; address StubRoutines::_cont_getSP = NULL; address StubRoutines::_cont_getPC = NULL;
--- a/src/hotspot/share/runtime/stubRoutines.hpp Mon Oct 15 16:15:54 2018 +0100 +++ b/src/hotspot/share/runtime/stubRoutines.hpp Thu Oct 18 10:27:43 2018 +0100 @@ -212,6 +212,7 @@ static address _cont_jump; static address _cont_thaw; static address _cont_returnBarrier; + static address _cont_returnBarrierExc; static address _cont_getSP; static address _cont_getPC; @@ -396,6 +397,7 @@ static address cont_jump() { return _cont_jump; } static address cont_thaw() { return _cont_thaw; } static address cont_returnBarrier() { return _cont_returnBarrier; } + static address cont_returnBarrierExc(){return _cont_returnBarrierExc; } static address cont_getSP() { return _cont_getSP; } static address cont_getPC() { return _cont_getPC; }