Mercurial > hg > truffle
changeset 8328:6b6cbd8b8914
Support deoptimizing before the entry to a synchronized method.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Sun, 17 Mar 2013 21:20:39 +0100 |
parents | e24fb475bdec |
children | 985e5188964f |
files | src/cpu/x86/vm/interpreterGenerator_x86.hpp src/cpu/x86/vm/templateInterpreter_x86_64.cpp src/share/vm/interpreter/templateInterpreter.cpp src/share/vm/interpreter/templateInterpreterGenerator.hpp src/share/vm/runtime/deoptimization.cpp src/share/vm/runtime/vframeArray.cpp src/share/vm/utilities/exceptions.hpp |
diffstat | 7 files changed, 37 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/src/cpu/x86/vm/interpreterGenerator_x86.hpp Sun Mar 17 21:14:35 2013 +0100 +++ b/src/cpu/x86/vm/interpreterGenerator_x86.hpp Sun Mar 17 21:20:39 2013 +0100 @@ -30,6 +30,8 @@ // friend class AbstractInterpreterGenerator; + address generate_deopt_entry_for(TosState state, int step); + private: address generate_normal_entry(bool synchronized);
--- a/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Sun Mar 17 21:14:35 2013 +0100 +++ b/src/cpu/x86/vm/templateInterpreter_x86_64.cpp Sun Mar 17 21:20:39 2013 +0100 @@ -204,13 +204,26 @@ } -address TemplateInterpreterGenerator::generate_deopt_entry_for(TosState state, +address InterpreterGenerator::generate_deopt_entry_for(TosState state, int step) { address entry = __ pc(); // NULL last_sp until next java call __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), (int32_t)NULL_WORD); __ restore_bcp(); __ restore_locals(); + // Check if we need to take lock at entry of synchronized method. + { + Label L; + __ cmpb(Address(r15_thread, Thread::pending_monitorenter_offset()), 0); + __ jcc(Assembler::zero, L); + // Clear flag. + __ movb(Address(r15_thread, Thread::pending_monitorenter_offset()), 0); + // Satisfy calling convention for lock_method(). + __ get_method(rbx); + // Take lock. + lock_method(); + __ bind(L); + } // handle exceptions { Label L;
--- a/src/share/vm/interpreter/templateInterpreter.cpp Sun Mar 17 21:14:35 2013 +0100 +++ b/src/share/vm/interpreter/templateInterpreter.cpp Sun Mar 17 21:20:39 2013 +0100 @@ -180,7 +180,7 @@ #endif // !PRODUCT EntryPoint TemplateInterpreter::_return_entry[TemplateInterpreter::number_of_return_entries]; EntryPoint TemplateInterpreter::_earlyret_entry; -EntryPoint TemplateInterpreter::_deopt_entry [TemplateInterpreter::number_of_deopt_entries ]; +EntryPoint TemplateInterpreter::_deopt_entry[TemplateInterpreter::number_of_deopt_entries ]; EntryPoint TemplateInterpreter::_continuation_entry; EntryPoint TemplateInterpreter::_safept_entry; @@ -272,15 +272,15 @@ for (int i = 0; i < Interpreter::number_of_deopt_entries; i++) { Interpreter::_deopt_entry[i] = EntryPoint( - generate_deopt_entry_for(itos, i), - generate_deopt_entry_for(itos, i), - generate_deopt_entry_for(itos, i), - generate_deopt_entry_for(atos, i), - generate_deopt_entry_for(itos, i), - generate_deopt_entry_for(ltos, i), - generate_deopt_entry_for(ftos, i), - generate_deopt_entry_for(dtos, i), - generate_deopt_entry_for(vtos, i) + ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i), + ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i), + ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i), + ((InterpreterGenerator*)this)->generate_deopt_entry_for(atos, i), + ((InterpreterGenerator*)this)->generate_deopt_entry_for(itos, i), + ((InterpreterGenerator*)this)->generate_deopt_entry_for(ltos, i), + ((InterpreterGenerator*)this)->generate_deopt_entry_for(ftos, i), + ((InterpreterGenerator*)this)->generate_deopt_entry_for(dtos, i), + ((InterpreterGenerator*)this)->generate_deopt_entry_for(vtos, i) ); } }
--- a/src/share/vm/interpreter/templateInterpreterGenerator.hpp Sun Mar 17 21:14:35 2013 +0100 +++ b/src/share/vm/interpreter/templateInterpreterGenerator.hpp Sun Mar 17 21:20:39 2013 +0100 @@ -55,7 +55,6 @@ address generate_continuation_for(TosState state); address generate_return_entry_for(TosState state, int step); address generate_earlyret_entry_for(TosState state); - address generate_deopt_entry_for(TosState state, int step); address generate_safept_entry_for(TosState state, address runtime_entry); void generate_throw_exception();
--- a/src/share/vm/runtime/deoptimization.cpp Sun Mar 17 21:14:35 2013 +0100 +++ b/src/share/vm/runtime/deoptimization.cpp Sun Mar 17 21:20:39 2013 +0100 @@ -1316,6 +1316,10 @@ methodHandle trap_method = trap_scope->method(); int trap_bci = trap_scope->bci(); + if (trap_bci == SynchronizationEntryBCI) { + trap_bci = 0; + Thread::current()->set_pending_monitorenter(true); + } Bytecodes::Code trap_bc = trap_method->java_code_at(trap_bci); if (trap_scope->rethrow_exception()) {
--- a/src/share/vm/runtime/vframeArray.cpp Sun Mar 17 21:14:35 2013 +0100 +++ b/src/share/vm/runtime/vframeArray.cpp Sun Mar 17 21:20:39 2013 +0100 @@ -286,7 +286,7 @@ _frame.patch_pc(thread, pc); - assert (!method()->is_synchronized() || locks > 0, "synchronized methods must have monitors"); + assert (!method()->is_synchronized() || locks > 0 || raw_bci() == SynchronizationEntryBCI, "synchronized methods must have monitors"); BasicObjectLock* top = iframe()->interpreter_frame_monitor_begin(); for (int index = 0; index < locks; index++) {
--- a/src/share/vm/utilities/exceptions.hpp Sun Mar 17 21:14:35 2013 +0100 +++ b/src/share/vm/utilities/exceptions.hpp Sun Mar 17 21:20:39 2013 +0100 @@ -61,6 +61,7 @@ friend class VMStructs; protected: + bool _pending_monitorenter; oop _pending_exception; // Thread has gc actions. const char* _exception_file; // file information for exception (debugging only) int _exception_line; // line information for exception (debugging only) @@ -79,9 +80,13 @@ bool has_pending_exception() const { return _pending_exception != NULL; } const char* exception_file() const { return _exception_file; } int exception_line() const { return _exception_line; } + bool has_pending_monitorenter() const { return _pending_monitorenter; } // Code generation support static ByteSize pending_exception_offset() { return byte_offset_of(ThreadShadow, _pending_exception); } + static ByteSize pending_monitorenter_offset() { return byte_offset_of(ThreadShadow, _pending_monitorenter); } + + bool set_pending_monitorenter(bool b) { return _pending_monitorenter = b; } // use THROW whenever possible! void set_pending_exception(oop exception, const char* file, int line); @@ -90,7 +95,7 @@ void clear_pending_exception(); ThreadShadow() : _pending_exception(NULL), - _exception_file(NULL), _exception_line(0) {} + _exception_file(NULL), _exception_line(0), _pending_monitorenter(false) {} };