src/share/vm/shark/sharkRuntime.cpp

Wed, 27 Apr 2016 01:25:04 +0800

author
aoqi
date
Wed, 27 Apr 2016 01:25:04 +0800
changeset 0
f90c822e73f8
child 6876
710a3c8b516e
permissions
-rw-r--r--

Initial load
http://hg.openjdk.java.net/jdk8u/jdk8u/hotspot/
changeset: 6782:28b50d07f6f8
tag: jdk8u25-b17

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

mercurial