1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/cpu/sparc/vm/runtime_sparc.cpp Wed Apr 27 01:25:04 2016 +0800 1.3 @@ -0,0 +1,158 @@ 1.4 +/* 1.5 + * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#ifdef COMPILER2 1.30 +#include "asm/macroAssembler.inline.hpp" 1.31 +#include "classfile/systemDictionary.hpp" 1.32 +#include "code/vmreg.hpp" 1.33 +#include "interpreter/interpreter.hpp" 1.34 +#include "nativeInst_sparc.hpp" 1.35 +#include "opto/runtime.hpp" 1.36 +#include "runtime/interfaceSupport.hpp" 1.37 +#include "runtime/sharedRuntime.hpp" 1.38 +#include "runtime/stubRoutines.hpp" 1.39 +#include "runtime/vframeArray.hpp" 1.40 +#include "utilities/globalDefinitions.hpp" 1.41 +#include "vmreg_sparc.inline.hpp" 1.42 +#endif 1.43 + 1.44 + 1.45 +#define __ masm-> 1.46 + 1.47 +//------------------------------ generate_exception_blob --------------------------- 1.48 +// creates exception blob at the end 1.49 +// Using exception blob, this code is jumped from a compiled method. 1.50 +// (see emit_exception_handler in sparc.ad file) 1.51 +// 1.52 +// Given an exception pc at a call we call into the runtime for the 1.53 +// handler in this method. This handler might merely restore state 1.54 +// (i.e. callee save registers) unwind the frame and jump to the 1.55 +// exception handler for the nmethod if there is no Java level handler 1.56 +// for the nmethod. 1.57 +// 1.58 +// This code is entered with a jmp. 1.59 +// 1.60 +// Arguments: 1.61 +// O0: exception oop 1.62 +// O1: exception pc 1.63 +// 1.64 +// Results: 1.65 +// O0: exception oop 1.66 +// O1: exception pc in caller or ??? 1.67 +// destination: exception handler of caller 1.68 +// 1.69 +// Note: the exception pc MUST be at a call (precise debug information) 1.70 +// 1.71 +void OptoRuntime::generate_exception_blob() { 1.72 + // allocate space for code 1.73 + ResourceMark rm; 1.74 + int pad = VerifyThread ? 256 : 0;// Extra slop space for more verify code 1.75 + 1.76 + // setup code generation tools 1.77 + // Measured 8/7/03 at 256 in 32bit debug build (no VerifyThread) 1.78 + // Measured 8/7/03 at 528 in 32bit debug build (VerifyThread) 1.79 + CodeBuffer buffer("exception_blob", 600+pad, 512); 1.80 + MacroAssembler* masm = new MacroAssembler(&buffer); 1.81 + 1.82 + int framesize_in_bytes = __ total_frame_size_in_bytes(0); 1.83 + int framesize_in_words = framesize_in_bytes / wordSize; 1.84 + int framesize_in_slots = framesize_in_bytes / sizeof(jint); 1.85 + 1.86 + Label L; 1.87 + 1.88 + int start = __ offset(); 1.89 + 1.90 + __ verify_thread(); 1.91 + __ st_ptr(Oexception, G2_thread, JavaThread::exception_oop_offset()); 1.92 + __ st_ptr(Oissuing_pc, G2_thread, JavaThread::exception_pc_offset()); 1.93 + 1.94 + // This call does all the hard work. It checks if an exception catch 1.95 + // exists in the method. 1.96 + // If so, it returns the handler address. 1.97 + // If the nmethod has been deoptimized and it had a handler the handler 1.98 + // address is the deopt blob unpack_with_exception entry. 1.99 + // 1.100 + // If no handler exists it prepares for stack-unwinding, restoring the callee-save 1.101 + // registers of the frame being removed. 1.102 + // 1.103 + __ save_frame(0); 1.104 + 1.105 + __ mov(G2_thread, O0); 1.106 + __ set_last_Java_frame(SP, noreg); 1.107 + __ save_thread(L7_thread_cache); 1.108 + 1.109 + // This call can block at exit and nmethod can be deoptimized at that 1.110 + // point. If the nmethod had a catch point we would jump to the 1.111 + // now deoptimized catch point and fall thru the vanilla deopt 1.112 + // path and lose the exception 1.113 + // Sure would be simpler if this call didn't block! 1.114 + __ call(CAST_FROM_FN_PTR(address, OptoRuntime::handle_exception_C), relocInfo::runtime_call_type); 1.115 + __ delayed()->mov(L7_thread_cache, O0); 1.116 + 1.117 + // Set an oopmap for the call site. This oopmap will only be used if we 1.118 + // are unwinding the stack. Hence, all locations will be dead. 1.119 + // Callee-saved registers will be the same as the frame above (i.e., 1.120 + // handle_exception_stub), since they were restored when we got the 1.121 + // exception. 1.122 + 1.123 + OopMapSet *oop_maps = new OopMapSet(); 1.124 + oop_maps->add_gc_map( __ offset()-start, new OopMap(framesize_in_slots, 0)); 1.125 + 1.126 + __ bind(L); 1.127 + __ restore_thread(L7_thread_cache); 1.128 + __ reset_last_Java_frame(); 1.129 + 1.130 + __ mov(O0, G3_scratch); // Move handler address to temp 1.131 + __ restore(); 1.132 + 1.133 + // Restore SP from L7 if the exception PC is a MethodHandle call site. 1.134 + __ lduw(Address(G2_thread, JavaThread::is_method_handle_return_offset()), O7); 1.135 + __ tst(O7); 1.136 + __ movcc(Assembler::notZero, false, Assembler::icc, L7_mh_SP_save, SP); 1.137 + 1.138 + // G3_scratch contains handler address 1.139 + // Since this may be the deopt blob we must set O7 to look like we returned 1.140 + // from the original pc that threw the exception 1.141 + 1.142 + __ ld_ptr(G2_thread, JavaThread::exception_pc_offset(), O7); 1.143 + __ sub(O7, frame::pc_return_offset, O7); 1.144 + 1.145 + 1.146 + assert(Assembler::is_simm13(in_bytes(JavaThread::exception_oop_offset())), "exception offset overflows simm13, following ld instruction cannot be in delay slot"); 1.147 + __ ld_ptr(G2_thread, JavaThread::exception_oop_offset(), Oexception); // O0 1.148 +#ifdef ASSERT 1.149 + __ st_ptr(G0, G2_thread, JavaThread::exception_handler_pc_offset()); 1.150 + __ st_ptr(G0, G2_thread, JavaThread::exception_pc_offset()); 1.151 +#endif 1.152 + __ JMP(G3_scratch, 0); 1.153 + // Clear the exception oop so GC no longer processes it as a root. 1.154 + __ delayed()->st_ptr(G0, G2_thread, JavaThread::exception_oop_offset()); 1.155 + 1.156 + // ------------- 1.157 + // make sure all code is generated 1.158 + masm->flush(); 1.159 + 1.160 + _exception_blob = ExceptionBlob::create(&buffer, oop_maps, framesize_in_words); 1.161 +}