sharkRuntime.cpp revision 3602:da91efe96a93
1/* 2 * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 3 * Copyright 2008, 2009, 2010 Red Hat, Inc. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 * 24 */ 25 26#include "precompiled.hpp" 27#include "runtime/biasedLocking.hpp" 28#include "runtime/deoptimization.hpp" 29#include "runtime/thread.hpp" 30#include "shark/llvmHeaders.hpp" 31#include "shark/sharkRuntime.hpp" 32#ifdef TARGET_ARCH_zero 33# include "stack_zero.inline.hpp" 34#endif 35 36using namespace llvm; 37 38JRT_ENTRY(int, SharkRuntime::find_exception_handler(JavaThread* thread, 39 int* indexes, 40 int num_indexes)) 41 constantPoolHandle pool(thread, method(thread)->constants()); 42 KlassHandle exc_klass(thread, ((oop) tos_at(thread, 0))->klass()); 43 44 for (int i = 0; i < num_indexes; i++) { 45 Klass* tmp = pool->klass_at(indexes[i], CHECK_0); 46 KlassHandle chk_klass(thread, tmp); 47 48 if (exc_klass() == chk_klass()) 49 return i; 50 51 if (exc_klass()->is_subtype_of(chk_klass())) 52 return i; 53 } 54 55 return -1; 56JRT_END 57 58JRT_ENTRY(void, SharkRuntime::monitorenter(JavaThread* thread, 59 BasicObjectLock* lock)) 60 if (PrintBiasedLockingStatistics) 61 Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); 62 63 Handle object(thread, lock->obj()); 64 assert(Universe::heap()->is_in_reserved_or_null(object()), "should be"); 65 if (UseBiasedLocking) { 66 // Retry fast entry if bias is revoked to avoid unnecessary inflation 67 ObjectSynchronizer::fast_enter(object, lock->lock(), true, CHECK); 68 } else { 69 ObjectSynchronizer::slow_enter(object, lock->lock(), CHECK); 70 } 71 assert(Universe::heap()->is_in_reserved_or_null(lock->obj()), "should be"); 72JRT_END 73 74JRT_ENTRY(void, SharkRuntime::monitorexit(JavaThread* thread, 75 BasicObjectLock* lock)) 76 Handle object(thread, lock->obj()); 77 assert(Universe::heap()->is_in_reserved_or_null(object()), "should be"); 78 if (lock == NULL || object()->is_unlocked()) { 79 THROW(vmSymbols::java_lang_IllegalMonitorStateException()); 80 } 81 ObjectSynchronizer::slow_exit(object(), lock->lock(), thread); 82JRT_END 83 84JRT_ENTRY(void, SharkRuntime::new_instance(JavaThread* thread, int index)) 85 Klass* k_oop = method(thread)->constants()->klass_at(index, CHECK); 86 instanceKlassHandle klass(THREAD, k_oop); 87 88 // Make sure we are not instantiating an abstract klass 89 klass->check_valid_for_instantiation(true, CHECK); 90 91 // Make sure klass is initialized 92 klass->initialize(CHECK); 93 94 // At this point the class may not be fully initialized 95 // because of recursive initialization. If it is fully 96 // initialized & has_finalized is not set, we rewrite 97 // it into its fast version (Note: no locking is needed 98 // here since this is an atomic byte write and can be 99 // done more than once). 100 // 101 // Note: In case of classes with has_finalized we don't 102 // rewrite since that saves us an extra check in 103 // the fast version which then would call the 104 // slow version anyway (and do a call back into 105 // Java). 106 // If we have a breakpoint, then we don't rewrite 107 // because the _breakpoint bytecode would be lost. 108 oop obj = klass->allocate_instance(CHECK); 109 thread->set_vm_result(obj); 110JRT_END 111 112JRT_ENTRY(void, SharkRuntime::newarray(JavaThread* thread, 113 BasicType type, 114 int size)) 115 oop obj = oopFactory::new_typeArray(type, size, CHECK); 116 thread->set_vm_result(obj); 117JRT_END 118 119JRT_ENTRY(void, SharkRuntime::anewarray(JavaThread* thread, 120 int index, 121 int size)) 122 Klass* klass = method(thread)->constants()->klass_at(index, CHECK); 123 objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK); 124 thread->set_vm_result(obj); 125JRT_END 126 127JRT_ENTRY(void, SharkRuntime::multianewarray(JavaThread* thread, 128 int index, 129 int ndims, 130 int* dims)) 131 Klass* klass = method(thread)->constants()->klass_at(index, CHECK); 132 oop obj = arrayKlass::cast(klass)->multi_allocate(ndims, dims, CHECK); 133 thread->set_vm_result(obj); 134JRT_END 135 136JRT_ENTRY(void, SharkRuntime::register_finalizer(JavaThread* thread, 137 oop object)) 138 assert(object->is_oop(), "should be"); 139 assert(object->klass()->has_finalizer(), "should have"); 140 InstanceKlass::register_finalizer(instanceOop(object), CHECK); 141JRT_END 142 143JRT_ENTRY(void, SharkRuntime::throw_ArithmeticException(JavaThread* thread, 144 const char* file, 145 int line)) 146 Exceptions::_throw_msg( 147 thread, file, line, 148 vmSymbols::java_lang_ArithmeticException(), 149 ""); 150JRT_END 151 152JRT_ENTRY(void, SharkRuntime::throw_ArrayIndexOutOfBoundsException( 153 JavaThread* thread, 154 const char* file, 155 int line, 156 int index)) 157 char msg[jintAsStringSize]; 158 snprintf(msg, sizeof(msg), "%d", index); 159 Exceptions::_throw_msg( 160 thread, file, line, 161 vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), 162 msg); 163JRT_END 164 165JRT_ENTRY(void, SharkRuntime::throw_ClassCastException(JavaThread* thread, 166 const char* file, 167 int line)) 168 Exceptions::_throw_msg( 169 thread, file, line, 170 vmSymbols::java_lang_ClassCastException(), 171 ""); 172JRT_END 173 174JRT_ENTRY(void, SharkRuntime::throw_NullPointerException(JavaThread* thread, 175 const char* file, 176 int line)) 177 Exceptions::_throw_msg( 178 thread, file, line, 179 vmSymbols::java_lang_NullPointerException(), 180 ""); 181JRT_END 182 183// Non-VM calls 184// Nothing in these must ever GC! 185 186void SharkRuntime::dump(const char *name, intptr_t value) { 187 oop valueOop = (oop) value; 188 tty->print("%s = ", name); 189 if (valueOop->is_oop(true)) 190 valueOop->print_on(tty); 191 else if (value >= ' ' && value <= '~') 192 tty->print("'%c' (%d)", value, value); 193 else 194 tty->print("%p", value); 195 tty->print_cr(""); 196} 197 198bool SharkRuntime::is_subtype_of(Klass* check_klass, Klass* object_klass) { 199 return object_klass->is_subtype_of(check_klass); 200} 201 202int SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) { 203 Thread *THREAD = thread; 204 205 // In C2, uncommon_trap_blob creates a frame, so all the various 206 // deoptimization functions expect to find the frame of the method 207 // being deopted one frame down on the stack. We create a dummy 208 // frame to mirror this. 209 FakeStubFrame *stubframe = FakeStubFrame::build(CHECK_0); 210 thread->push_zero_frame(stubframe); 211 212 // Initiate the trap 213 thread->set_last_Java_frame(); 214 Deoptimization::UnrollBlock *urb = 215 Deoptimization::uncommon_trap(thread, trap_request); 216 thread->reset_last_Java_frame(); 217 218 // Pop our dummy frame and the frame being deoptimized 219 thread->pop_zero_frame(); 220 thread->pop_zero_frame(); 221 222 // Push skeleton frames 223 int number_of_frames = urb->number_of_frames(); 224 for (int i = 0; i < number_of_frames; i++) { 225 intptr_t size = urb->frame_sizes()[i]; 226 InterpreterFrame *frame = InterpreterFrame::build(size, CHECK_0); 227 thread->push_zero_frame(frame); 228 } 229 230 // Push another dummy frame 231 stubframe = FakeStubFrame::build(CHECK_0); 232 thread->push_zero_frame(stubframe); 233 234 // Fill in the skeleton frames 235 thread->set_last_Java_frame(); 236 Deoptimization::unpack_frames(thread, Deoptimization::Unpack_uncommon_trap); 237 thread->reset_last_Java_frame(); 238 239 // Pop our dummy frame 240 thread->pop_zero_frame(); 241 242 // Fall back into the interpreter 243 return number_of_frames; 244} 245 246FakeStubFrame* FakeStubFrame::build(TRAPS) { 247 ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack(); 248 stack->overflow_check(header_words, CHECK_NULL); 249 250 stack->push(0); // next_frame, filled in later 251 intptr_t *fp = stack->sp(); 252 assert(fp - stack->sp() == next_frame_off, "should be"); 253 254 stack->push(FAKE_STUB_FRAME); 255 assert(fp - stack->sp() == frame_type_off, "should be"); 256 257 return (FakeStubFrame *) fp; 258} 259