1 /* 2 * Copyright (c) 1999, 2007, 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 "incls/_precompiled.incl" 27 #include "incls/_sharkRuntime.cpp.incl" 28 29 using namespace llvm; 30 31 JRT_ENTRY(int, SharkRuntime::find_exception_handler(JavaThread* thread, 32 int* indexes, 33 int num_indexes)) 34 constantPoolHandle pool(thread, method(thread)->constants()); 35 KlassHandle exc_klass(thread, ((oop) tos_at(thread, 0))->klass()); 36 37 for (int i = 0; i < num_indexes; i++) { 38 klassOop tmp = pool->klass_at(indexes[i], CHECK_0); 39 KlassHandle chk_klass(thread, tmp); 40 41 if (exc_klass() == chk_klass()) 42 return i; 43 44 if (exc_klass()->klass_part()->is_subtype_of(chk_klass())) 45 return i; 46 } 47 48 return -1; 49 JRT_END 50 51 JRT_ENTRY(void, SharkRuntime::monitorenter(JavaThread* thread, 52 BasicObjectLock* lock)) 53 if (PrintBiasedLockingStatistics) 54 Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); 55 56 Handle object(thread, lock->obj()); 57 assert(Universe::heap()->is_in_reserved_or_null(object()), "should be"); 58 if (UseBiasedLocking) { 59 // Retry fast entry if bias is revoked to avoid unnecessary inflation 60 ObjectSynchronizer::fast_enter(object, lock->lock(), true, CHECK); 61 } else { 62 ObjectSynchronizer::slow_enter(object, lock->lock(), CHECK); 63 } 64 assert(Universe::heap()->is_in_reserved_or_null(lock->obj()), "should be"); 65 JRT_END 66 67 JRT_ENTRY(void, SharkRuntime::monitorexit(JavaThread* thread, 68 BasicObjectLock* lock)) 69 Handle object(thread, lock->obj()); 70 assert(Universe::heap()->is_in_reserved_or_null(object()), "should be"); 71 if (lock == NULL || object()->is_unlocked()) { 72 THROW(vmSymbols::java_lang_IllegalMonitorStateException()); 73 } 74 ObjectSynchronizer::slow_exit(object(), lock->lock(), thread); 75 JRT_END 76 77 JRT_ENTRY(void, SharkRuntime::new_instance(JavaThread* thread, int index)) 78 klassOop k_oop = method(thread)->constants()->klass_at(index, CHECK); 79 instanceKlassHandle klass(THREAD, k_oop); 80 81 // Make sure we are not instantiating an abstract klass 82 klass->check_valid_for_instantiation(true, CHECK); 83 84 // Make sure klass is initialized 85 klass->initialize(CHECK); 86 87 // At this point the class may not be fully initialized 88 // because of recursive initialization. If it is fully 89 // initialized & has_finalized is not set, we rewrite 90 // it into its fast version (Note: no locking is needed 91 // here since this is an atomic byte write and can be 92 // done more than once). 93 // 94 // Note: In case of classes with has_finalized we don't 95 // rewrite since that saves us an extra check in 96 // the fast version which then would call the 97 // slow version anyway (and do a call back into 98 // Java). 99 // If we have a breakpoint, then we don't rewrite 100 // because the _breakpoint bytecode would be lost. 101 oop obj = klass->allocate_instance(CHECK); 102 thread->set_vm_result(obj); 103 JRT_END 104 105 JRT_ENTRY(void, SharkRuntime::newarray(JavaThread* thread, 106 BasicType type, 107 int size)) 108 oop obj = oopFactory::new_typeArray(type, size, CHECK); 109 thread->set_vm_result(obj); 110 JRT_END 111 112 JRT_ENTRY(void, SharkRuntime::anewarray(JavaThread* thread, 113 int index, 114 int size)) 115 klassOop klass = method(thread)->constants()->klass_at(index, CHECK); 116 objArrayOop obj = oopFactory::new_objArray(klass, size, CHECK); 117 thread->set_vm_result(obj); 118 JRT_END 119 120 JRT_ENTRY(void, SharkRuntime::multianewarray(JavaThread* thread, 121 int index, 122 int ndims, 123 int* dims)) 124 klassOop klass = method(thread)->constants()->klass_at(index, CHECK); 125 oop obj = arrayKlass::cast(klass)->multi_allocate(ndims, dims, CHECK); 126 thread->set_vm_result(obj); 127 JRT_END 128 129 JRT_ENTRY(void, SharkRuntime::register_finalizer(JavaThread* thread, 130 oop object)) 131 assert(object->is_oop(), "should be"); 132 assert(object->klass()->klass_part()->has_finalizer(), "should have"); 133 instanceKlass::register_finalizer(instanceOop(object), CHECK); 134 JRT_END 135 136 JRT_ENTRY(void, SharkRuntime::throw_ArithmeticException(JavaThread* thread, 137 const char* file, 138 int line)) 139 Exceptions::_throw_msg( 140 thread, file, line, 141 vmSymbols::java_lang_ArithmeticException(), 142 ""); 143 JRT_END 144 145 JRT_ENTRY(void, SharkRuntime::throw_ArrayIndexOutOfBoundsException( 146 JavaThread* thread, 147 const char* file, 148 int line, 149 int index)) 150 char msg[jintAsStringSize]; 151 snprintf(msg, sizeof(msg), "%d", index); 152 Exceptions::_throw_msg( 153 thread, file, line, 154 vmSymbols::java_lang_ArrayIndexOutOfBoundsException(), 155 msg); 156 JRT_END 157 158 JRT_ENTRY(void, SharkRuntime::throw_ClassCastException(JavaThread* thread, 159 const char* file, 160 int line)) 161 Exceptions::_throw_msg( 162 thread, file, line, 163 vmSymbols::java_lang_ClassCastException(), 164 ""); 165 JRT_END 166 167 JRT_ENTRY(void, SharkRuntime::throw_NullPointerException(JavaThread* thread, 168 const char* file, 169 int line)) 170 Exceptions::_throw_msg( 171 thread, file, line, 172 vmSymbols::java_lang_NullPointerException(), 173 ""); 174 JRT_END 175 176 // Non-VM calls 177 // Nothing in these must ever GC! 178 179 void SharkRuntime::dump(const char *name, intptr_t value) { 180 oop valueOop = (oop) value; 181 tty->print("%s = ", name); 182 if (valueOop->is_oop(true)) 183 valueOop->print_on(tty); 184 else if (value >= ' ' && value <= '~') 185 tty->print("'%c' (%d)", value, value); 186 else 187 tty->print("%p", value); 188 tty->print_cr(""); 189 } 190 191 bool SharkRuntime::is_subtype_of(klassOop check_klass, klassOop object_klass) { 192 return object_klass->klass_part()->is_subtype_of(check_klass); 193 } 194 195 int SharkRuntime::uncommon_trap(JavaThread* thread, int trap_request) { 196 Thread *THREAD = thread; 197 198 // In C2, uncommon_trap_blob creates a frame, so all the various 199 // deoptimization functions expect to find the frame of the method 200 // being deopted one frame down on the stack. We create a dummy 201 // frame to mirror this. 202 FakeStubFrame *stubframe = FakeStubFrame::build(CHECK_0); 203 thread->push_zero_frame(stubframe); 204 205 // Initiate the trap 206 thread->set_last_Java_frame(); 207 Deoptimization::UnrollBlock *urb = 208 Deoptimization::uncommon_trap(thread, trap_request); 209 thread->reset_last_Java_frame(); 210 211 // Pop our dummy frame and the frame being deoptimized 212 thread->pop_zero_frame(); 213 thread->pop_zero_frame(); 214 215 // Push skeleton frames 216 int number_of_frames = urb->number_of_frames(); 217 for (int i = 0; i < number_of_frames; i++) { 218 intptr_t size = urb->frame_sizes()[i]; 219 InterpreterFrame *frame = InterpreterFrame::build(size, CHECK_0); 220 thread->push_zero_frame(frame); 221 } 222 223 // Push another dummy frame 224 stubframe = FakeStubFrame::build(CHECK_0); 225 thread->push_zero_frame(stubframe); 226 227 // Fill in the skeleton frames 228 thread->set_last_Java_frame(); 229 Deoptimization::unpack_frames(thread, Deoptimization::Unpack_uncommon_trap); 230 thread->reset_last_Java_frame(); 231 232 // Pop our dummy frame 233 thread->pop_zero_frame(); 234 235 // Fall back into the interpreter 236 return number_of_frames; 237 } 238 239 FakeStubFrame* FakeStubFrame::build(TRAPS) { 240 ZeroStack *stack = ((JavaThread *) THREAD)->zero_stack(); 241 stack->overflow_check(header_words, CHECK_NULL); 242 243 stack->push(0); // next_frame, filled in later 244 intptr_t *fp = stack->sp(); 245 assert(fp - stack->sp() == next_frame_off, "should be"); 246 247 stack->push(FAKE_STUB_FRAME); 248 assert(fp - stack->sp() == frame_type_off, "should be"); 249 250 return (FakeStubFrame *) fp; 251 }