# HG changeset patch # User Thomas Wuerthinger # Date 1363551639 -3600 # Node ID 6b6cbd8b891456efc4ee08a8d96cb3b8211bf60b # Parent e24fb475bdece52de6e49cb22d876705b5d324c2 Support deoptimizing before the entry to a synchronized method. diff -r e24fb475bdec -r 6b6cbd8b8914 src/cpu/x86/vm/interpreterGenerator_x86.hpp --- 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); diff -r e24fb475bdec -r 6b6cbd8b8914 src/cpu/x86/vm/templateInterpreter_x86_64.cpp --- 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; diff -r e24fb475bdec -r 6b6cbd8b8914 src/share/vm/interpreter/templateInterpreter.cpp --- 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) ); } } diff -r e24fb475bdec -r 6b6cbd8b8914 src/share/vm/interpreter/templateInterpreterGenerator.hpp --- 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(); diff -r e24fb475bdec -r 6b6cbd8b8914 src/share/vm/runtime/deoptimization.cpp --- 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()) { diff -r e24fb475bdec -r 6b6cbd8b8914 src/share/vm/runtime/vframeArray.cpp --- 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++) { diff -r e24fb475bdec -r 6b6cbd8b8914 src/share/vm/utilities/exceptions.hpp --- 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) {} };