//------------------------------generate_exception_blob--------------------------- // creates exception blob at the end // Using exception blob, this code is jumped from a compiled method. // // Given an exception pc at a call we call into the runtime for the // handler in this method. This handler might merely restore state // (i.e. callee save registers) unwind the frame and jump to the // exception handler for the nmethod if there is no Java level handler // for the nmethod. // // This code is entered with a jmp. // // Arguments: // rax: exception oop // rdx: exception pc // // Results: // rax: exception oop // rdx: exception pc in caller or ??? // destination: exception handler of caller // // Note: the exception pc MUST be at a call (precise debug information) // Only register rax, rdx, rcx are not callee saved. //
void OptoRuntime::generate_exception_blob() {
// Capture info about frame layout enum layout {
thread_off, // last_java_sp // The frame sender code expects that rbp will be in the "natural" place and // will override any oopMap setting for it. We must therefore force the layout // so that it agrees with the frame sender code.
rbp_off,
return_off, // slot for return address
framesize
};
// allocate space for the code
ResourceMark rm; // setup code generation tools
CodeBuffer buffer("exception_blob", 512, 512);
MacroAssembler* masm = new MacroAssembler(&buffer);
// rbp, location is implicitly known
__ movptr(Address(rsp,rbp_off *wordSize), rbp);
// Store exception in Thread object. We cannot pass any arguments to the // handle_exception call, since we do not want to make any assumption // about the size of the frame where the exception happened in.
__ get_thread(rcx);
__ movptr(Address(rcx, JavaThread::exception_oop_offset()), rax);
__ movptr(Address(rcx, JavaThread::exception_pc_offset()), rdx);
// This call does all the hard work. It checks if an exception handler // exists in the method. // If so, it returns the handler address. // If not, it prepares for stack-unwinding, restoring the callee-save // registers of the frame being removed. //
__ movptr(Address(rsp, thread_off * wordSize), rcx); // Thread is first argument
__ set_last_Java_frame(rcx, noreg, noreg, NULL, noreg);
// No registers to map, rbp is known implicitly
oop_maps->add_gc_map( __ pc() - start, new OopMap( framesize, 0 ));
__ get_thread(rcx);
__ reset_last_Java_frame(rcx, false);
// rax: exception handler for given <exception oop/exception pc>
// We have a handler in rax, (could be deopt blob) // rdx - throwing pc, deopt blob will need it.
__ push(rax);
// Get the exception
__ movptr(rax, Address(rcx, JavaThread::exception_oop_offset())); // Get the exception pc in case we are deoptimized
__ movptr(rdx, Address(rcx, JavaThread::exception_pc_offset())); #ifdef ASSERT
__ movptr(Address(rcx, JavaThread::exception_handler_pc_offset()), NULL_WORD);
__ movptr(Address(rcx, JavaThread::exception_pc_offset()), NULL_WORD); #endif // Clear the exception oop so GC no longer processes it as a root.
__ movptr(Address(rcx, JavaThread::exception_oop_offset()), NULL_WORD);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.