1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/shark/sharkRuntime.cpp Wed Aug 11 05:51:21 2010 -0700 1.3 @@ -0,0 +1,251 @@ 1.4 +/* 1.5 + * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright 2008, 2009, 2010 Red Hat, Inc. 1.7 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.8 + * 1.9 + * This code is free software; you can redistribute it and/or modify it 1.10 + * under the terms of the GNU General Public License version 2 only, as 1.11 + * published by the Free Software Foundation. 1.12 + * 1.13 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.14 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.15 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.16 + * version 2 for more details (a copy is included in the LICENSE file that 1.17 + * accompanied this code). 1.18 + * 1.19 + * You should have received a copy of the GNU General Public License version 1.20 + * 2 along with this work; if not, write to the Free Software Foundation, 1.21 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.22 + * 1.23 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.24 + * or visit www.oracle.com if you need additional information or have any 1.25 + * questions. 1.26 + * 1.27 + */ 1.28 + 1.29 +#include "incls/_precompiled.incl" 1.30 +#include "incls/_sharkRuntime.cpp.incl" 1.31 + 1.32 +using namespace llvm; 1.33 + 1.34 +JRT_ENTRY(int, SharkRuntime::find_exception_handler(JavaThread* thread, 1.35 + int* indexes, 1.36 + int num_indexes)) 1.37 + constantPoolHandle pool(thread, method(thread)->constants()); 1.38 + KlassHandle exc_klass(thread, ((oop) tos_at(thread, 0))->klass()); 1.39 + 1.40 + for (int i = 0; i < num_indexes; i++) { 1.41 + klassOop tmp = pool->klass_at(indexes[i], CHECK_0); 1.42 + KlassHandle chk_klass(thread, tmp); 1.43 + 1.44 + if (exc_klass() == chk_klass()) 1.45 + return i; 1.46 + 1.47 + if (exc_klass()->klass_part()->is_subtype_of(chk_klass())) 1.48 + return i; 1.49 + } 1.50 + 1.51 + return -1; 1.52 +JRT_END 1.53 + 1.54 +JRT_ENTRY(void, SharkRuntime::monitorenter(JavaThread* thread, 1.55 + BasicObjectLock* lock)) 1.56 + if (PrintBiasedLockingStatistics) 1.57 + Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); 1.58 + 1.59 + Handle object(thread, lock->obj()); 1.60 + assert(Universe::heap()->is_in_reserved_or_null(object()), "should be"); 1.61 + if (UseBiasedLocking) { 1.62 + // Retry fast entry if bias is revoked to avoid unnecessary inflation 1.63 + ObjectSynchronizer::fast_enter(object, lock->lock(), true, CHECK); 1.64 + } else { 1.65 + ObjectSynchronizer::slow_enter(object, lock->lock(), CHECK); 1.66 + } 1.67 + assert(Universe::heap()->is_in_reserved_or_null(lock->obj()), "should be"); 1.68 +JRT_END 1.69 + 1.70 +JRT_ENTRY(void, SharkRuntime::monitorexit(JavaThread* thread, 1.71 + BasicObjectLock* lock)) 1.72 + Handle object(thread, lock->obj()); 1.73 + assert(Universe::heap()->is_in_reserved_or_null(object()), "should be"); 1.74 + if (lock == NULL || object()->is_unlocked()) { 1.75 + THROW(vmSymbols::java_lang_IllegalMonitorStateException()); 1.76 + } 1.77 + ObjectSynchronizer::slow_exit(object(), lock->lock(), thread); 1.78 +JRT_END 1.79 + 1.80 +JRT_ENTRY(void, SharkRuntime::new_instance(JavaThread* thread, int index)) 1.81 + klassOop k_oop = method(thread)->constants()->klass_at(index, CHECK); 1.82 + instanceKlassHandle klass(THREAD, k_oop); 1.83 + 1.84 + // Make sure we are not instantiating an abstract klass 1.85 + klass->check_valid_for_instantiation(true, CHECK); 1.86 + 1.87 + // Make sure klass is initialized 1.88 + klass->initialize(CHECK); 1.89 + 1.90 + // At this point the class may not be fully initialized 1.91 + // because of recursive initialization. If it is fully 1.92 + // initialized & has_finalized is not set, we rewrite 1.93 + // it into its fast version (Note: no locking is needed 1.94 + // here since this is an atomic byte write and can be 1.95 + // done more than once). 1.96 + // 1.97 + // Note: In case of classes with has_finalized we don't 1.98 + // rewrite since that saves us an extra check in 1.99 + // the fast version which then would call the 1.100 + // slow version anyway (and do a call back into 1.101 + // Java). 1.102 + // If we have a breakpoint, then we don't rewrite 1.103 + // because the _breakpoint bytecode would be lost. 1.104 + oop obj = klass->allocate_instance(CHECK); 1.105 + thread->set_vm_result(obj); 1.106 +JRT_END 1.107 + 1.108 +JRT_ENTRY(void, SharkRuntime::newarray(JavaThread* thread, 1.109 + BasicType type, 1.110 + int size)) 1.111 + oop obj = oopFactory::new_typeArray(type, size, CHECK); 1.112 + thread->set_vm_result(obj); 1.113 +JRT_END 1.114 + 1.115 +JRT_ENTRY(void, SharkRuntime::anewarray(JavaThread* thread, 1.116 + int index, 1.117 + int size)) 1.118 + klassOop klass = method(thread)->constants()->klass_at(index, CHECK); 1.119 + objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK); 1.120 + thread->set_vm_result(obj); 1.121 +JRT_END 1.122 + 1.123 +JRT_ENTRY(void, SharkRuntime::multianewarray(JavaThread* thread, 1.124 + int index, 1.125 + int ndims, 1.126 + int* dims)) 1.127 + klassOop klass = method(thread)->constants()->klass_at(index, CHECK); 1.128 + oop obj = arrayKlass::cast(klass)->multi_allocate(ndims, dims, CHECK); 1.129 + thread->set_vm_result(obj); 1.130 +JRT_END 1.131 + 1.132 +JRT_ENTRY(void, SharkRuntime::register_finalizer(JavaThread* thread, 1.133 + oop object)) 1.134 + assert(object->is_oop(), "should be"); 1.135 + assert(object->klass()->klass_part()->has_finalizer(), "should have"); 1.136 + instanceKlass::register_finalizer(instanceOop(object), CHECK); 1.137 +JRT_END 1.138 + 1.139 +JRT_ENTRY(void, SharkRuntime::throw_ArithmeticException(JavaThread* thread, 1.140 + const char* file, 1.141 + int line)) 1.142 + Exceptions::_throw_msg( 1.143 + thread, file, line, 1.144 + vmSymbols::java_lang_ArithmeticException(), 1.145 + ""); 1.146 +JRT_END 1.147 + 1.148 +JRT_ENTRY(void, SharkRuntime::throw_ArrayIndexOutOfBoundsException( 1.149 + JavaThread* thread, 1.150 + const char* file, 1.151 + int line, 1.152 + int index)) 1.153 + char msg[jintAsStringSize]; 1.154 + snprintf(msg, sizeof(msg), "%d", index); 1.155 + Exceptions::_throw_msg( 1.156 + thread, file, line, 1.157 + vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), 1.158 + msg); 1.159 +JRT_END 1.160 + 1.161 +JRT_ENTRY(void, SharkRuntime::throw_ClassCastException(JavaThread* thread, 1.162 + const char* file, 1.163 + int line)) 1.164 + Exceptions::_throw_msg( 1.165 + thread, file, line, 1.166 + vmSymbols::java_lang_ClassCastException(), 1.167 + ""); 1.168 +JRT_END 1.169 + 1.170 +JRT_ENTRY(void, SharkRuntime::throw_NullPointerException(JavaThread* thread, 1.171 + const char* file, 1.172 + int line)) 1.173 + Exceptions::_throw_msg( 1.174 + thread, file, line, 1.175 + vmSymbols::java_lang_NullPointerException(), 1.176 + ""); 1.177 +JRT_END 1.178 + 1.179 +// Non-VM calls 1.180 +// Nothing in these must ever GC! 1.181 + 1.182 +void SharkRuntime::dump(const char *name, intptr_t value) { 1.183 + oop valueOop = (oop) value; 1.184 + tty->print("%s = ", name); 1.185 + if (valueOop->is_oop(true)) 1.186 + valueOop->print_on(tty); 1.187 + else if (value >= ' ' && value <= '~') 1.188 + tty->print("'%c' (%d)", value, value); 1.189 + else 1.190 + tty->print("%p", value); 1.191 + tty->print_cr(""); 1.192 +} 1.193 + 1.194 +bool SharkRuntime::is_subtype_of(klassOop check_klass, klassOop object_klass) { 1.195 + return object_klass->klass_part()->is_subtype_of(check_klass); 1.196 +} 1.197 + 1.198 +int SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) { 1.199 + Thread *THREAD = thread; 1.200 + 1.201 + // In C2, uncommon_trap_blob creates a frame, so all the various 1.202 + // deoptimization functions expect to find the frame of the method 1.203 + // being deopted one frame down on the stack. We create a dummy 1.204 + // frame to mirror this. 1.205 + FakeStubFrame *stubframe = FakeStubFrame::build(CHECK_0); 1.206 + thread->push_zero_frame(stubframe); 1.207 + 1.208 + // Initiate the trap 1.209 + thread->set_last_Java_frame(); 1.210 + Deoptimization::UnrollBlock *urb = 1.211 + Deoptimization::uncommon_trap(thread, trap_request); 1.212 + thread->reset_last_Java_frame(); 1.213 + 1.214 + // Pop our dummy frame and the frame being deoptimized 1.215 + thread->pop_zero_frame(); 1.216 + thread->pop_zero_frame(); 1.217 + 1.218 + // Push skeleton frames 1.219 + int number_of_frames = urb->number_of_frames(); 1.220 + for (int i = 0; i < number_of_frames; i++) { 1.221 + intptr_t size = urb->frame_sizes()[i]; 1.222 + InterpreterFrame *frame = InterpreterFrame::build(size, CHECK_0); 1.223 + thread->push_zero_frame(frame); 1.224 + } 1.225 + 1.226 + // Push another dummy frame 1.227 + stubframe = FakeStubFrame::build(CHECK_0); 1.228 + thread->push_zero_frame(stubframe); 1.229 + 1.230 + // Fill in the skeleton frames 1.231 + thread->set_last_Java_frame(); 1.232 + Deoptimization::unpack_frames(thread, Deoptimization::Unpack_uncommon_trap); 1.233 + thread->reset_last_Java_frame(); 1.234 + 1.235 + // Pop our dummy frame 1.236 + thread->pop_zero_frame(); 1.237 + 1.238 + // Fall back into the interpreter 1.239 + return number_of_frames; 1.240 +} 1.241 + 1.242 +FakeStubFrame* FakeStubFrame::build(TRAPS) { 1.243 + ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack(); 1.244 + stack->overflow_check(header_words, CHECK_NULL); 1.245 + 1.246 + stack->push(0); // next_frame, filled in later 1.247 + intptr_t *fp = stack->sp(); 1.248 + assert(fp - stack->sp() == next_frame_off, "should be"); 1.249 + 1.250 + stack->push(FAKE_STUB_FRAME); 1.251 + assert(fp - stack->sp() == frame_type_off, "should be"); 1.252 + 1.253 + return (FakeStubFrame *) fp; 1.254 +}