runtime_sparc.cpp revision 0:a61af66fc99e
1104476Ssam/* 2139825Simp * Copyright 1998-2006 Sun Microsystems, Inc. All Rights Reserved. 3104476Ssam * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4104476Ssam * 5104476Ssam * This code is free software; you can redistribute it and/or modify it 6104476Ssam * under the terms of the GNU General Public License version 2 only, as 7104476Ssam * published by the Free Software Foundation. 8104476Ssam * 9104476Ssam * This code is distributed in the hope that it will be useful, but WITHOUT 10104476Ssam * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11104476Ssam * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12104476Ssam * version 2 for more details (a copy is included in the LICENSE file that 13104476Ssam * accompanied this code). 14104476Ssam * 15104476Ssam * You should have received a copy of the GNU General Public License version 16104476Ssam * 2 along with this work; if not, write to the Free Software Foundation, 17104476Ssam * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18104476Ssam * 19104476Ssam * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20104476Ssam * CA 95054 USA or visit www.sun.com if you need additional information or 21104476Ssam * have any questions. 22104476Ssam * 23104476Ssam */ 24104476Ssam 25104476Ssam#include "incls/_precompiled.incl" 26104476Ssam#include "incls/_runtime_sparc.cpp.incl" 27104476Ssam 28104476Ssam 29104476Ssam#define __ masm-> 30104476Ssam 31104476SsamExceptionBlob *OptoRuntime::_exception_blob; 32104476Ssam 33104476Ssam//------------------------------ generate_exception_blob --------------------------- 34104476Ssam// creates exception blob at the end 35104476Ssam// Using exception blob, this code is jumped from a compiled method. 36104476Ssam// (see emit_exception_handler in sparc.ad file) 37104476Ssam// 38104476Ssam// Given an exception pc at a call we call into the runtime for the 39116191Sobrien// handler in this method. This handler might merely restore state 40116191Sobrien// (i.e. callee save registers) unwind the frame and jump to the 41116191Sobrien// exception handler for the nmethod if there is no Java level handler 42104476Ssam// for the nmethod. 43104476Ssam// 44104476Ssam// This code is entered with a jmp. 45104476Ssam// 46104476Ssam// Arguments: 47104476Ssam// O0: exception oop 48104476Ssam// O1: exception pc 49104476Ssam// 50104476Ssam// Results: 51104476Ssam// O0: exception oop 52104476Ssam// O1: exception pc in caller or ??? 53143423Sume// destination: exception handler of caller 54169425Sgnn// 55104476Ssam// Note: the exception pc MUST be at a call (precise debug information) 56104476Ssam// 57104476Ssamvoid OptoRuntime::generate_exception_blob() { 58104476Ssam // allocate space for code 59104476Ssam ResourceMark rm; 60104476Ssam int pad = VerifyThread ? 256 : 0;// Extra slop space for more verify code 61104476Ssam 62104476Ssam // setup code generation tools 63104476Ssam // Measured 8/7/03 at 256 in 32bit debug build (no VerifyThread) 64104476Ssam // Measured 8/7/03 at 528 in 32bit debug build (VerifyThread) 65104476Ssam CodeBuffer buffer("exception_blob", 600+pad, 512); 66104476Ssam MacroAssembler* masm = new MacroAssembler(&buffer); 67104476Ssam 68104476Ssam int framesize_in_bytes = __ total_frame_size_in_bytes(0); 69104476Ssam int framesize_in_words = framesize_in_bytes / wordSize; 70104476Ssam int framesize_in_slots = framesize_in_bytes / sizeof(jint); 71104476Ssam 72104476Ssam Label L; 73104476Ssam 74104476Ssam int start = __ offset(); 75104476Ssam 76104476Ssam __ verify_thread(); 77104476Ssam __ st_ptr(Oexception, Address(G2_thread, 0, in_bytes(JavaThread::exception_oop_offset()))); 78169425Sgnn __ st_ptr(Oissuing_pc, Address(G2_thread, 0, in_bytes(JavaThread::exception_pc_offset()))); 79104476Ssam 80104476Ssam // This call does all the hard work. It checks if an exception catch 81104476Ssam // exists in the method. 82104476Ssam // If so, it returns the handler address. 83104476Ssam // If the nmethod has been deoptimized and it had a handler the handler 84104476Ssam // address is the deopt blob unpack_with_exception entry. 85169425Sgnn // 86104476Ssam // If no handler exists it prepares for stack-unwinding, restoring the callee-save 87104476Ssam // registers of the frame being removed. 88104476Ssam // 89104476Ssam __ save_frame(0); 90104476Ssam 91104476Ssam __ mov(G2_thread, O0); 92169425Sgnn __ set_last_Java_frame(SP, noreg); 93104476Ssam __ save_thread(L7_thread_cache); 94104476Ssam 95104476Ssam // This call can block at exit and nmethod can be deoptimized at that 96104476Ssam // point. If the nmethod had a catch point we would jump to the 97104476Ssam // now deoptimized catch point and fall thru the vanilla deopt 98104476Ssam // path and lose the exception 99169425Sgnn // Sure would be simpler if this call didn't block! 100104476Ssam __ call(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C), relocInfo::runtime_call_type); 101104476Ssam __ delayed()->mov(L7_thread_cache, O0); 102104476Ssam 103104476Ssam // Set an oopmap for the call site. This oopmap will only be used if we 104104476Ssam // are unwinding the stack. Hence, all locations will be dead. 105104476Ssam // Callee-saved registers will be the same as the frame above (i.e., 106104476Ssam // handle_exception_stub), since they were restored when we got the 107104476Ssam // exception. 108104476Ssam 109104476Ssam OopMapSet *oop_maps = new OopMapSet(); 110104476Ssam oop_maps->add_gc_map( __ offset()-start, new OopMap(framesize_in_slots, 0)); 111104476Ssam 112104476Ssam __ bind(L); 113104476Ssam __ restore_thread(L7_thread_cache); 114104476Ssam __ reset_last_Java_frame(); 115104476Ssam 116104476Ssam __ mov(O0, G3_scratch); // Move handler address to temp 117104476Ssam __ restore(); 118104476Ssam 119104476Ssam // G3_scratch contains handler address 120104476Ssam // Since this may be the deopt blob we must set O7 to look like we returned 121104476Ssam // from the original pc that threw the exception 122159235Spjd 123104476Ssam __ ld_ptr(Address(G2_thread, 0, in_bytes(JavaThread::exception_pc_offset())), O7); 124104476Ssam __ sub(O7, frame::pc_return_offset, O7); 125104476Ssam 126104476Ssam 127104476Ssam assert(Assembler::is_simm13(in_bytes(JavaThread::exception_oop_offset())), "exception offset overflows simm13, following ld instruction cannot be in delay slot"); 128104476Ssam __ ld_ptr(Address(G2_thread, 0, in_bytes(JavaThread::exception_oop_offset())), Oexception); // O0 129104476Ssam#ifdef ASSERT 130104476Ssam __ st_ptr(G0, Address(G2_thread, 0, in_bytes(JavaThread::exception_handler_pc_offset()))); 131159235Spjd __ st_ptr(G0, Address(G2_thread, 0, in_bytes(JavaThread::exception_pc_offset()))); 132104476Ssam#endif 133104476Ssam __ JMP(G3_scratch, 0); 134104476Ssam // Clear the exception oop so GC no longer processes it as a root. 135104476Ssam __ delayed()->st_ptr(G0, Address(G2_thread, 0, in_bytes(JavaThread::exception_oop_offset()))); 136104476Ssam 137104476Ssam // ------------- 138104476Ssam // make sure all code is generated 139104476Ssam masm->flush(); 140159235Spjd 141104476Ssam _exception_blob = ExceptionBlob::create(&buffer, oop_maps, framesize_in_words); 142104476Ssam} 143104476Ssam