Mercurial > hg > truffle
comparison src/share/vm/shark/sharkRuntime.cpp @ 1692:d2ede61b7a12
6976186: integrate Shark HotSpot changes
Summary: Shark is a JIT compiler for Zero that uses the LLVM compiler infrastructure.
Reviewed-by: kvn, twisti
Contributed-by: Gary Benson <gbenson@redhat.com>
author | twisti |
---|---|
date | Wed, 11 Aug 2010 05:51:21 -0700 |
parents | |
children | f95d63e2154a |
comparison
equal
deleted
inserted
replaced
1691:4a665be40fd3 | 1692:d2ede61b7a12 |
---|---|
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 } |