annotate src/share/vm/runtime/sharedRuntime.cpp @ 452:00b023ae2d78

6722113: CMS: Incorrect overflow handling during precleaning of Reference lists Summary: When we encounter marking stack overflow during precleaning of Reference lists, we were using the overflow list mechanism, which can cause problems on account of mutating the mark word of the header because of conflicts with mutator accesses and updates of that field. Instead we should use the usual mechanism for overflow handling in concurrent phases, namely dirtying of the card on which the overflowed object lies. Since precleaning effectively does a form of discovered list processing, albeit with discovery enabled, we needed to adjust some code to be correct in the face of interleaved processing and discovery. Reviewed-by: apetrusenko, jcoomes
author ysr
date Thu, 20 Nov 2008 12:27:41 -0800
parents 1ee8caae33af
children dc16daa0329d
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
196
d1605aabd0a1 6719955: Update copyright year
xdono
parents: 128
diff changeset
2 * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
a61af66fc99e Initial load
duke
parents:
diff changeset
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
a61af66fc99e Initial load
duke
parents:
diff changeset
20 * CA 95054 USA or visit www.sun.com if you need additional information or
a61af66fc99e Initial load
duke
parents:
diff changeset
21 * have any questions.
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
a61af66fc99e Initial load
duke
parents:
diff changeset
25 #include "incls/_precompiled.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
26 #include "incls/_sharedRuntime.cpp.incl"
a61af66fc99e Initial load
duke
parents:
diff changeset
27 #include <math.h>
a61af66fc99e Initial load
duke
parents:
diff changeset
28
a61af66fc99e Initial load
duke
parents:
diff changeset
29 HS_DTRACE_PROBE_DECL4(hotspot, object__alloc, Thread*, char*, int, size_t);
a61af66fc99e Initial load
duke
parents:
diff changeset
30 HS_DTRACE_PROBE_DECL7(hotspot, method__entry, int,
a61af66fc99e Initial load
duke
parents:
diff changeset
31 char*, int, char*, int, char*, int);
a61af66fc99e Initial load
duke
parents:
diff changeset
32 HS_DTRACE_PROBE_DECL7(hotspot, method__return, int,
a61af66fc99e Initial load
duke
parents:
diff changeset
33 char*, int, char*, int, char*, int);
a61af66fc99e Initial load
duke
parents:
diff changeset
34
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // Implementation of SharedRuntime
a61af66fc99e Initial load
duke
parents:
diff changeset
36
a61af66fc99e Initial load
duke
parents:
diff changeset
37 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // For statistics
a61af66fc99e Initial load
duke
parents:
diff changeset
39 int SharedRuntime::_ic_miss_ctr = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
40 int SharedRuntime::_wrong_method_ctr = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
41 int SharedRuntime::_resolve_static_ctr = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
42 int SharedRuntime::_resolve_virtual_ctr = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
43 int SharedRuntime::_resolve_opt_virtual_ctr = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
44 int SharedRuntime::_implicit_null_throws = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
45 int SharedRuntime::_implicit_div0_throws = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
46 int SharedRuntime::_throw_null_ctr = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
47
a61af66fc99e Initial load
duke
parents:
diff changeset
48 int SharedRuntime::_nof_normal_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
49 int SharedRuntime::_nof_optimized_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
50 int SharedRuntime::_nof_inlined_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
51 int SharedRuntime::_nof_megamorphic_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
52 int SharedRuntime::_nof_static_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
53 int SharedRuntime::_nof_inlined_static_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
54 int SharedRuntime::_nof_interface_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
55 int SharedRuntime::_nof_optimized_interface_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
56 int SharedRuntime::_nof_inlined_interface_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
57 int SharedRuntime::_nof_megamorphic_interface_calls = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
58 int SharedRuntime::_nof_removable_exceptions = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
59
a61af66fc99e Initial load
duke
parents:
diff changeset
60 int SharedRuntime::_new_instance_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
61 int SharedRuntime::_new_array_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
62 int SharedRuntime::_multi1_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
63 int SharedRuntime::_multi2_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
64 int SharedRuntime::_multi3_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 int SharedRuntime::_multi4_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 int SharedRuntime::_multi5_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 int SharedRuntime::_mon_enter_stub_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 int SharedRuntime::_mon_exit_stub_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 int SharedRuntime::_mon_enter_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 int SharedRuntime::_mon_exit_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
71 int SharedRuntime::_partial_subtype_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
72 int SharedRuntime::_jbyte_array_copy_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
73 int SharedRuntime::_jshort_array_copy_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
74 int SharedRuntime::_jint_array_copy_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
75 int SharedRuntime::_jlong_array_copy_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
76 int SharedRuntime::_oop_array_copy_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
77 int SharedRuntime::_checkcast_array_copy_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
78 int SharedRuntime::_unsafe_array_copy_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
79 int SharedRuntime::_generic_array_copy_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
80 int SharedRuntime::_slow_array_copy_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
81 int SharedRuntime::_find_handler_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
82 int SharedRuntime::_rethrow_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 int SharedRuntime::_ICmiss_index = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
85 int SharedRuntime::_ICmiss_count[SharedRuntime::maxICmiss_count];
a61af66fc99e Initial load
duke
parents:
diff changeset
86 address SharedRuntime::_ICmiss_at[SharedRuntime::maxICmiss_count];
a61af66fc99e Initial load
duke
parents:
diff changeset
87
a61af66fc99e Initial load
duke
parents:
diff changeset
88 void SharedRuntime::trace_ic_miss(address at) {
a61af66fc99e Initial load
duke
parents:
diff changeset
89 for (int i = 0; i < _ICmiss_index; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
90 if (_ICmiss_at[i] == at) {
a61af66fc99e Initial load
duke
parents:
diff changeset
91 _ICmiss_count[i]++;
a61af66fc99e Initial load
duke
parents:
diff changeset
92 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
93 }
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95 int index = _ICmiss_index++;
a61af66fc99e Initial load
duke
parents:
diff changeset
96 if (_ICmiss_index >= maxICmiss_count) _ICmiss_index = maxICmiss_count - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
97 _ICmiss_at[index] = at;
a61af66fc99e Initial load
duke
parents:
diff changeset
98 _ICmiss_count[index] = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 void SharedRuntime::print_ic_miss_histogram() {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 if (ICMissHistogram) {
a61af66fc99e Initial load
duke
parents:
diff changeset
103 tty->print_cr ("IC Miss Histogram:");
a61af66fc99e Initial load
duke
parents:
diff changeset
104 int tot_misses = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
105 for (int i = 0; i < _ICmiss_index; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
106 tty->print_cr(" at: " INTPTR_FORMAT " nof: %d", _ICmiss_at[i], _ICmiss_count[i]);
a61af66fc99e Initial load
duke
parents:
diff changeset
107 tot_misses += _ICmiss_count[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
108 }
a61af66fc99e Initial load
duke
parents:
diff changeset
109 tty->print_cr ("Total IC misses: %7d", tot_misses);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 }
a61af66fc99e Initial load
duke
parents:
diff changeset
111 }
a61af66fc99e Initial load
duke
parents:
diff changeset
112 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
113
342
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
114 #ifndef SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
115
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
116 // G1 write-barrier pre: executed before a pointer store.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
117 JRT_LEAF(void, SharedRuntime::g1_wb_pre(oopDesc* orig, JavaThread *thread))
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
118 if (orig == NULL) {
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
119 assert(false, "should be optimized out");
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
120 return;
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
121 }
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
122 // store the original value that was in the field reference
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
123 thread->satb_mark_queue().enqueue(orig);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
124 JRT_END
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
125
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
126 // G1 write-barrier post: executed after a pointer store.
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
127 JRT_LEAF(void, SharedRuntime::g1_wb_post(void* card_addr, JavaThread* thread))
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
128 thread->dirty_card_queue().enqueue(card_addr);
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
129 JRT_END
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
130
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
131 #endif // !SERIALGC
37f87013dfd8 6711316: Open source the Garbage-First garbage collector
ysr
parents: 128
diff changeset
132
0
a61af66fc99e Initial load
duke
parents:
diff changeset
133
a61af66fc99e Initial load
duke
parents:
diff changeset
134 JRT_LEAF(jlong, SharedRuntime::lmul(jlong y, jlong x))
a61af66fc99e Initial load
duke
parents:
diff changeset
135 return x * y;
a61af66fc99e Initial load
duke
parents:
diff changeset
136 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
137
a61af66fc99e Initial load
duke
parents:
diff changeset
138
a61af66fc99e Initial load
duke
parents:
diff changeset
139 JRT_LEAF(jlong, SharedRuntime::ldiv(jlong y, jlong x))
a61af66fc99e Initial load
duke
parents:
diff changeset
140 if (x == min_jlong && y == CONST64(-1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
141 return x;
a61af66fc99e Initial load
duke
parents:
diff changeset
142 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
143 return x / y;
a61af66fc99e Initial load
duke
parents:
diff changeset
144 }
a61af66fc99e Initial load
duke
parents:
diff changeset
145 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147
a61af66fc99e Initial load
duke
parents:
diff changeset
148 JRT_LEAF(jlong, SharedRuntime::lrem(jlong y, jlong x))
a61af66fc99e Initial load
duke
parents:
diff changeset
149 if (x == min_jlong && y == CONST64(-1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
152 return x % y;
a61af66fc99e Initial load
duke
parents:
diff changeset
153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
154 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
155
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 const juint float_sign_mask = 0x7FFFFFFF;
a61af66fc99e Initial load
duke
parents:
diff changeset
158 const juint float_infinity = 0x7F800000;
a61af66fc99e Initial load
duke
parents:
diff changeset
159 const julong double_sign_mask = CONST64(0x7FFFFFFFFFFFFFFF);
a61af66fc99e Initial load
duke
parents:
diff changeset
160 const julong double_infinity = CONST64(0x7FF0000000000000);
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 JRT_LEAF(jfloat, SharedRuntime::frem(jfloat x, jfloat y))
a61af66fc99e Initial load
duke
parents:
diff changeset
163 #ifdef _WIN64
a61af66fc99e Initial load
duke
parents:
diff changeset
164 // 64-bit Windows on amd64 returns the wrong values for
a61af66fc99e Initial load
duke
parents:
diff changeset
165 // infinity operands.
a61af66fc99e Initial load
duke
parents:
diff changeset
166 union { jfloat f; juint i; } xbits, ybits;
a61af66fc99e Initial load
duke
parents:
diff changeset
167 xbits.f = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
168 ybits.f = y;
a61af66fc99e Initial load
duke
parents:
diff changeset
169 // x Mod Infinity == x unless x is infinity
a61af66fc99e Initial load
duke
parents:
diff changeset
170 if ( ((xbits.i & float_sign_mask) != float_infinity) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
171 ((ybits.i & float_sign_mask) == float_infinity) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
172 return x;
a61af66fc99e Initial load
duke
parents:
diff changeset
173 }
a61af66fc99e Initial load
duke
parents:
diff changeset
174 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
175 return ((jfloat)fmod((double)x,(double)y));
a61af66fc99e Initial load
duke
parents:
diff changeset
176 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
177
a61af66fc99e Initial load
duke
parents:
diff changeset
178
a61af66fc99e Initial load
duke
parents:
diff changeset
179 JRT_LEAF(jdouble, SharedRuntime::drem(jdouble x, jdouble y))
a61af66fc99e Initial load
duke
parents:
diff changeset
180 #ifdef _WIN64
a61af66fc99e Initial load
duke
parents:
diff changeset
181 union { jdouble d; julong l; } xbits, ybits;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 xbits.d = x;
a61af66fc99e Initial load
duke
parents:
diff changeset
183 ybits.d = y;
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // x Mod Infinity == x unless x is infinity
a61af66fc99e Initial load
duke
parents:
diff changeset
185 if ( ((xbits.l & double_sign_mask) != double_infinity) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
186 ((ybits.l & double_sign_mask) == double_infinity) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 return x;
a61af66fc99e Initial load
duke
parents:
diff changeset
188 }
a61af66fc99e Initial load
duke
parents:
diff changeset
189 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
190 return ((jdouble)fmod((double)x,(double)y));
a61af66fc99e Initial load
duke
parents:
diff changeset
191 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
192
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
194 JRT_LEAF(jint, SharedRuntime::f2i(jfloat x))
a61af66fc99e Initial load
duke
parents:
diff changeset
195 if (g_isnan(x)) {return 0;}
a61af66fc99e Initial load
duke
parents:
diff changeset
196 jlong lltmp = (jlong)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
197 jint ltmp = (jint)lltmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
198 if (ltmp == lltmp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
199 return ltmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
200 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
201 if (x < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
202 return min_jint;
a61af66fc99e Initial load
duke
parents:
diff changeset
203 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
204 return max_jint;
a61af66fc99e Initial load
duke
parents:
diff changeset
205 }
a61af66fc99e Initial load
duke
parents:
diff changeset
206 }
a61af66fc99e Initial load
duke
parents:
diff changeset
207 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209
a61af66fc99e Initial load
duke
parents:
diff changeset
210 JRT_LEAF(jlong, SharedRuntime::f2l(jfloat x))
a61af66fc99e Initial load
duke
parents:
diff changeset
211 if (g_isnan(x)) {return 0;}
a61af66fc99e Initial load
duke
parents:
diff changeset
212 jlong lltmp = (jlong)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
213 if (lltmp != min_jlong) {
a61af66fc99e Initial load
duke
parents:
diff changeset
214 return lltmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
215 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
216 if (x < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
217 return min_jlong;
a61af66fc99e Initial load
duke
parents:
diff changeset
218 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
219 return max_jlong;
a61af66fc99e Initial load
duke
parents:
diff changeset
220 }
a61af66fc99e Initial load
duke
parents:
diff changeset
221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
222 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
223
a61af66fc99e Initial load
duke
parents:
diff changeset
224
a61af66fc99e Initial load
duke
parents:
diff changeset
225 JRT_LEAF(jint, SharedRuntime::d2i(jdouble x))
a61af66fc99e Initial load
duke
parents:
diff changeset
226 if (g_isnan(x)) {return 0;}
a61af66fc99e Initial load
duke
parents:
diff changeset
227 jlong lltmp = (jlong)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
228 jint ltmp = (jint)lltmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
229 if (ltmp == lltmp) {
a61af66fc99e Initial load
duke
parents:
diff changeset
230 return ltmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
231 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
232 if (x < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
233 return min_jint;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
235 return max_jint;
a61af66fc99e Initial load
duke
parents:
diff changeset
236 }
a61af66fc99e Initial load
duke
parents:
diff changeset
237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
238 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
239
a61af66fc99e Initial load
duke
parents:
diff changeset
240
a61af66fc99e Initial load
duke
parents:
diff changeset
241 JRT_LEAF(jlong, SharedRuntime::d2l(jdouble x))
a61af66fc99e Initial load
duke
parents:
diff changeset
242 if (g_isnan(x)) {return 0;}
a61af66fc99e Initial load
duke
parents:
diff changeset
243 jlong lltmp = (jlong)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 if (lltmp != min_jlong) {
a61af66fc99e Initial load
duke
parents:
diff changeset
245 return lltmp;
a61af66fc99e Initial load
duke
parents:
diff changeset
246 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
247 if (x < 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
248 return min_jlong;
a61af66fc99e Initial load
duke
parents:
diff changeset
249 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
250 return max_jlong;
a61af66fc99e Initial load
duke
parents:
diff changeset
251 }
a61af66fc99e Initial load
duke
parents:
diff changeset
252 }
a61af66fc99e Initial load
duke
parents:
diff changeset
253 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
254
a61af66fc99e Initial load
duke
parents:
diff changeset
255
a61af66fc99e Initial load
duke
parents:
diff changeset
256 JRT_LEAF(jfloat, SharedRuntime::d2f(jdouble x))
a61af66fc99e Initial load
duke
parents:
diff changeset
257 return (jfloat)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
258 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
259
a61af66fc99e Initial load
duke
parents:
diff changeset
260
a61af66fc99e Initial load
duke
parents:
diff changeset
261 JRT_LEAF(jfloat, SharedRuntime::l2f(jlong x))
a61af66fc99e Initial load
duke
parents:
diff changeset
262 return (jfloat)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
263 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
264
a61af66fc99e Initial load
duke
parents:
diff changeset
265
a61af66fc99e Initial load
duke
parents:
diff changeset
266 JRT_LEAF(jdouble, SharedRuntime::l2d(jlong x))
a61af66fc99e Initial load
duke
parents:
diff changeset
267 return (jdouble)x;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
269
a61af66fc99e Initial load
duke
parents:
diff changeset
270 // Exception handling accross interpreter/compiler boundaries
a61af66fc99e Initial load
duke
parents:
diff changeset
271 //
a61af66fc99e Initial load
duke
parents:
diff changeset
272 // exception_handler_for_return_address(...) returns the continuation address.
a61af66fc99e Initial load
duke
parents:
diff changeset
273 // The continuation address is the entry point of the exception handler of the
a61af66fc99e Initial load
duke
parents:
diff changeset
274 // previous frame depending on the return address.
a61af66fc99e Initial load
duke
parents:
diff changeset
275
a61af66fc99e Initial load
duke
parents:
diff changeset
276 address SharedRuntime::raw_exception_handler_for_return_address(address return_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
277 assert(frame::verify_return_pc(return_address), "must be a return pc");
a61af66fc99e Initial load
duke
parents:
diff changeset
278
a61af66fc99e Initial load
duke
parents:
diff changeset
279 // the fastest case first
a61af66fc99e Initial load
duke
parents:
diff changeset
280 CodeBlob* blob = CodeCache::find_blob(return_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
281 if (blob != NULL && blob->is_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
282 nmethod* code = (nmethod*)blob;
a61af66fc99e Initial load
duke
parents:
diff changeset
283 assert(code != NULL, "nmethod must be present");
a61af66fc99e Initial load
duke
parents:
diff changeset
284 // native nmethods don't have exception handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
285 assert(!code->is_native_method(), "no exception handler");
a61af66fc99e Initial load
duke
parents:
diff changeset
286 assert(code->header_begin() != code->exception_begin(), "no exception handler");
a61af66fc99e Initial load
duke
parents:
diff changeset
287 if (code->is_deopt_pc(return_address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
288 return SharedRuntime::deopt_blob()->unpack_with_exception();
a61af66fc99e Initial load
duke
parents:
diff changeset
289 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
290 return code->exception_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
291 }
a61af66fc99e Initial load
duke
parents:
diff changeset
292 }
a61af66fc99e Initial load
duke
parents:
diff changeset
293
a61af66fc99e Initial load
duke
parents:
diff changeset
294 // Entry code
a61af66fc99e Initial load
duke
parents:
diff changeset
295 if (StubRoutines::returns_to_call_stub(return_address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
296 return StubRoutines::catch_exception_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
297 }
a61af66fc99e Initial load
duke
parents:
diff changeset
298 // Interpreted code
a61af66fc99e Initial load
duke
parents:
diff changeset
299 if (Interpreter::contains(return_address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
300 return Interpreter::rethrow_exception_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
301 }
a61af66fc99e Initial load
duke
parents:
diff changeset
302
a61af66fc99e Initial load
duke
parents:
diff changeset
303 // Compiled code
a61af66fc99e Initial load
duke
parents:
diff changeset
304 if (CodeCache::contains(return_address)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
305 CodeBlob* blob = CodeCache::find_blob(return_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
306 if (blob->is_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
307 nmethod* code = (nmethod*)blob;
a61af66fc99e Initial load
duke
parents:
diff changeset
308 assert(code != NULL, "nmethod must be present");
a61af66fc99e Initial load
duke
parents:
diff changeset
309 assert(code->header_begin() != code->exception_begin(), "no exception handler");
a61af66fc99e Initial load
duke
parents:
diff changeset
310 return code->exception_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
312 if (blob->is_runtime_stub()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
313 ShouldNotReachHere(); // callers are responsible for skipping runtime stub frames
a61af66fc99e Initial load
duke
parents:
diff changeset
314 }
a61af66fc99e Initial load
duke
parents:
diff changeset
315 }
a61af66fc99e Initial load
duke
parents:
diff changeset
316 guarantee(!VtableStubs::contains(return_address), "NULL exceptions in vtables should have been handled already!");
a61af66fc99e Initial load
duke
parents:
diff changeset
317 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
318 { ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
319 tty->print_cr("No exception handler found for exception at " INTPTR_FORMAT " - potential problems:", return_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
320 tty->print_cr("a) exception happened in (new?) code stubs/buffers that is not handled here");
a61af66fc99e Initial load
duke
parents:
diff changeset
321 tty->print_cr("b) other problem");
a61af66fc99e Initial load
duke
parents:
diff changeset
322 }
a61af66fc99e Initial load
duke
parents:
diff changeset
323 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
324 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
325 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
326 }
a61af66fc99e Initial load
duke
parents:
diff changeset
327
a61af66fc99e Initial load
duke
parents:
diff changeset
328
a61af66fc99e Initial load
duke
parents:
diff changeset
329 JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(address return_address))
a61af66fc99e Initial load
duke
parents:
diff changeset
330 return raw_exception_handler_for_return_address(return_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 address SharedRuntime::get_poll_stub(address pc) {
a61af66fc99e Initial load
duke
parents:
diff changeset
334 address stub;
a61af66fc99e Initial load
duke
parents:
diff changeset
335 // Look up the code blob
a61af66fc99e Initial load
duke
parents:
diff changeset
336 CodeBlob *cb = CodeCache::find_blob(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338 // Should be an nmethod
a61af66fc99e Initial load
duke
parents:
diff changeset
339 assert( cb && cb->is_nmethod(), "safepoint polling: pc must refer to an nmethod" );
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // Look up the relocation information
a61af66fc99e Initial load
duke
parents:
diff changeset
342 assert( ((nmethod*)cb)->is_at_poll_or_poll_return(pc),
a61af66fc99e Initial load
duke
parents:
diff changeset
343 "safepoint polling: type must be poll" );
a61af66fc99e Initial load
duke
parents:
diff changeset
344
a61af66fc99e Initial load
duke
parents:
diff changeset
345 assert( ((NativeInstruction*)pc)->is_safepoint_poll(),
a61af66fc99e Initial load
duke
parents:
diff changeset
346 "Only polling locations are used for safepoint");
a61af66fc99e Initial load
duke
parents:
diff changeset
347
a61af66fc99e Initial load
duke
parents:
diff changeset
348 bool at_poll_return = ((nmethod*)cb)->is_at_poll_return(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
349 if (at_poll_return) {
a61af66fc99e Initial load
duke
parents:
diff changeset
350 assert(SharedRuntime::polling_page_return_handler_blob() != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
351 "polling page return stub not created yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
352 stub = SharedRuntime::polling_page_return_handler_blob()->instructions_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
353 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
354 assert(SharedRuntime::polling_page_safepoint_handler_blob() != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
355 "polling page safepoint stub not created yet");
a61af66fc99e Initial load
duke
parents:
diff changeset
356 stub = SharedRuntime::polling_page_safepoint_handler_blob()->instructions_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
357 }
a61af66fc99e Initial load
duke
parents:
diff changeset
358 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
359 if( TraceSafepoint ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
360 char buf[256];
a61af66fc99e Initial load
duke
parents:
diff changeset
361 jio_snprintf(buf, sizeof(buf),
a61af66fc99e Initial load
duke
parents:
diff changeset
362 "... found polling page %s exception at pc = "
a61af66fc99e Initial load
duke
parents:
diff changeset
363 INTPTR_FORMAT ", stub =" INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
364 at_poll_return ? "return" : "loop",
a61af66fc99e Initial load
duke
parents:
diff changeset
365 (intptr_t)pc, (intptr_t)stub);
a61af66fc99e Initial load
duke
parents:
diff changeset
366 tty->print_raw_cr(buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
368 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
369 return stub;
a61af66fc99e Initial load
duke
parents:
diff changeset
370 }
a61af66fc99e Initial load
duke
parents:
diff changeset
371
a61af66fc99e Initial load
duke
parents:
diff changeset
372
a61af66fc99e Initial load
duke
parents:
diff changeset
373 oop SharedRuntime::retrieve_receiver( symbolHandle sig, frame caller ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
374 assert(caller.is_interpreted_frame(), "");
a61af66fc99e Initial load
duke
parents:
diff changeset
375 int args_size = ArgumentSizeComputer(sig).size() + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
376 assert(args_size <= caller.interpreter_frame_expression_stack_size(), "receiver must be on interpreter stack");
a61af66fc99e Initial load
duke
parents:
diff changeset
377 oop result = (oop) *caller.interpreter_frame_tos_at(args_size - 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
378 assert(Universe::heap()->is_in(result) && result->is_oop(), "receiver must be an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
379 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
380 }
a61af66fc99e Initial load
duke
parents:
diff changeset
381
a61af66fc99e Initial load
duke
parents:
diff changeset
382
a61af66fc99e Initial load
duke
parents:
diff changeset
383 void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, Handle h_exception) {
a61af66fc99e Initial load
duke
parents:
diff changeset
384 if (JvmtiExport::can_post_exceptions()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
385 vframeStream vfst(thread, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
386 methodHandle method = methodHandle(thread, vfst.method());
a61af66fc99e Initial load
duke
parents:
diff changeset
387 address bcp = method()->bcp_from(vfst.bci());
a61af66fc99e Initial load
duke
parents:
diff changeset
388 JvmtiExport::post_exception_throw(thread, method(), bcp, h_exception());
a61af66fc99e Initial load
duke
parents:
diff changeset
389 }
a61af66fc99e Initial load
duke
parents:
diff changeset
390 Exceptions::_throw(thread, __FILE__, __LINE__, h_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
391 }
a61af66fc99e Initial load
duke
parents:
diff changeset
392
a61af66fc99e Initial load
duke
parents:
diff changeset
393 void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, symbolOop name, const char *message) {
a61af66fc99e Initial load
duke
parents:
diff changeset
394 Handle h_exception = Exceptions::new_exception(thread, name, message);
a61af66fc99e Initial load
duke
parents:
diff changeset
395 throw_and_post_jvmti_exception(thread, h_exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
396 }
a61af66fc99e Initial load
duke
parents:
diff changeset
397
a61af66fc99e Initial load
duke
parents:
diff changeset
398 // ret_pc points into caller; we are returning caller's exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
399 // for given exception
a61af66fc99e Initial load
duke
parents:
diff changeset
400 address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception,
a61af66fc99e Initial load
duke
parents:
diff changeset
401 bool force_unwind, bool top_frame_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 assert(nm != NULL, "must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
403 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
404
a61af66fc99e Initial load
duke
parents:
diff changeset
405 ScopeDesc* sd = nm->scope_desc_at(ret_pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
406 // determine handler bci, if any
a61af66fc99e Initial load
duke
parents:
diff changeset
407 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
408
a61af66fc99e Initial load
duke
parents:
diff changeset
409 int handler_bci = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
410 int scope_depth = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
411 if (!force_unwind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
412 int bci = sd->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
413 do {
a61af66fc99e Initial load
duke
parents:
diff changeset
414 bool skip_scope_increment = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
415 // exception handler lookup
a61af66fc99e Initial load
duke
parents:
diff changeset
416 KlassHandle ek (THREAD, exception->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
417 handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
418 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
419 // We threw an exception while trying to find the exception handler.
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // Transfer the new exception to the exception handle which will
a61af66fc99e Initial load
duke
parents:
diff changeset
421 // be set into thread local storage, and do another lookup for an
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // exception handler for this exception, this time starting at the
a61af66fc99e Initial load
duke
parents:
diff changeset
423 // BCI of the exception handler which caused the exception to be
a61af66fc99e Initial load
duke
parents:
diff changeset
424 // thrown (bugs 4307310 and 4546590). Set "exception" reference
a61af66fc99e Initial load
duke
parents:
diff changeset
425 // argument to ensure that the correct exception is thrown (4870175).
a61af66fc99e Initial load
duke
parents:
diff changeset
426 exception = Handle(THREAD, PENDING_EXCEPTION);
a61af66fc99e Initial load
duke
parents:
diff changeset
427 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
428 if (handler_bci >= 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
429 bci = handler_bci;
a61af66fc99e Initial load
duke
parents:
diff changeset
430 handler_bci = -1;
a61af66fc99e Initial load
duke
parents:
diff changeset
431 skip_scope_increment = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
432 }
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434 if (!top_frame_only && handler_bci < 0 && !skip_scope_increment) {
a61af66fc99e Initial load
duke
parents:
diff changeset
435 sd = sd->sender();
a61af66fc99e Initial load
duke
parents:
diff changeset
436 if (sd != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 bci = sd->bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
438 }
a61af66fc99e Initial load
duke
parents:
diff changeset
439 ++scope_depth;
a61af66fc99e Initial load
duke
parents:
diff changeset
440 }
a61af66fc99e Initial load
duke
parents:
diff changeset
441 } while (!top_frame_only && handler_bci < 0 && sd != NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
443
a61af66fc99e Initial load
duke
parents:
diff changeset
444 // found handling method => lookup exception handler
a61af66fc99e Initial load
duke
parents:
diff changeset
445 int catch_pco = ret_pc - nm->instructions_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
446
a61af66fc99e Initial load
duke
parents:
diff changeset
447 ExceptionHandlerTable table(nm);
a61af66fc99e Initial load
duke
parents:
diff changeset
448 HandlerTableEntry *t = table.entry_for(catch_pco, handler_bci, scope_depth);
a61af66fc99e Initial load
duke
parents:
diff changeset
449 if (t == NULL && (nm->is_compiled_by_c1() || handler_bci != -1)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
450 // Allow abbreviated catch tables. The idea is to allow a method
a61af66fc99e Initial load
duke
parents:
diff changeset
451 // to materialize its exceptions without committing to the exact
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // routing of exceptions. In particular this is needed for adding
a61af66fc99e Initial load
duke
parents:
diff changeset
453 // a synthethic handler to unlock monitors when inlining
a61af66fc99e Initial load
duke
parents:
diff changeset
454 // synchonized methods since the unlock path isn't represented in
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // the bytecodes.
a61af66fc99e Initial load
duke
parents:
diff changeset
456 t = table.entry_for(catch_pco, -1, 0);
a61af66fc99e Initial load
duke
parents:
diff changeset
457 }
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459 #ifdef COMPILER1
a61af66fc99e Initial load
duke
parents:
diff changeset
460 if (nm->is_compiled_by_c1() && t == NULL && handler_bci == -1) {
a61af66fc99e Initial load
duke
parents:
diff changeset
461 // Exception is not handled by this frame so unwind. Note that
a61af66fc99e Initial load
duke
parents:
diff changeset
462 // this is not the same as how C2 does this. C2 emits a table
a61af66fc99e Initial load
duke
parents:
diff changeset
463 // entry that dispatches to the unwind code in the nmethod.
a61af66fc99e Initial load
duke
parents:
diff changeset
464 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
465 }
a61af66fc99e Initial load
duke
parents:
diff changeset
466 #endif /* COMPILER1 */
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468
a61af66fc99e Initial load
duke
parents:
diff changeset
469 if (t == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
470 tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
471 tty->print_cr(" Exception:");
a61af66fc99e Initial load
duke
parents:
diff changeset
472 exception->print();
a61af66fc99e Initial load
duke
parents:
diff changeset
473 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
474 tty->print_cr(" Compiled exception table :");
a61af66fc99e Initial load
duke
parents:
diff changeset
475 table.print();
a61af66fc99e Initial load
duke
parents:
diff changeset
476 nm->print_code();
a61af66fc99e Initial load
duke
parents:
diff changeset
477 guarantee(false, "missing exception handler");
a61af66fc99e Initial load
duke
parents:
diff changeset
478 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480
a61af66fc99e Initial load
duke
parents:
diff changeset
481 return nm->instructions_begin() + t->pco();
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 JRT_ENTRY(void, SharedRuntime::throw_AbstractMethodError(JavaThread* thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // These errors occur only at call sites
a61af66fc99e Initial load
duke
parents:
diff changeset
486 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_AbstractMethodError());
a61af66fc99e Initial load
duke
parents:
diff changeset
487 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
488
16
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
489 JRT_ENTRY(void, SharedRuntime::throw_IncompatibleClassChangeError(JavaThread* thread))
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
490 // These errors occur only at call sites
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
491 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IncompatibleClassChangeError(), "vtable stub");
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
492 JRT_END
f8236e79048a 6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents: 0
diff changeset
493
0
a61af66fc99e Initial load
duke
parents:
diff changeset
494 JRT_ENTRY(void, SharedRuntime::throw_ArithmeticException(JavaThread* thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
495 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArithmeticException(), "/ by zero");
a61af66fc99e Initial load
duke
parents:
diff changeset
496 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
497
a61af66fc99e Initial load
duke
parents:
diff changeset
498 JRT_ENTRY(void, SharedRuntime::throw_NullPointerException(JavaThread* thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
499 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException());
a61af66fc99e Initial load
duke
parents:
diff changeset
500 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
501
a61af66fc99e Initial load
duke
parents:
diff changeset
502 JRT_ENTRY(void, SharedRuntime::throw_NullPointerException_at_call(JavaThread* thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
503 // This entry point is effectively only used for NullPointerExceptions which occur at inline
a61af66fc99e Initial load
duke
parents:
diff changeset
504 // cache sites (when the callee activation is not yet set up) so we are at a call site
a61af66fc99e Initial load
duke
parents:
diff changeset
505 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException());
a61af66fc99e Initial load
duke
parents:
diff changeset
506 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
507
a61af66fc99e Initial load
duke
parents:
diff changeset
508 JRT_ENTRY(void, SharedRuntime::throw_StackOverflowError(JavaThread* thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
509 // We avoid using the normal exception construction in this case because
a61af66fc99e Initial load
duke
parents:
diff changeset
510 // it performs an upcall to Java, and we're already out of stack space.
a61af66fc99e Initial load
duke
parents:
diff changeset
511 klassOop k = SystemDictionary::StackOverflowError_klass();
a61af66fc99e Initial load
duke
parents:
diff changeset
512 oop exception_oop = instanceKlass::cast(k)->allocate_instance(CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
513 Handle exception (thread, exception_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
514 if (StackTraceInThrowable) {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 java_lang_Throwable::fill_in_stack_trace(exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
517 throw_and_post_jvmti_exception(thread, exception);
a61af66fc99e Initial load
duke
parents:
diff changeset
518 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
519
a61af66fc99e Initial load
duke
parents:
diff changeset
520 address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
521 address pc,
a61af66fc99e Initial load
duke
parents:
diff changeset
522 SharedRuntime::ImplicitExceptionKind exception_kind)
a61af66fc99e Initial load
duke
parents:
diff changeset
523 {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 address target_pc = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
525
a61af66fc99e Initial load
duke
parents:
diff changeset
526 if (Interpreter::contains(pc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
527 #ifdef CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
528 // C++ interpreter doesn't throw implicit exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
529 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
530 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
531 switch (exception_kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
532 case IMPLICIT_NULL: return Interpreter::throw_NullPointerException_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
533 case IMPLICIT_DIVIDE_BY_ZERO: return Interpreter::throw_ArithmeticException_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
534 case STACK_OVERFLOW: return Interpreter::throw_StackOverflowError_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
535 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
536 }
a61af66fc99e Initial load
duke
parents:
diff changeset
537 #endif // !CC_INTERP
a61af66fc99e Initial load
duke
parents:
diff changeset
538 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 switch (exception_kind) {
a61af66fc99e Initial load
duke
parents:
diff changeset
540 case STACK_OVERFLOW: {
a61af66fc99e Initial load
duke
parents:
diff changeset
541 // Stack overflow only occurs upon frame setup; the callee is
a61af66fc99e Initial load
duke
parents:
diff changeset
542 // going to be unwound. Dispatch to a shared runtime stub
a61af66fc99e Initial load
duke
parents:
diff changeset
543 // which will cause the StackOverflowError to be fabricated
a61af66fc99e Initial load
duke
parents:
diff changeset
544 // and processed.
a61af66fc99e Initial load
duke
parents:
diff changeset
545 // For stack overflow in deoptimization blob, cleanup thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
546 if (thread->deopt_mark() != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
547 Deoptimization::cleanup_deopt_info(thread, NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
548 }
a61af66fc99e Initial load
duke
parents:
diff changeset
549 return StubRoutines::throw_StackOverflowError_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
550 }
a61af66fc99e Initial load
duke
parents:
diff changeset
551
a61af66fc99e Initial load
duke
parents:
diff changeset
552 case IMPLICIT_NULL: {
a61af66fc99e Initial load
duke
parents:
diff changeset
553 if (VtableStubs::contains(pc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
554 // We haven't yet entered the callee frame. Fabricate an
a61af66fc99e Initial load
duke
parents:
diff changeset
555 // exception and begin dispatching it in the caller. Since
a61af66fc99e Initial load
duke
parents:
diff changeset
556 // the caller was at a call site, it's safe to destroy all
a61af66fc99e Initial load
duke
parents:
diff changeset
557 // caller-saved registers, as these entry points do.
a61af66fc99e Initial load
duke
parents:
diff changeset
558 VtableStub* vt_stub = VtableStubs::stub_containing(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
559 guarantee(vt_stub != NULL, "unable to find SEGVing vtable stub");
a61af66fc99e Initial load
duke
parents:
diff changeset
560 if (vt_stub->is_abstract_method_error(pc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
561 assert(!vt_stub->is_vtable_stub(), "should never see AbstractMethodErrors from vtable-type VtableStubs");
a61af66fc99e Initial load
duke
parents:
diff changeset
562 return StubRoutines::throw_AbstractMethodError_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
563 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
564 return StubRoutines::throw_NullPointerException_at_call_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
565 }
a61af66fc99e Initial load
duke
parents:
diff changeset
566 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
567 CodeBlob* cb = CodeCache::find_blob(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
568 guarantee(cb != NULL, "exception happened outside interpreter, nmethods and vtable stubs (1)");
a61af66fc99e Initial load
duke
parents:
diff changeset
569
a61af66fc99e Initial load
duke
parents:
diff changeset
570 // Exception happened in CodeCache. Must be either:
a61af66fc99e Initial load
duke
parents:
diff changeset
571 // 1. Inline-cache check in C2I handler blob,
a61af66fc99e Initial load
duke
parents:
diff changeset
572 // 2. Inline-cache check in nmethod, or
a61af66fc99e Initial load
duke
parents:
diff changeset
573 // 3. Implict null exception in nmethod
a61af66fc99e Initial load
duke
parents:
diff changeset
574
a61af66fc99e Initial load
duke
parents:
diff changeset
575 if (!cb->is_nmethod()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
576 guarantee(cb->is_adapter_blob(),
a61af66fc99e Initial load
duke
parents:
diff changeset
577 "exception happened outside interpreter, nmethods and vtable stubs (2)");
a61af66fc99e Initial load
duke
parents:
diff changeset
578 // There is no handler here, so we will simply unwind.
a61af66fc99e Initial load
duke
parents:
diff changeset
579 return StubRoutines::throw_NullPointerException_at_call_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
580 }
a61af66fc99e Initial load
duke
parents:
diff changeset
581
a61af66fc99e Initial load
duke
parents:
diff changeset
582 // Otherwise, it's an nmethod. Consult its exception handlers.
a61af66fc99e Initial load
duke
parents:
diff changeset
583 nmethod* nm = (nmethod*)cb;
a61af66fc99e Initial load
duke
parents:
diff changeset
584 if (nm->inlinecache_check_contains(pc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
585 // exception happened inside inline-cache check code
a61af66fc99e Initial load
duke
parents:
diff changeset
586 // => the nmethod is not yet active (i.e., the frame
a61af66fc99e Initial load
duke
parents:
diff changeset
587 // is not set up yet) => use return address pushed by
a61af66fc99e Initial load
duke
parents:
diff changeset
588 // caller => don't push another return address
a61af66fc99e Initial load
duke
parents:
diff changeset
589 return StubRoutines::throw_NullPointerException_at_call_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
590 }
a61af66fc99e Initial load
duke
parents:
diff changeset
591
a61af66fc99e Initial load
duke
parents:
diff changeset
592 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
593 _implicit_null_throws++;
a61af66fc99e Initial load
duke
parents:
diff changeset
594 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
595 target_pc = nm->continuation_for_implicit_exception(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 guarantee(target_pc != 0, "must have a continuation point");
a61af66fc99e Initial load
duke
parents:
diff changeset
597 }
a61af66fc99e Initial load
duke
parents:
diff changeset
598
a61af66fc99e Initial load
duke
parents:
diff changeset
599 break; // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
601
a61af66fc99e Initial load
duke
parents:
diff changeset
602
a61af66fc99e Initial load
duke
parents:
diff changeset
603 case IMPLICIT_DIVIDE_BY_ZERO: {
a61af66fc99e Initial load
duke
parents:
diff changeset
604 nmethod* nm = CodeCache::find_nmethod(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
605 guarantee(nm != NULL, "must have containing nmethod for implicit division-by-zero exceptions");
a61af66fc99e Initial load
duke
parents:
diff changeset
606 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
607 _implicit_div0_throws++;
a61af66fc99e Initial load
duke
parents:
diff changeset
608 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
609 target_pc = nm->continuation_for_implicit_exception(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
610 guarantee(target_pc != 0, "must have a continuation point");
a61af66fc99e Initial load
duke
parents:
diff changeset
611 break; // fall through
a61af66fc99e Initial load
duke
parents:
diff changeset
612 }
a61af66fc99e Initial load
duke
parents:
diff changeset
613
a61af66fc99e Initial load
duke
parents:
diff changeset
614 default: ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
615 }
a61af66fc99e Initial load
duke
parents:
diff changeset
616
a61af66fc99e Initial load
duke
parents:
diff changeset
617 guarantee(target_pc != NULL, "must have computed destination PC for implicit exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
618 assert(exception_kind == IMPLICIT_NULL || exception_kind == IMPLICIT_DIVIDE_BY_ZERO, "wrong implicit exception kind");
a61af66fc99e Initial load
duke
parents:
diff changeset
619
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // for AbortVMOnException flag
a61af66fc99e Initial load
duke
parents:
diff changeset
621 NOT_PRODUCT(Exceptions::debug_check_abort("java.lang.NullPointerException"));
a61af66fc99e Initial load
duke
parents:
diff changeset
622 if (exception_kind == IMPLICIT_NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
623 Events::log("Implicit null exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
624 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
625 Events::log("Implicit division by zero exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
626 }
a61af66fc99e Initial load
duke
parents:
diff changeset
627 return target_pc;
a61af66fc99e Initial load
duke
parents:
diff changeset
628 }
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
631 return NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
632 }
a61af66fc99e Initial load
duke
parents:
diff changeset
633
a61af66fc99e Initial load
duke
parents:
diff changeset
634
a61af66fc99e Initial load
duke
parents:
diff changeset
635 JNI_ENTRY(void, throw_unsatisfied_link_error(JNIEnv* env, ...))
a61af66fc99e Initial load
duke
parents:
diff changeset
636 {
a61af66fc99e Initial load
duke
parents:
diff changeset
637 THROW(vmSymbols::java_lang_UnsatisfiedLinkError());
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639 JNI_END
a61af66fc99e Initial load
duke
parents:
diff changeset
640
a61af66fc99e Initial load
duke
parents:
diff changeset
641
a61af66fc99e Initial load
duke
parents:
diff changeset
642 address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() {
a61af66fc99e Initial load
duke
parents:
diff changeset
643 return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error);
a61af66fc99e Initial load
duke
parents:
diff changeset
644 }
a61af66fc99e Initial load
duke
parents:
diff changeset
645
a61af66fc99e Initial load
duke
parents:
diff changeset
646
a61af66fc99e Initial load
duke
parents:
diff changeset
647 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
648 JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2))
a61af66fc99e Initial load
duke
parents:
diff changeset
649 const frame f = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
650 assert(f.is_interpreted_frame(), "must be an interpreted frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
651 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
652 methodHandle mh(THREAD, f.interpreter_frame_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
653 BytecodeTracer::trace(mh, f.interpreter_frame_bcp(), tos, tos2);
a61af66fc99e Initial load
duke
parents:
diff changeset
654 #endif // !PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
655 return preserve_this_value;
a61af66fc99e Initial load
duke
parents:
diff changeset
656 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
657 #endif // !PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
658
a61af66fc99e Initial load
duke
parents:
diff changeset
659
a61af66fc99e Initial load
duke
parents:
diff changeset
660 JRT_ENTRY(void, SharedRuntime::yield_all(JavaThread* thread, int attempts))
a61af66fc99e Initial load
duke
parents:
diff changeset
661 os::yield_all(attempts);
a61af66fc99e Initial load
duke
parents:
diff changeset
662 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
663
a61af66fc99e Initial load
duke
parents:
diff changeset
664
a61af66fc99e Initial load
duke
parents:
diff changeset
665 // ---------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
666 // Non-product code
a61af66fc99e Initial load
duke
parents:
diff changeset
667 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
668
a61af66fc99e Initial load
duke
parents:
diff changeset
669 void SharedRuntime::verify_caller_frame(frame caller_frame, methodHandle callee_method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
670 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
671 assert (caller_frame.is_interpreted_frame(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
672 assert (callee_method->has_compiled_code(), "callee must be compiled");
a61af66fc99e Initial load
duke
parents:
diff changeset
673 methodHandle caller_method (Thread::current(), caller_frame.interpreter_frame_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
674 jint bci = caller_frame.interpreter_frame_bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
675 methodHandle method = find_callee_method_inside_interpreter(caller_frame, caller_method, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
676 assert (callee_method == method, "incorrect method");
a61af66fc99e Initial load
duke
parents:
diff changeset
677 }
a61af66fc99e Initial load
duke
parents:
diff changeset
678
a61af66fc99e Initial load
duke
parents:
diff changeset
679 methodHandle SharedRuntime::find_callee_method_inside_interpreter(frame caller_frame, methodHandle caller_method, int bci) {
a61af66fc99e Initial load
duke
parents:
diff changeset
680 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
681 Bytecode_invoke* bytecode = Bytecode_invoke_at(caller_method, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
682 methodHandle staticCallee = bytecode->static_target(CATCH); // Non-product code
a61af66fc99e Initial load
duke
parents:
diff changeset
683
a61af66fc99e Initial load
duke
parents:
diff changeset
684 bytecode = Bytecode_invoke_at(caller_method, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
685 int bytecode_index = bytecode->index();
a61af66fc99e Initial load
duke
parents:
diff changeset
686 Bytecodes::Code bc = bytecode->adjusted_invoke_code();
a61af66fc99e Initial load
duke
parents:
diff changeset
687
a61af66fc99e Initial load
duke
parents:
diff changeset
688 Handle receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
689 if (bc == Bytecodes::_invokeinterface ||
a61af66fc99e Initial load
duke
parents:
diff changeset
690 bc == Bytecodes::_invokevirtual ||
a61af66fc99e Initial load
duke
parents:
diff changeset
691 bc == Bytecodes::_invokespecial) {
a61af66fc99e Initial load
duke
parents:
diff changeset
692 symbolHandle signature (THREAD, staticCallee->signature());
a61af66fc99e Initial load
duke
parents:
diff changeset
693 receiver = Handle(THREAD, retrieve_receiver(signature, caller_frame));
a61af66fc99e Initial load
duke
parents:
diff changeset
694 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
695 receiver = Handle();
a61af66fc99e Initial load
duke
parents:
diff changeset
696 }
a61af66fc99e Initial load
duke
parents:
diff changeset
697 CallInfo result;
a61af66fc99e Initial load
duke
parents:
diff changeset
698 constantPoolHandle constants (THREAD, caller_method->constants());
a61af66fc99e Initial load
duke
parents:
diff changeset
699 LinkResolver::resolve_invoke(result, receiver, constants, bytecode_index, bc, CATCH); // Non-product code
a61af66fc99e Initial load
duke
parents:
diff changeset
700 methodHandle calleeMethod = result.selected_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
701 return calleeMethod;
a61af66fc99e Initial load
duke
parents:
diff changeset
702 }
a61af66fc99e Initial load
duke
parents:
diff changeset
703
a61af66fc99e Initial load
duke
parents:
diff changeset
704 #endif // PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706
a61af66fc99e Initial load
duke
parents:
diff changeset
707 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj))
a61af66fc99e Initial load
duke
parents:
diff changeset
708 assert(obj->is_oop(), "must be a valid oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
709 assert(obj->klass()->klass_part()->has_finalizer(), "shouldn't be here otherwise");
a61af66fc99e Initial load
duke
parents:
diff changeset
710 instanceKlass::register_finalizer(instanceOop(obj), CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
711 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
712
a61af66fc99e Initial load
duke
parents:
diff changeset
713
a61af66fc99e Initial load
duke
parents:
diff changeset
714 jlong SharedRuntime::get_java_tid(Thread* thread) {
a61af66fc99e Initial load
duke
parents:
diff changeset
715 if (thread != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
716 if (thread->is_Java_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
717 oop obj = ((JavaThread*)thread)->threadObj();
a61af66fc99e Initial load
duke
parents:
diff changeset
718 return (obj == NULL) ? 0 : java_lang_Thread::thread_id(obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
719 }
a61af66fc99e Initial load
duke
parents:
diff changeset
720 }
a61af66fc99e Initial load
duke
parents:
diff changeset
721 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
722 }
a61af66fc99e Initial load
duke
parents:
diff changeset
723
a61af66fc99e Initial load
duke
parents:
diff changeset
724 /**
a61af66fc99e Initial load
duke
parents:
diff changeset
725 * This function ought to be a void function, but cannot be because
a61af66fc99e Initial load
duke
parents:
diff changeset
726 * it gets turned into a tail-call on sparc, which runs into dtrace bug
a61af66fc99e Initial load
duke
parents:
diff changeset
727 * 6254741. Once that is fixed we can remove the dummy return value.
a61af66fc99e Initial load
duke
parents:
diff changeset
728 */
a61af66fc99e Initial load
duke
parents:
diff changeset
729 int SharedRuntime::dtrace_object_alloc(oopDesc* o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
730 return dtrace_object_alloc_base(Thread::current(), o);
a61af66fc99e Initial load
duke
parents:
diff changeset
731 }
a61af66fc99e Initial load
duke
parents:
diff changeset
732
a61af66fc99e Initial load
duke
parents:
diff changeset
733 int SharedRuntime::dtrace_object_alloc_base(Thread* thread, oopDesc* o) {
a61af66fc99e Initial load
duke
parents:
diff changeset
734 assert(DTraceAllocProbes, "wrong call");
a61af66fc99e Initial load
duke
parents:
diff changeset
735 Klass* klass = o->blueprint();
a61af66fc99e Initial load
duke
parents:
diff changeset
736 int size = o->size();
a61af66fc99e Initial load
duke
parents:
diff changeset
737 symbolOop name = klass->name();
a61af66fc99e Initial load
duke
parents:
diff changeset
738 HS_DTRACE_PROBE4(hotspot, object__alloc, get_java_tid(thread),
a61af66fc99e Initial load
duke
parents:
diff changeset
739 name->bytes(), name->utf8_length(), size * HeapWordSize);
a61af66fc99e Initial load
duke
parents:
diff changeset
740 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
741 }
a61af66fc99e Initial load
duke
parents:
diff changeset
742
a61af66fc99e Initial load
duke
parents:
diff changeset
743 JRT_LEAF(int, SharedRuntime::dtrace_method_entry(
a61af66fc99e Initial load
duke
parents:
diff changeset
744 JavaThread* thread, methodOopDesc* method))
a61af66fc99e Initial load
duke
parents:
diff changeset
745 assert(DTraceMethodProbes, "wrong call");
a61af66fc99e Initial load
duke
parents:
diff changeset
746 symbolOop kname = method->klass_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
747 symbolOop name = method->name();
a61af66fc99e Initial load
duke
parents:
diff changeset
748 symbolOop sig = method->signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
749 HS_DTRACE_PROBE7(hotspot, method__entry, get_java_tid(thread),
a61af66fc99e Initial load
duke
parents:
diff changeset
750 kname->bytes(), kname->utf8_length(),
a61af66fc99e Initial load
duke
parents:
diff changeset
751 name->bytes(), name->utf8_length(),
a61af66fc99e Initial load
duke
parents:
diff changeset
752 sig->bytes(), sig->utf8_length());
a61af66fc99e Initial load
duke
parents:
diff changeset
753 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
754 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
755
a61af66fc99e Initial load
duke
parents:
diff changeset
756 JRT_LEAF(int, SharedRuntime::dtrace_method_exit(
a61af66fc99e Initial load
duke
parents:
diff changeset
757 JavaThread* thread, methodOopDesc* method))
a61af66fc99e Initial load
duke
parents:
diff changeset
758 assert(DTraceMethodProbes, "wrong call");
a61af66fc99e Initial load
duke
parents:
diff changeset
759 symbolOop kname = method->klass_name();
a61af66fc99e Initial load
duke
parents:
diff changeset
760 symbolOop name = method->name();
a61af66fc99e Initial load
duke
parents:
diff changeset
761 symbolOop sig = method->signature();
a61af66fc99e Initial load
duke
parents:
diff changeset
762 HS_DTRACE_PROBE7(hotspot, method__return, get_java_tid(thread),
a61af66fc99e Initial load
duke
parents:
diff changeset
763 kname->bytes(), kname->utf8_length(),
a61af66fc99e Initial load
duke
parents:
diff changeset
764 name->bytes(), name->utf8_length(),
a61af66fc99e Initial load
duke
parents:
diff changeset
765 sig->bytes(), sig->utf8_length());
a61af66fc99e Initial load
duke
parents:
diff changeset
766 return 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
767 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
768
a61af66fc99e Initial load
duke
parents:
diff changeset
769
a61af66fc99e Initial load
duke
parents:
diff changeset
770 // Finds receiver, CallInfo (i.e. receiver method), and calling bytecode)
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // for a call current in progress, i.e., arguments has been pushed on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
772 // put callee has not been invoked yet. Used by: resolve virtual/static,
a61af66fc99e Initial load
duke
parents:
diff changeset
773 // vtable updates, etc. Caller frame must be compiled.
a61af66fc99e Initial load
duke
parents:
diff changeset
774 Handle SharedRuntime::find_callee_info(JavaThread* thread, Bytecodes::Code& bc, CallInfo& callinfo, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
775 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // last java frame on stack (which includes native call frames)
a61af66fc99e Initial load
duke
parents:
diff changeset
778 vframeStream vfst(thread, true); // Do not skip and javaCalls
a61af66fc99e Initial load
duke
parents:
diff changeset
779
a61af66fc99e Initial load
duke
parents:
diff changeset
780 return find_callee_info_helper(thread, vfst, bc, callinfo, CHECK_(Handle()));
a61af66fc99e Initial load
duke
parents:
diff changeset
781 }
a61af66fc99e Initial load
duke
parents:
diff changeset
782
a61af66fc99e Initial load
duke
parents:
diff changeset
783
a61af66fc99e Initial load
duke
parents:
diff changeset
784 // Finds receiver, CallInfo (i.e. receiver method), and calling bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
785 // for a call current in progress, i.e., arguments has been pushed on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
786 // but callee has not been invoked yet. Caller frame must be compiled.
a61af66fc99e Initial load
duke
parents:
diff changeset
787 Handle SharedRuntime::find_callee_info_helper(JavaThread* thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
788 vframeStream& vfst,
a61af66fc99e Initial load
duke
parents:
diff changeset
789 Bytecodes::Code& bc,
a61af66fc99e Initial load
duke
parents:
diff changeset
790 CallInfo& callinfo, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
791 Handle receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
792 Handle nullHandle; //create a handy null handle for exception returns
a61af66fc99e Initial load
duke
parents:
diff changeset
793
a61af66fc99e Initial load
duke
parents:
diff changeset
794 assert(!vfst.at_end(), "Java frame must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
795
a61af66fc99e Initial load
duke
parents:
diff changeset
796 // Find caller and bci from vframe
a61af66fc99e Initial load
duke
parents:
diff changeset
797 methodHandle caller (THREAD, vfst.method());
a61af66fc99e Initial load
duke
parents:
diff changeset
798 int bci = vfst.bci();
a61af66fc99e Initial load
duke
parents:
diff changeset
799
a61af66fc99e Initial load
duke
parents:
diff changeset
800 // Find bytecode
a61af66fc99e Initial load
duke
parents:
diff changeset
801 Bytecode_invoke* bytecode = Bytecode_invoke_at(caller, bci);
a61af66fc99e Initial load
duke
parents:
diff changeset
802 bc = bytecode->adjusted_invoke_code();
a61af66fc99e Initial load
duke
parents:
diff changeset
803 int bytecode_index = bytecode->index();
a61af66fc99e Initial load
duke
parents:
diff changeset
804
a61af66fc99e Initial load
duke
parents:
diff changeset
805 // Find receiver for non-static call
a61af66fc99e Initial load
duke
parents:
diff changeset
806 if (bc != Bytecodes::_invokestatic) {
a61af66fc99e Initial load
duke
parents:
diff changeset
807 // This register map must be update since we need to find the receiver for
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // compiled frames. The receiver might be in a register.
a61af66fc99e Initial load
duke
parents:
diff changeset
809 RegisterMap reg_map2(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
810 frame stubFrame = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
811 // Caller-frame is a compiled frame
a61af66fc99e Initial load
duke
parents:
diff changeset
812 frame callerFrame = stubFrame.sender(&reg_map2);
a61af66fc99e Initial load
duke
parents:
diff changeset
813
a61af66fc99e Initial load
duke
parents:
diff changeset
814 methodHandle callee = bytecode->static_target(CHECK_(nullHandle));
a61af66fc99e Initial load
duke
parents:
diff changeset
815 if (callee.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
816 THROW_(vmSymbols::java_lang_NoSuchMethodException(), nullHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
817 }
a61af66fc99e Initial load
duke
parents:
diff changeset
818 // Retrieve from a compiled argument list
a61af66fc99e Initial load
duke
parents:
diff changeset
819 receiver = Handle(THREAD, callerFrame.retrieve_receiver(&reg_map2));
a61af66fc99e Initial load
duke
parents:
diff changeset
820
a61af66fc99e Initial load
duke
parents:
diff changeset
821 if (receiver.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
822 THROW_(vmSymbols::java_lang_NullPointerException(), nullHandle);
a61af66fc99e Initial load
duke
parents:
diff changeset
823 }
a61af66fc99e Initial load
duke
parents:
diff changeset
824 }
a61af66fc99e Initial load
duke
parents:
diff changeset
825
a61af66fc99e Initial load
duke
parents:
diff changeset
826 // Resolve method. This is parameterized by bytecode.
a61af66fc99e Initial load
duke
parents:
diff changeset
827 constantPoolHandle constants (THREAD, caller->constants());
a61af66fc99e Initial load
duke
parents:
diff changeset
828 assert (receiver.is_null() || receiver->is_oop(), "wrong receiver");
a61af66fc99e Initial load
duke
parents:
diff changeset
829 LinkResolver::resolve_invoke(callinfo, receiver, constants, bytecode_index, bc, CHECK_(nullHandle));
a61af66fc99e Initial load
duke
parents:
diff changeset
830
a61af66fc99e Initial load
duke
parents:
diff changeset
831 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // Check that the receiver klass is of the right subtype and that it is initialized for virtual calls
a61af66fc99e Initial load
duke
parents:
diff changeset
833 if (bc != Bytecodes::_invokestatic) {
a61af66fc99e Initial load
duke
parents:
diff changeset
834 assert(receiver.not_null(), "should have thrown exception");
a61af66fc99e Initial load
duke
parents:
diff changeset
835 KlassHandle receiver_klass (THREAD, receiver->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
836 klassOop rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle));
a61af66fc99e Initial load
duke
parents:
diff changeset
837 // klass is already loaded
a61af66fc99e Initial load
duke
parents:
diff changeset
838 KlassHandle static_receiver_klass (THREAD, rk);
a61af66fc99e Initial load
duke
parents:
diff changeset
839 assert(receiver_klass->is_subtype_of(static_receiver_klass()), "actual receiver must be subclass of static receiver klass");
a61af66fc99e Initial load
duke
parents:
diff changeset
840 if (receiver_klass->oop_is_instance()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
841 if (instanceKlass::cast(receiver_klass())->is_not_initialized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
842 tty->print_cr("ERROR: Klass not yet initialized!!");
a61af66fc99e Initial load
duke
parents:
diff changeset
843 receiver_klass.print();
a61af66fc99e Initial load
duke
parents:
diff changeset
844 }
a61af66fc99e Initial load
duke
parents:
diff changeset
845 assert (!instanceKlass::cast(receiver_klass())->is_not_initialized(), "receiver_klass must be initialized");
a61af66fc99e Initial load
duke
parents:
diff changeset
846 }
a61af66fc99e Initial load
duke
parents:
diff changeset
847 }
a61af66fc99e Initial load
duke
parents:
diff changeset
848 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
849
a61af66fc99e Initial load
duke
parents:
diff changeset
850 return receiver;
a61af66fc99e Initial load
duke
parents:
diff changeset
851 }
a61af66fc99e Initial load
duke
parents:
diff changeset
852
a61af66fc99e Initial load
duke
parents:
diff changeset
853 methodHandle SharedRuntime::find_callee_method(JavaThread* thread, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
854 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // We need first to check if any Java activations (compiled, interpreted)
a61af66fc99e Initial load
duke
parents:
diff changeset
856 // exist on the stack since last JavaCall. If not, we need
a61af66fc99e Initial load
duke
parents:
diff changeset
857 // to get the target method from the JavaCall wrapper.
a61af66fc99e Initial load
duke
parents:
diff changeset
858 vframeStream vfst(thread, true); // Do not skip any javaCalls
a61af66fc99e Initial load
duke
parents:
diff changeset
859 methodHandle callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
860 if (vfst.at_end()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
861 // No Java frames were found on stack since we did the JavaCall.
a61af66fc99e Initial load
duke
parents:
diff changeset
862 // Hence the stack can only contain an entry_frame. We need to
a61af66fc99e Initial load
duke
parents:
diff changeset
863 // find the target method from the stub frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
864 RegisterMap reg_map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
865 frame fr = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
866 assert(fr.is_runtime_frame(), "must be a runtimeStub");
a61af66fc99e Initial load
duke
parents:
diff changeset
867 fr = fr.sender(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
868 assert(fr.is_entry_frame(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
869 // fr is now pointing to the entry frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
870 callee_method = methodHandle(THREAD, fr.entry_frame_call_wrapper()->callee_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
871 assert(fr.entry_frame_call_wrapper()->receiver() == NULL || !callee_method->is_static(), "non-null receiver for static call??");
a61af66fc99e Initial load
duke
parents:
diff changeset
872 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
873 Bytecodes::Code bc;
a61af66fc99e Initial load
duke
parents:
diff changeset
874 CallInfo callinfo;
a61af66fc99e Initial load
duke
parents:
diff changeset
875 find_callee_info_helper(thread, vfst, bc, callinfo, CHECK_(methodHandle()));
a61af66fc99e Initial load
duke
parents:
diff changeset
876 callee_method = callinfo.selected_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
877 }
a61af66fc99e Initial load
duke
parents:
diff changeset
878 assert(callee_method()->is_method(), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
879 return callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
880 }
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 // Resolves a call.
a61af66fc99e Initial load
duke
parents:
diff changeset
883 methodHandle SharedRuntime::resolve_helper(JavaThread *thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
884 bool is_virtual,
a61af66fc99e Initial load
duke
parents:
diff changeset
885 bool is_optimized, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
886 methodHandle callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
887 callee_method = resolve_sub_helper(thread, is_virtual, is_optimized, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
888 if (JvmtiExport::can_hotswap_or_post_breakpoint()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
889 int retry_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
890 while (!HAS_PENDING_EXCEPTION && callee_method->is_old() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
891 callee_method->method_holder() != SystemDictionary::object_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
892 // If has a pending exception then there is no need to re-try to
a61af66fc99e Initial load
duke
parents:
diff changeset
893 // resolve this method.
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // If the method has been redefined, we need to try again.
a61af66fc99e Initial load
duke
parents:
diff changeset
895 // Hack: we have no way to update the vtables of arrays, so don't
a61af66fc99e Initial load
duke
parents:
diff changeset
896 // require that java.lang.Object has been updated.
a61af66fc99e Initial load
duke
parents:
diff changeset
897
a61af66fc99e Initial load
duke
parents:
diff changeset
898 // It is very unlikely that method is redefined more than 100 times
a61af66fc99e Initial load
duke
parents:
diff changeset
899 // in the middle of resolve. If it is looping here more than 100 times
a61af66fc99e Initial load
duke
parents:
diff changeset
900 // means then there could be a bug here.
a61af66fc99e Initial load
duke
parents:
diff changeset
901 guarantee((retry_count++ < 100),
a61af66fc99e Initial load
duke
parents:
diff changeset
902 "Could not resolve to latest version of redefined method");
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // method is redefined in the middle of resolve so re-try.
a61af66fc99e Initial load
duke
parents:
diff changeset
904 callee_method = resolve_sub_helper(thread, is_virtual, is_optimized, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
905 }
a61af66fc99e Initial load
duke
parents:
diff changeset
906 }
a61af66fc99e Initial load
duke
parents:
diff changeset
907 return callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
908 }
a61af66fc99e Initial load
duke
parents:
diff changeset
909
a61af66fc99e Initial load
duke
parents:
diff changeset
910 // Resolves a call. The compilers generate code for calls that go here
a61af66fc99e Initial load
duke
parents:
diff changeset
911 // and are patched with the real destination of the call.
a61af66fc99e Initial load
duke
parents:
diff changeset
912 methodHandle SharedRuntime::resolve_sub_helper(JavaThread *thread,
a61af66fc99e Initial load
duke
parents:
diff changeset
913 bool is_virtual,
a61af66fc99e Initial load
duke
parents:
diff changeset
914 bool is_optimized, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
915
a61af66fc99e Initial load
duke
parents:
diff changeset
916 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
917 RegisterMap cbl_map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
918 frame caller_frame = thread->last_frame().sender(&cbl_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
919
a61af66fc99e Initial load
duke
parents:
diff changeset
920 CodeBlob* cb = caller_frame.cb();
a61af66fc99e Initial load
duke
parents:
diff changeset
921 guarantee(cb != NULL && cb->is_nmethod(), "must be called from nmethod");
a61af66fc99e Initial load
duke
parents:
diff changeset
922 // make sure caller is not getting deoptimized
a61af66fc99e Initial load
duke
parents:
diff changeset
923 // and removed before we are done with it.
a61af66fc99e Initial load
duke
parents:
diff changeset
924 // CLEANUP - with lazy deopt shouldn't need this lock
a61af66fc99e Initial load
duke
parents:
diff changeset
925 nmethodLocker caller_lock((nmethod*)cb);
a61af66fc99e Initial load
duke
parents:
diff changeset
926
a61af66fc99e Initial load
duke
parents:
diff changeset
927
a61af66fc99e Initial load
duke
parents:
diff changeset
928 // determine call info & receiver
a61af66fc99e Initial load
duke
parents:
diff changeset
929 // note: a) receiver is NULL for static calls
a61af66fc99e Initial load
duke
parents:
diff changeset
930 // b) an exception is thrown if receiver is NULL for non-static calls
a61af66fc99e Initial load
duke
parents:
diff changeset
931 CallInfo call_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
932 Bytecodes::Code invoke_code = Bytecodes::_illegal;
a61af66fc99e Initial load
duke
parents:
diff changeset
933 Handle receiver = find_callee_info(thread, invoke_code,
a61af66fc99e Initial load
duke
parents:
diff changeset
934 call_info, CHECK_(methodHandle()));
a61af66fc99e Initial load
duke
parents:
diff changeset
935 methodHandle callee_method = call_info.selected_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
936
a61af66fc99e Initial load
duke
parents:
diff changeset
937 assert((!is_virtual && invoke_code == Bytecodes::_invokestatic) ||
a61af66fc99e Initial load
duke
parents:
diff changeset
938 ( is_virtual && invoke_code != Bytecodes::_invokestatic), "inconsistent bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
939
a61af66fc99e Initial load
duke
parents:
diff changeset
940 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
941 // tracing/debugging/statistics
a61af66fc99e Initial load
duke
parents:
diff changeset
942 int *addr = (is_optimized) ? (&_resolve_opt_virtual_ctr) :
a61af66fc99e Initial load
duke
parents:
diff changeset
943 (is_virtual) ? (&_resolve_virtual_ctr) :
a61af66fc99e Initial load
duke
parents:
diff changeset
944 (&_resolve_static_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
945 Atomic::inc(addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
946
a61af66fc99e Initial load
duke
parents:
diff changeset
947 if (TraceCallFixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
948 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
949 tty->print("resolving %s%s (%s) call to",
a61af66fc99e Initial load
duke
parents:
diff changeset
950 (is_optimized) ? "optimized " : "", (is_virtual) ? "virtual" : "static",
a61af66fc99e Initial load
duke
parents:
diff changeset
951 Bytecodes::name(invoke_code));
a61af66fc99e Initial load
duke
parents:
diff changeset
952 callee_method->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
953 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
a61af66fc99e Initial load
duke
parents:
diff changeset
954 }
a61af66fc99e Initial load
duke
parents:
diff changeset
955 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
956
a61af66fc99e Initial load
duke
parents:
diff changeset
957 // Compute entry points. This might require generation of C2I converter
a61af66fc99e Initial load
duke
parents:
diff changeset
958 // frames, so we cannot be holding any locks here. Furthermore, the
a61af66fc99e Initial load
duke
parents:
diff changeset
959 // computation of the entry points is independent of patching the call. We
a61af66fc99e Initial load
duke
parents:
diff changeset
960 // always return the entry-point, but we only patch the stub if the call has
a61af66fc99e Initial load
duke
parents:
diff changeset
961 // not been deoptimized. Return values: For a virtual call this is an
a61af66fc99e Initial load
duke
parents:
diff changeset
962 // (cached_oop, destination address) pair. For a static call/optimized
a61af66fc99e Initial load
duke
parents:
diff changeset
963 // virtual this is just a destination address.
a61af66fc99e Initial load
duke
parents:
diff changeset
964
a61af66fc99e Initial load
duke
parents:
diff changeset
965 StaticCallInfo static_call_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
966 CompiledICInfo virtual_call_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
967
a61af66fc99e Initial load
duke
parents:
diff changeset
968
a61af66fc99e Initial load
duke
parents:
diff changeset
969 // Make sure the callee nmethod does not get deoptimized and removed before
a61af66fc99e Initial load
duke
parents:
diff changeset
970 // we are done patching the code.
a61af66fc99e Initial load
duke
parents:
diff changeset
971 nmethod* nm = callee_method->code();
a61af66fc99e Initial load
duke
parents:
diff changeset
972 nmethodLocker nl_callee(nm);
a61af66fc99e Initial load
duke
parents:
diff changeset
973 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
974 address dest_entry_point = nm == NULL ? 0 : nm->entry_point(); // used below
a61af66fc99e Initial load
duke
parents:
diff changeset
975 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
976
a61af66fc99e Initial load
duke
parents:
diff changeset
977 if (is_virtual) {
a61af66fc99e Initial load
duke
parents:
diff changeset
978 assert(receiver.not_null(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
979 bool static_bound = call_info.resolved_method()->can_be_statically_bound();
a61af66fc99e Initial load
duke
parents:
diff changeset
980 KlassHandle h_klass(THREAD, receiver->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
981 CompiledIC::compute_monomorphic_entry(callee_method, h_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
982 is_optimized, static_bound, virtual_call_info,
a61af66fc99e Initial load
duke
parents:
diff changeset
983 CHECK_(methodHandle()));
a61af66fc99e Initial load
duke
parents:
diff changeset
984 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
985 // static call
a61af66fc99e Initial load
duke
parents:
diff changeset
986 CompiledStaticCall::compute_entry(callee_method, static_call_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
987 }
a61af66fc99e Initial load
duke
parents:
diff changeset
988
a61af66fc99e Initial load
duke
parents:
diff changeset
989 // grab lock, check for deoptimization and potentially patch caller
a61af66fc99e Initial load
duke
parents:
diff changeset
990 {
a61af66fc99e Initial load
duke
parents:
diff changeset
991 MutexLocker ml_patch(CompiledIC_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
992
a61af66fc99e Initial load
duke
parents:
diff changeset
993 // Now that we are ready to patch if the methodOop was redefined then
a61af66fc99e Initial load
duke
parents:
diff changeset
994 // don't update call site and let the caller retry.
a61af66fc99e Initial load
duke
parents:
diff changeset
995
a61af66fc99e Initial load
duke
parents:
diff changeset
996 if (!callee_method->is_old()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
997 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
998 // We must not try to patch to jump to an already unloaded method.
a61af66fc99e Initial load
duke
parents:
diff changeset
999 if (dest_entry_point != 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 assert(CodeCache::find_blob(dest_entry_point) != NULL,
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 "should not unload nmethod while locked");
a61af66fc99e Initial load
duke
parents:
diff changeset
1002 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 if (is_virtual) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1005 CompiledIC* inline_cache = CompiledIC_before(caller_frame.pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1006 if (inline_cache->is_clean()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1007 inline_cache->set_to_monomorphic(virtual_call_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 CompiledStaticCall* ssc = compiledStaticCall_before(caller_frame.pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 if (ssc->is_clean()) ssc->set(static_call_info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1014
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 } // unlock CompiledIC_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1016
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 return callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1018 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1019
a61af66fc99e Initial load
duke
parents:
diff changeset
1020
a61af66fc99e Initial load
duke
parents:
diff changeset
1021 // Inline caches exist only in compiled code
a61af66fc99e Initial load
duke
parents:
diff changeset
1022 JRT_BLOCK_ENTRY(address, SharedRuntime::handle_wrong_method_ic_miss(JavaThread* thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 RegisterMap reg_map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 frame stub_frame = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 assert(stub_frame.is_runtime_frame(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 frame caller_frame = stub_frame.sender(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 assert(!caller_frame.is_interpreted_frame() && !caller_frame.is_entry_frame(), "unexpected frame");
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 #endif /* ASSERT */
a61af66fc99e Initial load
duke
parents:
diff changeset
1030
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 methodHandle callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 JRT_BLOCK
a61af66fc99e Initial load
duke
parents:
diff changeset
1033 callee_method = SharedRuntime::handle_ic_miss_helper(thread, CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1034 // Return methodOop through TLS
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 thread->set_vm_result(callee_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 JRT_BLOCK_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 // return compiled code entry point after potential safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 return callee_method->verified_code_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1041
a61af66fc99e Initial load
duke
parents:
diff changeset
1042
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 // Handle call site that has been made non-entrant
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 JRT_BLOCK_ENTRY(address, SharedRuntime::handle_wrong_method(JavaThread* thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
1045 // 6243940 We might end up in here if the callee is deoptimized
a61af66fc99e Initial load
duke
parents:
diff changeset
1046 // as we race to call it. We don't want to take a safepoint if
a61af66fc99e Initial load
duke
parents:
diff changeset
1047 // the caller was interpreted because the caller frame will look
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 // interpreted to the stack walkers and arguments are now
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // "compiled" so it is much better to make this transition
a61af66fc99e Initial load
duke
parents:
diff changeset
1050 // invisible to the stack walking code. The i2c path will
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 // place the callee method in the callee_target. It is stashed
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 // there because if we try and find the callee by normal means a
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 // safepoint is possible and have trouble gc'ing the compiled args.
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 RegisterMap reg_map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1055 frame stub_frame = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1056 assert(stub_frame.is_runtime_frame(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 frame caller_frame = stub_frame.sender(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 if (caller_frame.is_interpreted_frame() || caller_frame.is_entry_frame() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 methodOop callee = thread->callee_target();
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 guarantee(callee != NULL && callee->is_method(), "bad handshake");
a61af66fc99e Initial load
duke
parents:
diff changeset
1061 thread->set_vm_result(callee);
a61af66fc99e Initial load
duke
parents:
diff changeset
1062 thread->set_callee_target(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 return callee->get_c2i_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1065
a61af66fc99e Initial load
duke
parents:
diff changeset
1066 // Must be compiled to compiled path which is safe to stackwalk
a61af66fc99e Initial load
duke
parents:
diff changeset
1067 methodHandle callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1068 JRT_BLOCK
a61af66fc99e Initial load
duke
parents:
diff changeset
1069 // Force resolving of caller (if we called from compiled frame)
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 callee_method = SharedRuntime::reresolve_call_site(thread, CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 thread->set_vm_result(callee_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1072 JRT_BLOCK_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1073 // return compiled code entry point after potential safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1075 return callee_method->verified_code_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
1076 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1077
a61af66fc99e Initial load
duke
parents:
diff changeset
1078
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 // resolve a static call and patch code
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_static_call_C(JavaThread *thread ))
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 methodHandle callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1082 JRT_BLOCK
a61af66fc99e Initial load
duke
parents:
diff changeset
1083 callee_method = SharedRuntime::resolve_helper(thread, false, false, CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 thread->set_vm_result(callee_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1085 JRT_BLOCK_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1086 // return compiled code entry point after potential safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
1087 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 return callee_method->verified_code_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1090
a61af66fc99e Initial load
duke
parents:
diff changeset
1091
a61af66fc99e Initial load
duke
parents:
diff changeset
1092 // resolve virtual call and update inline cache to monomorphic
a61af66fc99e Initial load
duke
parents:
diff changeset
1093 JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_virtual_call_C(JavaThread *thread ))
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 methodHandle callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 JRT_BLOCK
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 callee_method = SharedRuntime::resolve_helper(thread, true, false, CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1097 thread->set_vm_result(callee_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1098 JRT_BLOCK_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1099 // return compiled code entry point after potential safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
1100 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 return callee_method->verified_code_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1103
a61af66fc99e Initial load
duke
parents:
diff changeset
1104
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 // Resolve a virtual call that can be statically bound (e.g., always
a61af66fc99e Initial load
duke
parents:
diff changeset
1106 // monomorphic, so it has no inline cache). Patch code to resolved target.
a61af66fc99e Initial load
duke
parents:
diff changeset
1107 JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_opt_virtual_call_C(JavaThread *thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 methodHandle callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1109 JRT_BLOCK
a61af66fc99e Initial load
duke
parents:
diff changeset
1110 callee_method = SharedRuntime::resolve_helper(thread, true, true, CHECK_NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1111 thread->set_vm_result(callee_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 JRT_BLOCK_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 // return compiled code entry point after potential safepoints
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 return callee_method->verified_code_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1117
a61af66fc99e Initial load
duke
parents:
diff changeset
1118
a61af66fc99e Initial load
duke
parents:
diff changeset
1119
a61af66fc99e Initial load
duke
parents:
diff changeset
1120
a61af66fc99e Initial load
duke
parents:
diff changeset
1121
a61af66fc99e Initial load
duke
parents:
diff changeset
1122 methodHandle SharedRuntime::handle_ic_miss_helper(JavaThread *thread, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1123 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1124 CallInfo call_info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1125 Bytecodes::Code bc;
a61af66fc99e Initial load
duke
parents:
diff changeset
1126
a61af66fc99e Initial load
duke
parents:
diff changeset
1127 // receiver is NULL for static calls. An exception is thrown for NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
1128 // receivers for non-static calls
a61af66fc99e Initial load
duke
parents:
diff changeset
1129 Handle receiver = find_callee_info(thread, bc, call_info,
a61af66fc99e Initial load
duke
parents:
diff changeset
1130 CHECK_(methodHandle()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1131 // Compiler1 can produce virtual call sites that can actually be statically bound
a61af66fc99e Initial load
duke
parents:
diff changeset
1132 // If we fell thru to below we would think that the site was going megamorphic
a61af66fc99e Initial load
duke
parents:
diff changeset
1133 // when in fact the site can never miss. Worse because we'd think it was megamorphic
a61af66fc99e Initial load
duke
parents:
diff changeset
1134 // we'd try and do a vtable dispatch however methods that can be statically bound
a61af66fc99e Initial load
duke
parents:
diff changeset
1135 // don't have vtable entries (vtable_index < 0) and we'd blow up. So we force a
a61af66fc99e Initial load
duke
parents:
diff changeset
1136 // reresolution of the call site (as if we did a handle_wrong_method and not an
a61af66fc99e Initial load
duke
parents:
diff changeset
1137 // plain ic_miss) and the site will be converted to an optimized virtual call site
a61af66fc99e Initial load
duke
parents:
diff changeset
1138 // never to miss again. I don't believe C2 will produce code like this but if it
a61af66fc99e Initial load
duke
parents:
diff changeset
1139 // did this would still be the correct thing to do for it too, hence no ifdef.
a61af66fc99e Initial load
duke
parents:
diff changeset
1140 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1141 if (call_info.resolved_method()->can_be_statically_bound()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1142 methodHandle callee_method = SharedRuntime::reresolve_call_site(thread, CHECK_(methodHandle()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1143 if (TraceCallFixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1144 RegisterMap reg_map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1145 frame caller_frame = thread->last_frame().sender(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1146 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1147 tty->print("converting IC miss to reresolve (%s) call to", Bytecodes::name(bc));
a61af66fc99e Initial load
duke
parents:
diff changeset
1148 callee_method->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1149 tty->print_cr(" from pc: " INTPTR_FORMAT, caller_frame.pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1150 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
a61af66fc99e Initial load
duke
parents:
diff changeset
1151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1152 return callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1154
a61af66fc99e Initial load
duke
parents:
diff changeset
1155 methodHandle callee_method = call_info.selected_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1156
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 bool should_be_mono = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1158
a61af66fc99e Initial load
duke
parents:
diff changeset
1159 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 Atomic::inc(&_ic_miss_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1161
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 // Statistics & Tracing
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 if (TraceCallFixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1164 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 tty->print("IC miss (%s) call to", Bytecodes::name(bc));
a61af66fc99e Initial load
duke
parents:
diff changeset
1166 callee_method->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1167 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
a61af66fc99e Initial load
duke
parents:
diff changeset
1168 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1169
a61af66fc99e Initial load
duke
parents:
diff changeset
1170 if (ICMissHistogram) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1171 MutexLocker m(VMStatistic_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1172 RegisterMap reg_map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1173 frame f = thread->last_frame().real_sender(&reg_map);// skip runtime stub
a61af66fc99e Initial load
duke
parents:
diff changeset
1174 // produce statistics under the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1175 trace_ic_miss(f.pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1176 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1177 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1178
a61af66fc99e Initial load
duke
parents:
diff changeset
1179 // install an event collector so that when a vtable stub is created the
a61af66fc99e Initial load
duke
parents:
diff changeset
1180 // profiler can be notified via a DYNAMIC_CODE_GENERATED event. The
a61af66fc99e Initial load
duke
parents:
diff changeset
1181 // event can't be posted when the stub is created as locks are held
a61af66fc99e Initial load
duke
parents:
diff changeset
1182 // - instead the event will be deferred until the event collector goes
a61af66fc99e Initial load
duke
parents:
diff changeset
1183 // out of scope.
a61af66fc99e Initial load
duke
parents:
diff changeset
1184 JvmtiDynamicCodeEventCollector event_collector;
a61af66fc99e Initial load
duke
parents:
diff changeset
1185
a61af66fc99e Initial load
duke
parents:
diff changeset
1186 // Update inline cache to megamorphic. Skip update if caller has been
a61af66fc99e Initial load
duke
parents:
diff changeset
1187 // made non-entrant or we are called from interpreted.
a61af66fc99e Initial load
duke
parents:
diff changeset
1188 { MutexLocker ml_patch (CompiledIC_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1189 RegisterMap reg_map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1190 frame caller_frame = thread->last_frame().sender(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1191 CodeBlob* cb = caller_frame.cb();
a61af66fc99e Initial load
duke
parents:
diff changeset
1192 if (cb->is_nmethod() && ((nmethod*)cb)->is_in_use()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1193 // Not a non-entrant nmethod, so find inline_cache
a61af66fc99e Initial load
duke
parents:
diff changeset
1194 CompiledIC* inline_cache = CompiledIC_before(caller_frame.pc());
a61af66fc99e Initial load
duke
parents:
diff changeset
1195 bool should_be_mono = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1196 if (inline_cache->is_optimized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1197 if (TraceCallFixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1198 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1199 tty->print("OPTIMIZED IC miss (%s) call to", Bytecodes::name(bc));
a61af66fc99e Initial load
duke
parents:
diff changeset
1200 callee_method->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1201 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
a61af66fc99e Initial load
duke
parents:
diff changeset
1202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1203 should_be_mono = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1204 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1205 compiledICHolderOop ic_oop = (compiledICHolderOop) inline_cache->cached_oop();
a61af66fc99e Initial load
duke
parents:
diff changeset
1206 if ( ic_oop != NULL && ic_oop->is_compiledICHolder()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1207
a61af66fc99e Initial load
duke
parents:
diff changeset
1208 if (receiver()->klass() == ic_oop->holder_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1209 // This isn't a real miss. We must have seen that compiled code
a61af66fc99e Initial load
duke
parents:
diff changeset
1210 // is now available and we want the call site converted to a
a61af66fc99e Initial load
duke
parents:
diff changeset
1211 // monomorphic compiled call site.
a61af66fc99e Initial load
duke
parents:
diff changeset
1212 // We can't assert for callee_method->code() != NULL because it
a61af66fc99e Initial load
duke
parents:
diff changeset
1213 // could have been deoptimized in the meantime
a61af66fc99e Initial load
duke
parents:
diff changeset
1214 if (TraceCallFixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1215 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1216 tty->print("FALSE IC miss (%s) converting to compiled call to", Bytecodes::name(bc));
a61af66fc99e Initial load
duke
parents:
diff changeset
1217 callee_method->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1218 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
a61af66fc99e Initial load
duke
parents:
diff changeset
1219 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1220 should_be_mono = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1221 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1223 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1224
a61af66fc99e Initial load
duke
parents:
diff changeset
1225 if (should_be_mono) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1226
a61af66fc99e Initial load
duke
parents:
diff changeset
1227 // We have a path that was monomorphic but was going interpreted
a61af66fc99e Initial load
duke
parents:
diff changeset
1228 // and now we have (or had) a compiled entry. We correct the IC
a61af66fc99e Initial load
duke
parents:
diff changeset
1229 // by using a new icBuffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
1230 CompiledICInfo info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1231 KlassHandle receiver_klass(THREAD, receiver()->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
1232 inline_cache->compute_monomorphic_entry(callee_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
1233 receiver_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
1234 inline_cache->is_optimized(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1235 false,
a61af66fc99e Initial load
duke
parents:
diff changeset
1236 info, CHECK_(methodHandle()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1237 inline_cache->set_to_monomorphic(info);
a61af66fc99e Initial load
duke
parents:
diff changeset
1238 } else if (!inline_cache->is_megamorphic() && !inline_cache->is_clean()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1239 // Change to megamorphic
a61af66fc99e Initial load
duke
parents:
diff changeset
1240 inline_cache->set_to_megamorphic(&call_info, bc, CHECK_(methodHandle()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1241 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1242 // Either clean or megamorphic
a61af66fc99e Initial load
duke
parents:
diff changeset
1243 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1245 } // Release CompiledIC_lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1246
a61af66fc99e Initial load
duke
parents:
diff changeset
1247 return callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1248 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1249
a61af66fc99e Initial load
duke
parents:
diff changeset
1250 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1251 // Resets a call-site in compiled code so it will get resolved again.
a61af66fc99e Initial load
duke
parents:
diff changeset
1252 // This routines handles both virtual call sites, optimized virtual call
a61af66fc99e Initial load
duke
parents:
diff changeset
1253 // sites, and static call sites. Typically used to change a call sites
a61af66fc99e Initial load
duke
parents:
diff changeset
1254 // destination from compiled to interpreted.
a61af66fc99e Initial load
duke
parents:
diff changeset
1255 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1256 methodHandle SharedRuntime::reresolve_call_site(JavaThread *thread, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1257 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1258 RegisterMap reg_map(thread, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1259 frame stub_frame = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
1260 assert(stub_frame.is_runtime_frame(), "must be a runtimeStub");
a61af66fc99e Initial load
duke
parents:
diff changeset
1261 frame caller = stub_frame.sender(&reg_map);
a61af66fc99e Initial load
duke
parents:
diff changeset
1262
a61af66fc99e Initial load
duke
parents:
diff changeset
1263 // Do nothing if the frame isn't a live compiled frame.
a61af66fc99e Initial load
duke
parents:
diff changeset
1264 // nmethod could be deoptimized by the time we get here
a61af66fc99e Initial load
duke
parents:
diff changeset
1265 // so no update to the caller is needed.
a61af66fc99e Initial load
duke
parents:
diff changeset
1266
a61af66fc99e Initial load
duke
parents:
diff changeset
1267 if (caller.is_compiled_frame() && !caller.is_deoptimized_frame()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1268
a61af66fc99e Initial load
duke
parents:
diff changeset
1269 address pc = caller.pc();
a61af66fc99e Initial load
duke
parents:
diff changeset
1270 Events::log("update call-site at pc " INTPTR_FORMAT, pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1271
a61af66fc99e Initial load
duke
parents:
diff changeset
1272 // Default call_addr is the location of the "basic" call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1273 // Determine the address of the call we a reresolving. With
a61af66fc99e Initial load
duke
parents:
diff changeset
1274 // Inline Caches we will always find a recognizable call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1275 // With Inline Caches disabled we may or may not find a
a61af66fc99e Initial load
duke
parents:
diff changeset
1276 // recognizable call. We will always find a call for static
a61af66fc99e Initial load
duke
parents:
diff changeset
1277 // calls and for optimized virtual calls. For vanilla virtual
a61af66fc99e Initial load
duke
parents:
diff changeset
1278 // calls it depends on the state of the UseInlineCaches switch.
a61af66fc99e Initial load
duke
parents:
diff changeset
1279 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1280 // With Inline Caches disabled we can get here for a virtual call
a61af66fc99e Initial load
duke
parents:
diff changeset
1281 // for two reasons:
a61af66fc99e Initial load
duke
parents:
diff changeset
1282 // 1 - calling an abstract method. The vtable for abstract methods
a61af66fc99e Initial load
duke
parents:
diff changeset
1283 // will run us thru handle_wrong_method and we will eventually
a61af66fc99e Initial load
duke
parents:
diff changeset
1284 // end up in the interpreter to throw the ame.
a61af66fc99e Initial load
duke
parents:
diff changeset
1285 // 2 - a racing deoptimization. We could be doing a vanilla vtable
a61af66fc99e Initial load
duke
parents:
diff changeset
1286 // call and between the time we fetch the entry address and
a61af66fc99e Initial load
duke
parents:
diff changeset
1287 // we jump to it the target gets deoptimized. Similar to 1
a61af66fc99e Initial load
duke
parents:
diff changeset
1288 // we will wind up in the interprter (thru a c2i with c2).
a61af66fc99e Initial load
duke
parents:
diff changeset
1289 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1290 address call_addr = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1291 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1292 // Get call instruction under lock because another thread may be
a61af66fc99e Initial load
duke
parents:
diff changeset
1293 // busy patching it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1294 MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1295 // Location of call instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1296 if (NativeCall::is_call_before(pc)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1297 NativeCall *ncall = nativeCall_before(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1298 call_addr = ncall->instruction_address();
a61af66fc99e Initial load
duke
parents:
diff changeset
1299 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1300 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1301
a61af66fc99e Initial load
duke
parents:
diff changeset
1302 // Check for static or virtual call
a61af66fc99e Initial load
duke
parents:
diff changeset
1303 bool is_static_call = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
1304 nmethod* caller_nm = CodeCache::find_nmethod(pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1305 // Make sure nmethod doesn't get deoptimized and removed until
a61af66fc99e Initial load
duke
parents:
diff changeset
1306 // this is done with it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1307 // CLEANUP - with lazy deopt shouldn't need this lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1308 nmethodLocker nmlock(caller_nm);
a61af66fc99e Initial load
duke
parents:
diff changeset
1309
a61af66fc99e Initial load
duke
parents:
diff changeset
1310 if (call_addr != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1311 RelocIterator iter(caller_nm, call_addr, call_addr+1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1312 int ret = iter.next(); // Get item
a61af66fc99e Initial load
duke
parents:
diff changeset
1313 if (ret) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1314 assert(iter.addr() == call_addr, "must find call");
a61af66fc99e Initial load
duke
parents:
diff changeset
1315 if (iter.type() == relocInfo::static_call_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1316 is_static_call = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1317 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1318 assert(iter.type() == relocInfo::virtual_call_type ||
a61af66fc99e Initial load
duke
parents:
diff changeset
1319 iter.type() == relocInfo::opt_virtual_call_type
a61af66fc99e Initial load
duke
parents:
diff changeset
1320 , "unexpected relocInfo. type");
a61af66fc99e Initial load
duke
parents:
diff changeset
1321 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1322 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1323 assert(!UseInlineCaches, "relocation info. must exist for this address");
a61af66fc99e Initial load
duke
parents:
diff changeset
1324 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1325
a61af66fc99e Initial load
duke
parents:
diff changeset
1326 // Cleaning the inline cache will force a new resolve. This is more robust
a61af66fc99e Initial load
duke
parents:
diff changeset
1327 // than directly setting it to the new destination, since resolving of calls
a61af66fc99e Initial load
duke
parents:
diff changeset
1328 // is always done through the same code path. (experience shows that it
a61af66fc99e Initial load
duke
parents:
diff changeset
1329 // leads to very hard to track down bugs, if an inline cache gets updated
a61af66fc99e Initial load
duke
parents:
diff changeset
1330 // to a wrong method). It should not be performance critical, since the
a61af66fc99e Initial load
duke
parents:
diff changeset
1331 // resolve is only done once.
a61af66fc99e Initial load
duke
parents:
diff changeset
1332
a61af66fc99e Initial load
duke
parents:
diff changeset
1333 MutexLocker ml(CompiledIC_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1334 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1335 // We do not patch the call site if the nmethod has been made non-entrant
a61af66fc99e Initial load
duke
parents:
diff changeset
1336 // as it is a waste of time
a61af66fc99e Initial load
duke
parents:
diff changeset
1337 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1338 if (caller_nm->is_in_use()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1339 if (is_static_call) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1340 CompiledStaticCall* ssc= compiledStaticCall_at(call_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1341 ssc->set_to_clean();
a61af66fc99e Initial load
duke
parents:
diff changeset
1342 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1343 // compiled, dispatched call (which used to call an interpreted method)
a61af66fc99e Initial load
duke
parents:
diff changeset
1344 CompiledIC* inline_cache = CompiledIC_at(call_addr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1345 inline_cache->set_to_clean();
a61af66fc99e Initial load
duke
parents:
diff changeset
1346 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1348 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1349
a61af66fc99e Initial load
duke
parents:
diff changeset
1350 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1351
a61af66fc99e Initial load
duke
parents:
diff changeset
1352 methodHandle callee_method = find_callee_method(thread, CHECK_(methodHandle()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1353
a61af66fc99e Initial load
duke
parents:
diff changeset
1354
a61af66fc99e Initial load
duke
parents:
diff changeset
1355 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1356 Atomic::inc(&_wrong_method_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1357
a61af66fc99e Initial load
duke
parents:
diff changeset
1358 if (TraceCallFixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1359 ResourceMark rm(thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1360 tty->print("handle_wrong_method reresolving call to");
a61af66fc99e Initial load
duke
parents:
diff changeset
1361 callee_method->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1362 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code());
a61af66fc99e Initial load
duke
parents:
diff changeset
1363 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1364 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1365
a61af66fc99e Initial load
duke
parents:
diff changeset
1366 return callee_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
1367 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1368
a61af66fc99e Initial load
duke
parents:
diff changeset
1369 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1370 // We are calling the interpreter via a c2i. Normally this would mean that
a61af66fc99e Initial load
duke
parents:
diff changeset
1371 // we were called by a compiled method. However we could have lost a race
a61af66fc99e Initial load
duke
parents:
diff changeset
1372 // where we went int -> i2c -> c2i and so the caller could in fact be
a61af66fc99e Initial load
duke
parents:
diff changeset
1373 // interpreted. If the caller is compiled we attampt to patch the caller
a61af66fc99e Initial load
duke
parents:
diff changeset
1374 // so he no longer calls into the interpreter.
a61af66fc99e Initial load
duke
parents:
diff changeset
1375 IRT_LEAF(void, SharedRuntime::fixup_callers_callsite(methodOopDesc* method, address caller_pc))
a61af66fc99e Initial load
duke
parents:
diff changeset
1376 methodOop moop(method);
a61af66fc99e Initial load
duke
parents:
diff changeset
1377
a61af66fc99e Initial load
duke
parents:
diff changeset
1378 address entry_point = moop->from_compiled_entry();
a61af66fc99e Initial load
duke
parents:
diff changeset
1379
a61af66fc99e Initial load
duke
parents:
diff changeset
1380 // It's possible that deoptimization can occur at a call site which hasn't
a61af66fc99e Initial load
duke
parents:
diff changeset
1381 // been resolved yet, in which case this function will be called from
a61af66fc99e Initial load
duke
parents:
diff changeset
1382 // an nmethod that has been patched for deopt and we can ignore the
a61af66fc99e Initial load
duke
parents:
diff changeset
1383 // request for a fixup.
a61af66fc99e Initial load
duke
parents:
diff changeset
1384 // Also it is possible that we lost a race in that from_compiled_entry
a61af66fc99e Initial load
duke
parents:
diff changeset
1385 // is now back to the i2c in that case we don't need to patch and if
a61af66fc99e Initial load
duke
parents:
diff changeset
1386 // we did we'd leap into space because the callsite needs to use
a61af66fc99e Initial load
duke
parents:
diff changeset
1387 // "to interpreter" stub in order to load up the methodOop. Don't
a61af66fc99e Initial load
duke
parents:
diff changeset
1388 // ask me how I know this...
a61af66fc99e Initial load
duke
parents:
diff changeset
1389 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1390
a61af66fc99e Initial load
duke
parents:
diff changeset
1391 CodeBlob* cb = CodeCache::find_blob(caller_pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1392 if ( !cb->is_nmethod() || entry_point == moop->get_c2i_entry()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1393 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1394 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1395
a61af66fc99e Initial load
duke
parents:
diff changeset
1396 // There is a benign race here. We could be attempting to patch to a compiled
a61af66fc99e Initial load
duke
parents:
diff changeset
1397 // entry point at the same time the callee is being deoptimized. If that is
a61af66fc99e Initial load
duke
parents:
diff changeset
1398 // the case then entry_point may in fact point to a c2i and we'd patch the
a61af66fc99e Initial load
duke
parents:
diff changeset
1399 // call site with the same old data. clear_code will set code() to NULL
a61af66fc99e Initial load
duke
parents:
diff changeset
1400 // at the end of it. If we happen to see that NULL then we can skip trying
a61af66fc99e Initial load
duke
parents:
diff changeset
1401 // to patch. If we hit the window where the callee has a c2i in the
a61af66fc99e Initial load
duke
parents:
diff changeset
1402 // from_compiled_entry and the NULL isn't present yet then we lose the race
a61af66fc99e Initial load
duke
parents:
diff changeset
1403 // and patch the code with the same old data. Asi es la vida.
a61af66fc99e Initial load
duke
parents:
diff changeset
1404
a61af66fc99e Initial load
duke
parents:
diff changeset
1405 if (moop->code() == NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1406
a61af66fc99e Initial load
duke
parents:
diff changeset
1407 if (((nmethod*)cb)->is_in_use()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1408
a61af66fc99e Initial load
duke
parents:
diff changeset
1409 // Expect to find a native call there (unless it was no-inline cache vtable dispatch)
a61af66fc99e Initial load
duke
parents:
diff changeset
1410 MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1411 if (NativeCall::is_call_before(caller_pc + frame::pc_return_offset)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1412 NativeCall *call = nativeCall_before(caller_pc + frame::pc_return_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
1413 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1414 // bug 6281185. We might get here after resolving a call site to a vanilla
a61af66fc99e Initial load
duke
parents:
diff changeset
1415 // virtual call. Because the resolvee uses the verified entry it may then
a61af66fc99e Initial load
duke
parents:
diff changeset
1416 // see compiled code and attempt to patch the site by calling us. This would
a61af66fc99e Initial load
duke
parents:
diff changeset
1417 // then incorrectly convert the call site to optimized and its downhill from
a61af66fc99e Initial load
duke
parents:
diff changeset
1418 // there. If you're lucky you'll get the assert in the bugid, if not you've
a61af66fc99e Initial load
duke
parents:
diff changeset
1419 // just made a call site that could be megamorphic into a monomorphic site
a61af66fc99e Initial load
duke
parents:
diff changeset
1420 // for the rest of its life! Just another racing bug in the life of
a61af66fc99e Initial load
duke
parents:
diff changeset
1421 // fixup_callers_callsite ...
a61af66fc99e Initial load
duke
parents:
diff changeset
1422 //
a61af66fc99e Initial load
duke
parents:
diff changeset
1423 RelocIterator iter(cb, call->instruction_address(), call->next_instruction_address());
a61af66fc99e Initial load
duke
parents:
diff changeset
1424 iter.next();
a61af66fc99e Initial load
duke
parents:
diff changeset
1425 assert(iter.has_current(), "must have a reloc at java call site");
a61af66fc99e Initial load
duke
parents:
diff changeset
1426 relocInfo::relocType typ = iter.reloc()->type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1427 if ( typ != relocInfo::static_call_type &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1428 typ != relocInfo::opt_virtual_call_type &&
a61af66fc99e Initial load
duke
parents:
diff changeset
1429 typ != relocInfo::static_stub_type) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1430 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1431 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1432 address destination = call->destination();
a61af66fc99e Initial load
duke
parents:
diff changeset
1433 if (destination != entry_point) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1434 CodeBlob* callee = CodeCache::find_blob(destination);
a61af66fc99e Initial load
duke
parents:
diff changeset
1435 // callee == cb seems weird. It means calling interpreter thru stub.
a61af66fc99e Initial load
duke
parents:
diff changeset
1436 if (callee == cb || callee->is_adapter_blob()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1437 // static call or optimized virtual
a61af66fc99e Initial load
duke
parents:
diff changeset
1438 if (TraceCallFixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1439 tty->print("fixup callsite at " INTPTR_FORMAT " to compiled code for", caller_pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1440 moop->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1441 tty->print_cr(" to " INTPTR_FORMAT, entry_point);
a61af66fc99e Initial load
duke
parents:
diff changeset
1442 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1443 call->set_destination_mt_safe(entry_point);
a61af66fc99e Initial load
duke
parents:
diff changeset
1444 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1445 if (TraceCallFixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1446 tty->print("failed to fixup callsite at " INTPTR_FORMAT " to compiled code for", caller_pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1447 moop->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1448 tty->print_cr(" to " INTPTR_FORMAT, entry_point);
a61af66fc99e Initial load
duke
parents:
diff changeset
1449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1450 // assert is too strong could also be resolve destinations.
a61af66fc99e Initial load
duke
parents:
diff changeset
1451 // assert(InlineCacheBuffer::contains(destination) || VtableStubs::contains(destination), "must be");
a61af66fc99e Initial load
duke
parents:
diff changeset
1452 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1453 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1454 if (TraceCallFixup) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1455 tty->print("already patched callsite at " INTPTR_FORMAT " to compiled code for", caller_pc);
a61af66fc99e Initial load
duke
parents:
diff changeset
1456 moop->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1457 tty->print_cr(" to " INTPTR_FORMAT, entry_point);
a61af66fc99e Initial load
duke
parents:
diff changeset
1458 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1459 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1460 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1461 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1462
a61af66fc99e Initial load
duke
parents:
diff changeset
1463 IRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1464
a61af66fc99e Initial load
duke
parents:
diff changeset
1465
a61af66fc99e Initial load
duke
parents:
diff changeset
1466 // same as JVM_Arraycopy, but called directly from compiled code
a61af66fc99e Initial load
duke
parents:
diff changeset
1467 JRT_ENTRY(void, SharedRuntime::slow_arraycopy_C(oopDesc* src, jint src_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
1468 oopDesc* dest, jint dest_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
1469 jint length,
a61af66fc99e Initial load
duke
parents:
diff changeset
1470 JavaThread* thread)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1471 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1472 _slow_array_copy_ctr++;
a61af66fc99e Initial load
duke
parents:
diff changeset
1473 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1474 // Check if we have null pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
1475 if (src == NULL || dest == NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1476 THROW(vmSymbols::java_lang_NullPointerException());
a61af66fc99e Initial load
duke
parents:
diff changeset
1477 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1478 // Do the copy. The casts to arrayOop are necessary to the copy_array API,
a61af66fc99e Initial load
duke
parents:
diff changeset
1479 // even though the copy_array API also performs dynamic checks to ensure
a61af66fc99e Initial load
duke
parents:
diff changeset
1480 // that src and dest are truly arrays (and are conformable).
a61af66fc99e Initial load
duke
parents:
diff changeset
1481 // The copy_array mechanism is awkward and could be removed, but
a61af66fc99e Initial load
duke
parents:
diff changeset
1482 // the compilers don't call this function except as a last resort,
a61af66fc99e Initial load
duke
parents:
diff changeset
1483 // so it probably doesn't matter.
a61af66fc99e Initial load
duke
parents:
diff changeset
1484 Klass::cast(src->klass())->copy_array((arrayOopDesc*)src, src_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
1485 (arrayOopDesc*)dest, dest_pos,
a61af66fc99e Initial load
duke
parents:
diff changeset
1486 length, thread);
a61af66fc99e Initial load
duke
parents:
diff changeset
1487 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1488 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1489
a61af66fc99e Initial load
duke
parents:
diff changeset
1490 char* SharedRuntime::generate_class_cast_message(
a61af66fc99e Initial load
duke
parents:
diff changeset
1491 JavaThread* thread, const char* objName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1492
a61af66fc99e Initial load
duke
parents:
diff changeset
1493 // Get target class name from the checkcast instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
1494 vframeStream vfst(thread, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1495 assert(!vfst.at_end(), "Java frame must exist");
a61af66fc99e Initial load
duke
parents:
diff changeset
1496 Bytecode_checkcast* cc = Bytecode_checkcast_at(
a61af66fc99e Initial load
duke
parents:
diff changeset
1497 vfst.method()->bcp_from(vfst.bci()));
a61af66fc99e Initial load
duke
parents:
diff changeset
1498 Klass* targetKlass = Klass::cast(vfst.method()->constants()->klass_at(
a61af66fc99e Initial load
duke
parents:
diff changeset
1499 cc->index(), thread));
a61af66fc99e Initial load
duke
parents:
diff changeset
1500 return generate_class_cast_message(objName, targetKlass->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
1501 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1502
a61af66fc99e Initial load
duke
parents:
diff changeset
1503 char* SharedRuntime::generate_class_cast_message(
a61af66fc99e Initial load
duke
parents:
diff changeset
1504 const char* objName, const char* targetKlassName) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1505 const char* desc = " cannot be cast to ";
a61af66fc99e Initial load
duke
parents:
diff changeset
1506 size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1507
53
9785f6d2dd97 6631248: Memory problem when doing invalid type cast
kamg
parents: 0
diff changeset
1508 char* message = NEW_RESOURCE_ARRAY(char, msglen);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1509 if (NULL == message) {
53
9785f6d2dd97 6631248: Memory problem when doing invalid type cast
kamg
parents: 0
diff changeset
1510 // Shouldn't happen, but don't cause even more problems if it does
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1511 message = const_cast<char*>(objName);
a61af66fc99e Initial load
duke
parents:
diff changeset
1512 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1513 jio_snprintf(message, msglen, "%s%s%s", objName, desc, targetKlassName);
a61af66fc99e Initial load
duke
parents:
diff changeset
1514 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1515 return message;
a61af66fc99e Initial load
duke
parents:
diff changeset
1516 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1517
a61af66fc99e Initial load
duke
parents:
diff changeset
1518 JRT_LEAF(void, SharedRuntime::reguard_yellow_pages())
a61af66fc99e Initial load
duke
parents:
diff changeset
1519 (void) JavaThread::current()->reguard_stack();
a61af66fc99e Initial load
duke
parents:
diff changeset
1520 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1521
a61af66fc99e Initial load
duke
parents:
diff changeset
1522
a61af66fc99e Initial load
duke
parents:
diff changeset
1523 // Handles the uncommon case in locking, i.e., contention or an inflated lock.
a61af66fc99e Initial load
duke
parents:
diff changeset
1524 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1525 int SharedRuntime::_monitor_enter_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1526 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1527 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::complete_monitor_locking_C(oopDesc* _obj, BasicLock* lock, JavaThread* thread))
a61af66fc99e Initial load
duke
parents:
diff changeset
1528 oop obj(_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1529 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1530 _monitor_enter_ctr++; // monitor enter slow
a61af66fc99e Initial load
duke
parents:
diff changeset
1531 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1532 if (PrintBiasedLockingStatistics) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1533 Atomic::inc(BiasedLocking::slow_path_entry_count_addr());
a61af66fc99e Initial load
duke
parents:
diff changeset
1534 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1535 Handle h_obj(THREAD, obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1536 if (UseBiasedLocking) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1537 // Retry fast entry if bias is revoked to avoid unnecessary inflation
a61af66fc99e Initial load
duke
parents:
diff changeset
1538 ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1539 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1540 ObjectSynchronizer::slow_enter(h_obj, lock, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1541 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1542 assert(!HAS_PENDING_EXCEPTION, "Should have no exception here");
a61af66fc99e Initial load
duke
parents:
diff changeset
1543 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1544
a61af66fc99e Initial load
duke
parents:
diff changeset
1545 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1546 int SharedRuntime::_monitor_exit_ctr=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1547 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1548 // Handles the uncommon cases of monitor unlocking in compiled code
a61af66fc99e Initial load
duke
parents:
diff changeset
1549 JRT_LEAF(void, SharedRuntime::complete_monitor_unlocking_C(oopDesc* _obj, BasicLock* lock))
a61af66fc99e Initial load
duke
parents:
diff changeset
1550 oop obj(_obj);
a61af66fc99e Initial load
duke
parents:
diff changeset
1551 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1552 _monitor_exit_ctr++; // monitor exit slow
a61af66fc99e Initial load
duke
parents:
diff changeset
1553 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1554 Thread* THREAD = JavaThread::current();
a61af66fc99e Initial load
duke
parents:
diff changeset
1555 // I'm not convinced we need the code contained by MIGHT_HAVE_PENDING anymore
a61af66fc99e Initial load
duke
parents:
diff changeset
1556 // testing was unable to ever fire the assert that guarded it so I have removed it.
a61af66fc99e Initial load
duke
parents:
diff changeset
1557 assert(!HAS_PENDING_EXCEPTION, "Do we need code below anymore?");
a61af66fc99e Initial load
duke
parents:
diff changeset
1558 #undef MIGHT_HAVE_PENDING
a61af66fc99e Initial load
duke
parents:
diff changeset
1559 #ifdef MIGHT_HAVE_PENDING
a61af66fc99e Initial load
duke
parents:
diff changeset
1560 // Save and restore any pending_exception around the exception mark.
a61af66fc99e Initial load
duke
parents:
diff changeset
1561 // While the slow_exit must not throw an exception, we could come into
a61af66fc99e Initial load
duke
parents:
diff changeset
1562 // this routine with one set.
a61af66fc99e Initial load
duke
parents:
diff changeset
1563 oop pending_excep = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1564 const char* pending_file;
a61af66fc99e Initial load
duke
parents:
diff changeset
1565 int pending_line;
a61af66fc99e Initial load
duke
parents:
diff changeset
1566 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1567 pending_excep = PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
1568 pending_file = THREAD->exception_file();
a61af66fc99e Initial load
duke
parents:
diff changeset
1569 pending_line = THREAD->exception_line();
a61af66fc99e Initial load
duke
parents:
diff changeset
1570 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
1571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1572 #endif /* MIGHT_HAVE_PENDING */
a61af66fc99e Initial load
duke
parents:
diff changeset
1573
a61af66fc99e Initial load
duke
parents:
diff changeset
1574 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1575 // Exit must be non-blocking, and therefore no exceptions can be thrown.
a61af66fc99e Initial load
duke
parents:
diff changeset
1576 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
1577 ObjectSynchronizer::slow_exit(obj, lock, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1578 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1579
a61af66fc99e Initial load
duke
parents:
diff changeset
1580 #ifdef MIGHT_HAVE_PENDING
a61af66fc99e Initial load
duke
parents:
diff changeset
1581 if (pending_excep != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1582 THREAD->set_pending_exception(pending_excep, pending_file, pending_line);
a61af66fc99e Initial load
duke
parents:
diff changeset
1583 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1584 #endif /* MIGHT_HAVE_PENDING */
a61af66fc99e Initial load
duke
parents:
diff changeset
1585 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
1586
a61af66fc99e Initial load
duke
parents:
diff changeset
1587 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1588
a61af66fc99e Initial load
duke
parents:
diff changeset
1589 void SharedRuntime::print_statistics() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1590 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1591 if (xtty != NULL) xtty->head("statistics type='SharedRuntime'");
a61af66fc99e Initial load
duke
parents:
diff changeset
1592
a61af66fc99e Initial load
duke
parents:
diff changeset
1593 if (_monitor_enter_ctr ) tty->print_cr("%5d monitor enter slow", _monitor_enter_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1594 if (_monitor_exit_ctr ) tty->print_cr("%5d monitor exit slow", _monitor_exit_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1595 if (_throw_null_ctr) tty->print_cr("%5d implicit null throw", _throw_null_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1596
a61af66fc99e Initial load
duke
parents:
diff changeset
1597 SharedRuntime::print_ic_miss_histogram();
a61af66fc99e Initial load
duke
parents:
diff changeset
1598
a61af66fc99e Initial load
duke
parents:
diff changeset
1599 if (CountRemovableExceptions) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1600 if (_nof_removable_exceptions > 0) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1601 Unimplemented(); // this counter is not yet incremented
a61af66fc99e Initial load
duke
parents:
diff changeset
1602 tty->print_cr("Removable exceptions: %d", _nof_removable_exceptions);
a61af66fc99e Initial load
duke
parents:
diff changeset
1603 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1604 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1605
a61af66fc99e Initial load
duke
parents:
diff changeset
1606 // Dump the JRT_ENTRY counters
a61af66fc99e Initial load
duke
parents:
diff changeset
1607 if( _new_instance_ctr ) tty->print_cr("%5d new instance requires GC", _new_instance_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1608 if( _new_array_ctr ) tty->print_cr("%5d new array requires GC", _new_array_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1609 if( _multi1_ctr ) tty->print_cr("%5d multianewarray 1 dim", _multi1_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1610 if( _multi2_ctr ) tty->print_cr("%5d multianewarray 2 dim", _multi2_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1611 if( _multi3_ctr ) tty->print_cr("%5d multianewarray 3 dim", _multi3_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1612 if( _multi4_ctr ) tty->print_cr("%5d multianewarray 4 dim", _multi4_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1613 if( _multi5_ctr ) tty->print_cr("%5d multianewarray 5 dim", _multi5_ctr);
a61af66fc99e Initial load
duke
parents:
diff changeset
1614
a61af66fc99e Initial load
duke
parents:
diff changeset
1615 tty->print_cr("%5d inline cache miss in compiled", _ic_miss_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1616 tty->print_cr("%5d wrong method", _wrong_method_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1617 tty->print_cr("%5d unresolved static call site", _resolve_static_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1618 tty->print_cr("%5d unresolved virtual call site", _resolve_virtual_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1619 tty->print_cr("%5d unresolved opt virtual call site", _resolve_opt_virtual_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1620
a61af66fc99e Initial load
duke
parents:
diff changeset
1621 if( _mon_enter_stub_ctr ) tty->print_cr("%5d monitor enter stub", _mon_enter_stub_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1622 if( _mon_exit_stub_ctr ) tty->print_cr("%5d monitor exit stub", _mon_exit_stub_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1623 if( _mon_enter_ctr ) tty->print_cr("%5d monitor enter slow", _mon_enter_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1624 if( _mon_exit_ctr ) tty->print_cr("%5d monitor exit slow", _mon_exit_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1625 if( _partial_subtype_ctr) tty->print_cr("%5d slow partial subtype", _partial_subtype_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1626 if( _jbyte_array_copy_ctr ) tty->print_cr("%5d byte array copies", _jbyte_array_copy_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1627 if( _jshort_array_copy_ctr ) tty->print_cr("%5d short array copies", _jshort_array_copy_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1628 if( _jint_array_copy_ctr ) tty->print_cr("%5d int array copies", _jint_array_copy_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1629 if( _jlong_array_copy_ctr ) tty->print_cr("%5d long array copies", _jlong_array_copy_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1630 if( _oop_array_copy_ctr ) tty->print_cr("%5d oop array copies", _oop_array_copy_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1631 if( _checkcast_array_copy_ctr ) tty->print_cr("%5d checkcast array copies", _checkcast_array_copy_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1632 if( _unsafe_array_copy_ctr ) tty->print_cr("%5d unsafe array copies", _unsafe_array_copy_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1633 if( _generic_array_copy_ctr ) tty->print_cr("%5d generic array copies", _generic_array_copy_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1634 if( _slow_array_copy_ctr ) tty->print_cr("%5d slow array copies", _slow_array_copy_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1635 if( _find_handler_ctr ) tty->print_cr("%5d find exception handler", _find_handler_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1636 if( _rethrow_ctr ) tty->print_cr("%5d rethrow handler", _rethrow_ctr );
a61af66fc99e Initial load
duke
parents:
diff changeset
1637
a61af66fc99e Initial load
duke
parents:
diff changeset
1638 if (xtty != NULL) xtty->tail("statistics");
a61af66fc99e Initial load
duke
parents:
diff changeset
1639 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1640
a61af66fc99e Initial load
duke
parents:
diff changeset
1641 inline double percent(int x, int y) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1642 return 100.0 * x / MAX2(y, 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1643 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1644
a61af66fc99e Initial load
duke
parents:
diff changeset
1645 class MethodArityHistogram {
a61af66fc99e Initial load
duke
parents:
diff changeset
1646 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1647 enum { MAX_ARITY = 256 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1648 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
1649 static int _arity_histogram[MAX_ARITY]; // histogram of #args
a61af66fc99e Initial load
duke
parents:
diff changeset
1650 static int _size_histogram[MAX_ARITY]; // histogram of arg size in words
a61af66fc99e Initial load
duke
parents:
diff changeset
1651 static int _max_arity; // max. arity seen
a61af66fc99e Initial load
duke
parents:
diff changeset
1652 static int _max_size; // max. arg size seen
a61af66fc99e Initial load
duke
parents:
diff changeset
1653
a61af66fc99e Initial load
duke
parents:
diff changeset
1654 static void add_method_to_histogram(nmethod* nm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1655 methodOop m = nm->method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1656 ArgumentCount args(m->signature());
a61af66fc99e Initial load
duke
parents:
diff changeset
1657 int arity = args.size() + (m->is_static() ? 0 : 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1658 int argsize = m->size_of_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
1659 arity = MIN2(arity, MAX_ARITY-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1660 argsize = MIN2(argsize, MAX_ARITY-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
1661 int count = nm->method()->compiled_invocation_count();
a61af66fc99e Initial load
duke
parents:
diff changeset
1662 _arity_histogram[arity] += count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1663 _size_histogram[argsize] += count;
a61af66fc99e Initial load
duke
parents:
diff changeset
1664 _max_arity = MAX2(_max_arity, arity);
a61af66fc99e Initial load
duke
parents:
diff changeset
1665 _max_size = MAX2(_max_size, argsize);
a61af66fc99e Initial load
duke
parents:
diff changeset
1666 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1667
a61af66fc99e Initial load
duke
parents:
diff changeset
1668 void print_histogram_helper(int n, int* histo, const char* name) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1669 const int N = MIN2(5, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1670 tty->print_cr("\nHistogram of call arity (incl. rcvr, calls to compiled methods only):");
a61af66fc99e Initial load
duke
parents:
diff changeset
1671 double sum = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1672 double weighted_sum = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1673 int i;
a61af66fc99e Initial load
duke
parents:
diff changeset
1674 for (i = 0; i <= n; i++) { sum += histo[i]; weighted_sum += i*histo[i]; }
a61af66fc99e Initial load
duke
parents:
diff changeset
1675 double rest = sum;
a61af66fc99e Initial load
duke
parents:
diff changeset
1676 double percent = sum / 100;
a61af66fc99e Initial load
duke
parents:
diff changeset
1677 for (i = 0; i <= N; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1678 rest -= histo[i];
a61af66fc99e Initial load
duke
parents:
diff changeset
1679 tty->print_cr("%4d: %7d (%5.1f%%)", i, histo[i], histo[i] / percent);
a61af66fc99e Initial load
duke
parents:
diff changeset
1680 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1681 tty->print_cr("rest: %7d (%5.1f%%))", (int)rest, rest / percent);
a61af66fc99e Initial load
duke
parents:
diff changeset
1682 tty->print_cr("(avg. %s = %3.1f, max = %d)", name, weighted_sum / sum, n);
a61af66fc99e Initial load
duke
parents:
diff changeset
1683 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1684
a61af66fc99e Initial load
duke
parents:
diff changeset
1685 void print_histogram() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1686 tty->print_cr("\nHistogram of call arity (incl. rcvr, calls to compiled methods only):");
a61af66fc99e Initial load
duke
parents:
diff changeset
1687 print_histogram_helper(_max_arity, _arity_histogram, "arity");
a61af66fc99e Initial load
duke
parents:
diff changeset
1688 tty->print_cr("\nSame for parameter size (in words):");
a61af66fc99e Initial load
duke
parents:
diff changeset
1689 print_histogram_helper(_max_size, _size_histogram, "size");
a61af66fc99e Initial load
duke
parents:
diff changeset
1690 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1691 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1692
a61af66fc99e Initial load
duke
parents:
diff changeset
1693 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
1694 MethodArityHistogram() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1695 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
a61af66fc99e Initial load
duke
parents:
diff changeset
1696 _max_arity = _max_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1697 for (int i = 0; i < MAX_ARITY; i++) _arity_histogram[i] = _size_histogram [i] = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1698 CodeCache::nmethods_do(add_method_to_histogram);
a61af66fc99e Initial load
duke
parents:
diff changeset
1699 print_histogram();
a61af66fc99e Initial load
duke
parents:
diff changeset
1700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1701 };
a61af66fc99e Initial load
duke
parents:
diff changeset
1702
a61af66fc99e Initial load
duke
parents:
diff changeset
1703 int MethodArityHistogram::_arity_histogram[MethodArityHistogram::MAX_ARITY];
a61af66fc99e Initial load
duke
parents:
diff changeset
1704 int MethodArityHistogram::_size_histogram[MethodArityHistogram::MAX_ARITY];
a61af66fc99e Initial load
duke
parents:
diff changeset
1705 int MethodArityHistogram::_max_arity;
a61af66fc99e Initial load
duke
parents:
diff changeset
1706 int MethodArityHistogram::_max_size;
a61af66fc99e Initial load
duke
parents:
diff changeset
1707
a61af66fc99e Initial load
duke
parents:
diff changeset
1708 void SharedRuntime::print_call_statistics(int comp_total) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1709 tty->print_cr("Calls from compiled code:");
a61af66fc99e Initial load
duke
parents:
diff changeset
1710 int total = _nof_normal_calls + _nof_interface_calls + _nof_static_calls;
a61af66fc99e Initial load
duke
parents:
diff changeset
1711 int mono_c = _nof_normal_calls - _nof_optimized_calls - _nof_megamorphic_calls;
a61af66fc99e Initial load
duke
parents:
diff changeset
1712 int mono_i = _nof_interface_calls - _nof_optimized_interface_calls - _nof_megamorphic_interface_calls;
a61af66fc99e Initial load
duke
parents:
diff changeset
1713 tty->print_cr("\t%9d (%4.1f%%) total non-inlined ", total, percent(total, total));
a61af66fc99e Initial load
duke
parents:
diff changeset
1714 tty->print_cr("\t%9d (%4.1f%%) virtual calls ", _nof_normal_calls, percent(_nof_normal_calls, total));
a61af66fc99e Initial load
duke
parents:
diff changeset
1715 tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_calls, percent(_nof_inlined_calls, _nof_normal_calls));
a61af66fc99e Initial load
duke
parents:
diff changeset
1716 tty->print_cr("\t %9d (%3.0f%%) optimized ", _nof_optimized_calls, percent(_nof_optimized_calls, _nof_normal_calls));
a61af66fc99e Initial load
duke
parents:
diff changeset
1717 tty->print_cr("\t %9d (%3.0f%%) monomorphic ", mono_c, percent(mono_c, _nof_normal_calls));
a61af66fc99e Initial load
duke
parents:
diff changeset
1718 tty->print_cr("\t %9d (%3.0f%%) megamorphic ", _nof_megamorphic_calls, percent(_nof_megamorphic_calls, _nof_normal_calls));
a61af66fc99e Initial load
duke
parents:
diff changeset
1719 tty->print_cr("\t%9d (%4.1f%%) interface calls ", _nof_interface_calls, percent(_nof_interface_calls, total));
a61af66fc99e Initial load
duke
parents:
diff changeset
1720 tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_interface_calls, percent(_nof_inlined_interface_calls, _nof_interface_calls));
a61af66fc99e Initial load
duke
parents:
diff changeset
1721 tty->print_cr("\t %9d (%3.0f%%) optimized ", _nof_optimized_interface_calls, percent(_nof_optimized_interface_calls, _nof_interface_calls));
a61af66fc99e Initial load
duke
parents:
diff changeset
1722 tty->print_cr("\t %9d (%3.0f%%) monomorphic ", mono_i, percent(mono_i, _nof_interface_calls));
a61af66fc99e Initial load
duke
parents:
diff changeset
1723 tty->print_cr("\t %9d (%3.0f%%) megamorphic ", _nof_megamorphic_interface_calls, percent(_nof_megamorphic_interface_calls, _nof_interface_calls));
a61af66fc99e Initial load
duke
parents:
diff changeset
1724 tty->print_cr("\t%9d (%4.1f%%) static/special calls", _nof_static_calls, percent(_nof_static_calls, total));
a61af66fc99e Initial load
duke
parents:
diff changeset
1725 tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_static_calls, percent(_nof_inlined_static_calls, _nof_static_calls));
a61af66fc99e Initial load
duke
parents:
diff changeset
1726 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1727 tty->print_cr("Note 1: counter updates are not MT-safe.");
a61af66fc99e Initial load
duke
parents:
diff changeset
1728 tty->print_cr("Note 2: %% in major categories are relative to total non-inlined calls;");
a61af66fc99e Initial load
duke
parents:
diff changeset
1729 tty->print_cr(" %% in nested categories are relative to their category");
a61af66fc99e Initial load
duke
parents:
diff changeset
1730 tty->print_cr(" (and thus add up to more than 100%% with inlining)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1731 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1732
a61af66fc99e Initial load
duke
parents:
diff changeset
1733 MethodArityHistogram h;
a61af66fc99e Initial load
duke
parents:
diff changeset
1734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1735 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1736
a61af66fc99e Initial load
duke
parents:
diff changeset
1737
a61af66fc99e Initial load
duke
parents:
diff changeset
1738 // ---------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1739 // Implementation of AdapterHandlerLibrary
a61af66fc99e Initial load
duke
parents:
diff changeset
1740 const char* AdapterHandlerEntry::name = "I2C/C2I adapters";
a61af66fc99e Initial load
duke
parents:
diff changeset
1741 GrowableArray<uint64_t>* AdapterHandlerLibrary::_fingerprints = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1742 GrowableArray<AdapterHandlerEntry* >* AdapterHandlerLibrary::_handlers = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1743 const int AdapterHandlerLibrary_size = 16*K;
a61af66fc99e Initial load
duke
parents:
diff changeset
1744 u_char AdapterHandlerLibrary::_buffer[AdapterHandlerLibrary_size + 32];
a61af66fc99e Initial load
duke
parents:
diff changeset
1745
a61af66fc99e Initial load
duke
parents:
diff changeset
1746 void AdapterHandlerLibrary::initialize() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1747 if (_fingerprints != NULL) return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1748 _fingerprints = new(ResourceObj::C_HEAP)GrowableArray<uint64_t>(32, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1749 _handlers = new(ResourceObj::C_HEAP)GrowableArray<AdapterHandlerEntry*>(32, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
1750 // Index 0 reserved for the slow path handler
a61af66fc99e Initial load
duke
parents:
diff changeset
1751 _fingerprints->append(0/*the never-allowed 0 fingerprint*/);
a61af66fc99e Initial load
duke
parents:
diff changeset
1752 _handlers->append(NULL);
a61af66fc99e Initial load
duke
parents:
diff changeset
1753
a61af66fc99e Initial load
duke
parents:
diff changeset
1754 // Create a special handler for abstract methods. Abstract methods
a61af66fc99e Initial load
duke
parents:
diff changeset
1755 // are never compiled so an i2c entry is somewhat meaningless, but
a61af66fc99e Initial load
duke
parents:
diff changeset
1756 // fill it in with something appropriate just in case. Pass handle
a61af66fc99e Initial load
duke
parents:
diff changeset
1757 // wrong method for the c2i transitions.
a61af66fc99e Initial load
duke
parents:
diff changeset
1758 address wrong_method = SharedRuntime::get_handle_wrong_method_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
1759 _fingerprints->append(0/*the never-allowed 0 fingerprint*/);
a61af66fc99e Initial load
duke
parents:
diff changeset
1760 assert(_handlers->length() == AbstractMethodHandler, "in wrong slot");
a61af66fc99e Initial load
duke
parents:
diff changeset
1761 _handlers->append(new AdapterHandlerEntry(StubRoutines::throw_AbstractMethodError_entry(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1762 wrong_method, wrong_method));
a61af66fc99e Initial load
duke
parents:
diff changeset
1763 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1764
a61af66fc99e Initial load
duke
parents:
diff changeset
1765 int AdapterHandlerLibrary::get_create_adapter_index(methodHandle method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1766 // Use customized signature handler. Need to lock around updates to the
a61af66fc99e Initial load
duke
parents:
diff changeset
1767 // _fingerprints array (it is not safe for concurrent readers and a single
a61af66fc99e Initial load
duke
parents:
diff changeset
1768 // writer: this can be fixed if it becomes a problem).
a61af66fc99e Initial load
duke
parents:
diff changeset
1769
a61af66fc99e Initial load
duke
parents:
diff changeset
1770 // Get the address of the ic_miss handlers before we grab the
a61af66fc99e Initial load
duke
parents:
diff changeset
1771 // AdapterHandlerLibrary_lock. This fixes bug 6236259 which
a61af66fc99e Initial load
duke
parents:
diff changeset
1772 // was caused by the initialization of the stubs happening
a61af66fc99e Initial load
duke
parents:
diff changeset
1773 // while we held the lock and then notifying jvmti while
a61af66fc99e Initial load
duke
parents:
diff changeset
1774 // holding it. This just forces the initialization to be a little
a61af66fc99e Initial load
duke
parents:
diff changeset
1775 // earlier.
a61af66fc99e Initial load
duke
parents:
diff changeset
1776 address ic_miss = SharedRuntime::get_ic_miss_stub();
a61af66fc99e Initial load
duke
parents:
diff changeset
1777 assert(ic_miss != NULL, "must have handler");
a61af66fc99e Initial load
duke
parents:
diff changeset
1778
a61af66fc99e Initial load
duke
parents:
diff changeset
1779 int result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1780 BufferBlob *B = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1781 uint64_t fingerprint;
a61af66fc99e Initial load
duke
parents:
diff changeset
1782 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1783 MutexLocker mu(AdapterHandlerLibrary_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1784 // make sure data structure is initialized
a61af66fc99e Initial load
duke
parents:
diff changeset
1785 initialize();
a61af66fc99e Initial load
duke
parents:
diff changeset
1786
a61af66fc99e Initial load
duke
parents:
diff changeset
1787 if (method->is_abstract()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1788 return AbstractMethodHandler;
a61af66fc99e Initial load
duke
parents:
diff changeset
1789 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1790
a61af66fc99e Initial load
duke
parents:
diff changeset
1791 // Lookup method signature's fingerprint
a61af66fc99e Initial load
duke
parents:
diff changeset
1792 fingerprint = Fingerprinter(method).fingerprint();
a61af66fc99e Initial load
duke
parents:
diff changeset
1793 assert( fingerprint != CONST64( 0), "no zero fingerprints allowed" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1794 // Fingerprints are small fixed-size condensed representations of
a61af66fc99e Initial load
duke
parents:
diff changeset
1795 // signatures. If the signature is too large, it won't fit in a
a61af66fc99e Initial load
duke
parents:
diff changeset
1796 // fingerprint. Signatures which cannot support a fingerprint get a new i2c
a61af66fc99e Initial load
duke
parents:
diff changeset
1797 // adapter gen'd each time, instead of searching the cache for one. This -1
a61af66fc99e Initial load
duke
parents:
diff changeset
1798 // game can be avoided if I compared signatures instead of using
a61af66fc99e Initial load
duke
parents:
diff changeset
1799 // fingerprints. However, -1 fingerprints are very rare.
a61af66fc99e Initial load
duke
parents:
diff changeset
1800 if( fingerprint != UCONST64(-1) ) { // If this is a cache-able fingerprint
a61af66fc99e Initial load
duke
parents:
diff changeset
1801 // Turns out i2c adapters do not care what the return value is. Mask it
a61af66fc99e Initial load
duke
parents:
diff changeset
1802 // out so signatures that only differ in return type will share the same
a61af66fc99e Initial load
duke
parents:
diff changeset
1803 // adapter.
a61af66fc99e Initial load
duke
parents:
diff changeset
1804 fingerprint &= ~(SignatureIterator::result_feature_mask << SignatureIterator::static_feature_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1805 // Search for a prior existing i2c/c2i adapter
a61af66fc99e Initial load
duke
parents:
diff changeset
1806 int index = _fingerprints->find(fingerprint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1807 if( index >= 0 ) return index; // Found existing handlers?
a61af66fc99e Initial load
duke
parents:
diff changeset
1808 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1809 // Annoyingly, I end up adding -1 fingerprints to the array of handlers,
a61af66fc99e Initial load
duke
parents:
diff changeset
1810 // because I need a unique handler index. It cannot be scanned for
a61af66fc99e Initial load
duke
parents:
diff changeset
1811 // because all -1's look alike. Instead, the matching index is passed out
a61af66fc99e Initial load
duke
parents:
diff changeset
1812 // and immediately used to collect the 2 return values (the c2i and i2c
a61af66fc99e Initial load
duke
parents:
diff changeset
1813 // adapters).
a61af66fc99e Initial load
duke
parents:
diff changeset
1814 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1815
a61af66fc99e Initial load
duke
parents:
diff changeset
1816 // Create I2C & C2I handlers
a61af66fc99e Initial load
duke
parents:
diff changeset
1817 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1818 // Improve alignment slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
1819 u_char *buf = (u_char*)(((intptr_t)_buffer + CodeEntryAlignment-1) & ~(CodeEntryAlignment-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1820 CodeBuffer buffer(buf, AdapterHandlerLibrary_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1821 short buffer_locs[20];
a61af66fc99e Initial load
duke
parents:
diff changeset
1822 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs,
a61af66fc99e Initial load
duke
parents:
diff changeset
1823 sizeof(buffer_locs)/sizeof(relocInfo));
a61af66fc99e Initial load
duke
parents:
diff changeset
1824 MacroAssembler _masm(&buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
1825
a61af66fc99e Initial load
duke
parents:
diff changeset
1826 // Fill in the signature array, for the calling-convention call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1827 int total_args_passed = method->size_of_parameters(); // All args on stack
a61af66fc99e Initial load
duke
parents:
diff changeset
1828
a61af66fc99e Initial load
duke
parents:
diff changeset
1829 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1830 VMRegPair * regs = NEW_RESOURCE_ARRAY(VMRegPair ,total_args_passed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1831 int i=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1832 if( !method->is_static() ) // Pass in receiver first
a61af66fc99e Initial load
duke
parents:
diff changeset
1833 sig_bt[i++] = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1834 for( SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1835 sig_bt[i++] = ss.type(); // Collect remaining bits of signature
a61af66fc99e Initial load
duke
parents:
diff changeset
1836 if( ss.type() == T_LONG || ss.type() == T_DOUBLE )
a61af66fc99e Initial load
duke
parents:
diff changeset
1837 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots
a61af66fc99e Initial load
duke
parents:
diff changeset
1838 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1839 assert( i==total_args_passed, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1840
a61af66fc99e Initial load
duke
parents:
diff changeset
1841 // Now get the re-packed compiled-Java layout.
a61af66fc99e Initial load
duke
parents:
diff changeset
1842 int comp_args_on_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1843
a61af66fc99e Initial load
duke
parents:
diff changeset
1844 // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage
a61af66fc99e Initial load
duke
parents:
diff changeset
1845 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1846
a61af66fc99e Initial load
duke
parents:
diff changeset
1847 AdapterHandlerEntry* entry = SharedRuntime::generate_i2c2i_adapters(&_masm,
a61af66fc99e Initial load
duke
parents:
diff changeset
1848 total_args_passed,
a61af66fc99e Initial load
duke
parents:
diff changeset
1849 comp_args_on_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1850 sig_bt,
a61af66fc99e Initial load
duke
parents:
diff changeset
1851 regs);
a61af66fc99e Initial load
duke
parents:
diff changeset
1852
a61af66fc99e Initial load
duke
parents:
diff changeset
1853 B = BufferBlob::create(AdapterHandlerEntry::name, &buffer);
28
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1854 if (B == NULL) {
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1855 // CodeCache is full, disable compilation
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1856 // Ought to log this but compile log is only per compile thread
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1857 // and we're some non descript Java thread.
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1858 UseInterpreter = true;
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1859 if (UseCompiler || AlwaysCompileLoopMethods ) {
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1860 #ifndef PRODUCT
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1861 warning("CodeCache is full. Compiler has been disabled");
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1862 if (CompileTheWorld || ExitOnFullCodeCache) {
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1863 before_exit(JavaThread::current());
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1864 exit_globals(); // will delete tty
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1865 vm_direct_exit(CompileTheWorld ? 0 : 1);
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1866 }
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1867 #endif
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1868 UseCompiler = false;
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1869 AlwaysCompileLoopMethods = false;
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1870 }
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1871 return 0; // Out of CodeCache space (_handlers[0] == NULL)
67914967a4b5 6650373: Assert in methodOopDesc::make_adapters()
kvn
parents: 16
diff changeset
1872 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1873 entry->relocate(B->instructions_begin());
a61af66fc99e Initial load
duke
parents:
diff changeset
1874 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1875 // debugging suppport
a61af66fc99e Initial load
duke
parents:
diff changeset
1876 if (PrintAdapterHandlers) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1877 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1878 tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = 0x%llx, %d bytes generated)",
a61af66fc99e Initial load
duke
parents:
diff changeset
1879 _handlers->length(), (method->is_static() ? "static" : "receiver"),
a61af66fc99e Initial load
duke
parents:
diff changeset
1880 method->signature()->as_C_string(), fingerprint, buffer.code_size() );
a61af66fc99e Initial load
duke
parents:
diff changeset
1881 tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
1882 Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + buffer.code_size());
a61af66fc99e Initial load
duke
parents:
diff changeset
1883 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1884 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
1885
a61af66fc99e Initial load
duke
parents:
diff changeset
1886 // add handlers to library
a61af66fc99e Initial load
duke
parents:
diff changeset
1887 _fingerprints->append(fingerprint);
a61af66fc99e Initial load
duke
parents:
diff changeset
1888 _handlers->append(entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
1889 // set handler index
a61af66fc99e Initial load
duke
parents:
diff changeset
1890 assert(_fingerprints->length() == _handlers->length(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
1891 result = _fingerprints->length() - 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
1892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1893 // Outside of the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1894 if (B != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1895 char blob_id[256];
a61af66fc99e Initial load
duke
parents:
diff changeset
1896 jio_snprintf(blob_id,
a61af66fc99e Initial load
duke
parents:
diff changeset
1897 sizeof(blob_id),
a61af66fc99e Initial load
duke
parents:
diff changeset
1898 "%s(" PTR64_FORMAT ")@" PTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
1899 AdapterHandlerEntry::name,
a61af66fc99e Initial load
duke
parents:
diff changeset
1900 fingerprint,
a61af66fc99e Initial load
duke
parents:
diff changeset
1901 B->instructions_begin());
a61af66fc99e Initial load
duke
parents:
diff changeset
1902 VTune::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
a61af66fc99e Initial load
duke
parents:
diff changeset
1903 Forte::register_stub(blob_id, B->instructions_begin(), B->instructions_end());
a61af66fc99e Initial load
duke
parents:
diff changeset
1904
a61af66fc99e Initial load
duke
parents:
diff changeset
1905 if (JvmtiExport::should_post_dynamic_code_generated()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1906 JvmtiExport::post_dynamic_code_generated(blob_id,
a61af66fc99e Initial load
duke
parents:
diff changeset
1907 B->instructions_begin(),
a61af66fc99e Initial load
duke
parents:
diff changeset
1908 B->instructions_end());
a61af66fc99e Initial load
duke
parents:
diff changeset
1909 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1910 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1911 return result;
a61af66fc99e Initial load
duke
parents:
diff changeset
1912 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1913
a61af66fc99e Initial load
duke
parents:
diff changeset
1914 void AdapterHandlerEntry::relocate(address new_base) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1915 ptrdiff_t delta = new_base - _i2c_entry;
a61af66fc99e Initial load
duke
parents:
diff changeset
1916 _i2c_entry += delta;
a61af66fc99e Initial load
duke
parents:
diff changeset
1917 _c2i_entry += delta;
a61af66fc99e Initial load
duke
parents:
diff changeset
1918 _c2i_unverified_entry += delta;
a61af66fc99e Initial load
duke
parents:
diff changeset
1919 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1920
a61af66fc99e Initial load
duke
parents:
diff changeset
1921 // Create a native wrapper for this native method. The wrapper converts the
a61af66fc99e Initial load
duke
parents:
diff changeset
1922 // java compiled calling convention to the native convention, handlizes
a61af66fc99e Initial load
duke
parents:
diff changeset
1923 // arguments, and transitions to native. On return from the native we transition
a61af66fc99e Initial load
duke
parents:
diff changeset
1924 // back to java blocking if a safepoint is in progress.
a61af66fc99e Initial load
duke
parents:
diff changeset
1925 nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1926 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1927 nmethod* nm = NULL;
a61af66fc99e Initial load
duke
parents:
diff changeset
1928
a61af66fc99e Initial load
duke
parents:
diff changeset
1929 if (PrintCompilation) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1930 ttyLocker ttyl;
a61af66fc99e Initial load
duke
parents:
diff changeset
1931 tty->print("--- n%s ", (method->is_synchronized() ? "s" : " "));
a61af66fc99e Initial load
duke
parents:
diff changeset
1932 method->print_short_name(tty);
a61af66fc99e Initial load
duke
parents:
diff changeset
1933 if (method->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1934 tty->print(" (static)");
a61af66fc99e Initial load
duke
parents:
diff changeset
1935 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1936 tty->cr();
a61af66fc99e Initial load
duke
parents:
diff changeset
1937 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1938
a61af66fc99e Initial load
duke
parents:
diff changeset
1939 assert(method->has_native_function(), "must have something valid to call!");
a61af66fc99e Initial load
duke
parents:
diff changeset
1940
a61af66fc99e Initial load
duke
parents:
diff changeset
1941 {
a61af66fc99e Initial load
duke
parents:
diff changeset
1942 // perform the work while holding the lock, but perform any printing outside the lock
a61af66fc99e Initial load
duke
parents:
diff changeset
1943 MutexLocker mu(AdapterHandlerLibrary_lock);
a61af66fc99e Initial load
duke
parents:
diff changeset
1944 // See if somebody beat us to it
a61af66fc99e Initial load
duke
parents:
diff changeset
1945 nm = method->code();
a61af66fc99e Initial load
duke
parents:
diff changeset
1946 if (nm) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1947 return nm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1948 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1949
a61af66fc99e Initial load
duke
parents:
diff changeset
1950 // Improve alignment slightly
a61af66fc99e Initial load
duke
parents:
diff changeset
1951 u_char* buf = (u_char*)(((intptr_t)_buffer + CodeEntryAlignment-1) & ~(CodeEntryAlignment-1));
a61af66fc99e Initial load
duke
parents:
diff changeset
1952 CodeBuffer buffer(buf, AdapterHandlerLibrary_size);
a61af66fc99e Initial load
duke
parents:
diff changeset
1953 // Need a few relocation entries
a61af66fc99e Initial load
duke
parents:
diff changeset
1954 double locs_buf[20];
a61af66fc99e Initial load
duke
parents:
diff changeset
1955 buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
a61af66fc99e Initial load
duke
parents:
diff changeset
1956 MacroAssembler _masm(&buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
1957
a61af66fc99e Initial load
duke
parents:
diff changeset
1958 // Fill in the signature array, for the calling-convention call.
a61af66fc99e Initial load
duke
parents:
diff changeset
1959 int total_args_passed = method->size_of_parameters();
a61af66fc99e Initial load
duke
parents:
diff changeset
1960
a61af66fc99e Initial load
duke
parents:
diff changeset
1961 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1962 VMRegPair * regs = NEW_RESOURCE_ARRAY(VMRegPair ,total_args_passed);
a61af66fc99e Initial load
duke
parents:
diff changeset
1963 int i=0;
a61af66fc99e Initial load
duke
parents:
diff changeset
1964 if( !method->is_static() ) // Pass in receiver first
a61af66fc99e Initial load
duke
parents:
diff changeset
1965 sig_bt[i++] = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
1966 SignatureStream ss(method->signature());
a61af66fc99e Initial load
duke
parents:
diff changeset
1967 for( ; !ss.at_return_type(); ss.next()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1968 sig_bt[i++] = ss.type(); // Collect remaining bits of signature
a61af66fc99e Initial load
duke
parents:
diff changeset
1969 if( ss.type() == T_LONG || ss.type() == T_DOUBLE )
a61af66fc99e Initial load
duke
parents:
diff changeset
1970 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots
a61af66fc99e Initial load
duke
parents:
diff changeset
1971 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1972 assert( i==total_args_passed, "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
1973 BasicType ret_type = ss.type();
a61af66fc99e Initial load
duke
parents:
diff changeset
1974
a61af66fc99e Initial load
duke
parents:
diff changeset
1975 // Now get the compiled-Java layout as input arguments
a61af66fc99e Initial load
duke
parents:
diff changeset
1976 int comp_args_on_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
1977 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false);
a61af66fc99e Initial load
duke
parents:
diff changeset
1978
a61af66fc99e Initial load
duke
parents:
diff changeset
1979 // Generate the compiled-to-native wrapper code
a61af66fc99e Initial load
duke
parents:
diff changeset
1980 nm = SharedRuntime::generate_native_wrapper(&_masm,
a61af66fc99e Initial load
duke
parents:
diff changeset
1981 method,
a61af66fc99e Initial load
duke
parents:
diff changeset
1982 total_args_passed,
a61af66fc99e Initial load
duke
parents:
diff changeset
1983 comp_args_on_stack,
a61af66fc99e Initial load
duke
parents:
diff changeset
1984 sig_bt,regs,
a61af66fc99e Initial load
duke
parents:
diff changeset
1985 ret_type);
a61af66fc99e Initial load
duke
parents:
diff changeset
1986 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1987
a61af66fc99e Initial load
duke
parents:
diff changeset
1988 // Must unlock before calling set_code
a61af66fc99e Initial load
duke
parents:
diff changeset
1989 // Install the generated code.
a61af66fc99e Initial load
duke
parents:
diff changeset
1990 if (nm != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1991 method->set_code(method, nm);
a61af66fc99e Initial load
duke
parents:
diff changeset
1992 nm->post_compiled_method_load_event();
a61af66fc99e Initial load
duke
parents:
diff changeset
1993 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
1994 // CodeCache is full, disable compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
1995 // Ought to log this but compile log is only per compile thread
a61af66fc99e Initial load
duke
parents:
diff changeset
1996 // and we're some non descript Java thread.
a61af66fc99e Initial load
duke
parents:
diff changeset
1997 UseInterpreter = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
1998 if (UseCompiler || AlwaysCompileLoopMethods ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1999 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2000 warning("CodeCache is full. Compiler has been disabled");
a61af66fc99e Initial load
duke
parents:
diff changeset
2001 if (CompileTheWorld || ExitOnFullCodeCache) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2002 before_exit(JavaThread::current());
a61af66fc99e Initial load
duke
parents:
diff changeset
2003 exit_globals(); // will delete tty
a61af66fc99e Initial load
duke
parents:
diff changeset
2004 vm_direct_exit(CompileTheWorld ? 0 : 1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2005 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2006 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
2007 UseCompiler = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2008 AlwaysCompileLoopMethods = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2009 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2010 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2011 return nm;
a61af66fc99e Initial load
duke
parents:
diff changeset
2012 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2013
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2014 #ifdef HAVE_DTRACE_H
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2015 // Create a dtrace nmethod for this method. The wrapper converts the
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2016 // java compiled calling convention to the native convention, makes a dummy call
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2017 // (actually nops for the size of the call instruction, which become a trap if
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2018 // probe is enabled). The returns to the caller. Since this all looks like a
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2019 // leaf no thread transition is needed.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2020
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2021 nmethod *AdapterHandlerLibrary::create_dtrace_nmethod(methodHandle method) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2022 ResourceMark rm;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2023 nmethod* nm = NULL;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2024
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2025 if (PrintCompilation) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2026 ttyLocker ttyl;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2027 tty->print("--- n%s ");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2028 method->print_short_name(tty);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2029 if (method->is_static()) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2030 tty->print(" (static)");
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2031 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2032 tty->cr();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2033 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2034
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2035 {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2036 // perform the work while holding the lock, but perform any printing
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2037 // outside the lock
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2038 MutexLocker mu(AdapterHandlerLibrary_lock);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2039 // See if somebody beat us to it
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2040 nm = method->code();
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2041 if (nm) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2042 return nm;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2043 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2044
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2045 // Improve alignment slightly
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2046 u_char* buf = (u_char*)
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2047 (((intptr_t)_buffer + CodeEntryAlignment-1) & ~(CodeEntryAlignment-1));
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2048 CodeBuffer buffer(buf, AdapterHandlerLibrary_size);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2049 // Need a few relocation entries
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2050 double locs_buf[20];
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2051 buffer.insts()->initialize_shared_locs(
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2052 (relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo));
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2053 MacroAssembler _masm(&buffer);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2054
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2055 // Generate the compiled-to-native wrapper code
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2056 nm = SharedRuntime::generate_dtrace_nmethod(&_masm, method);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2057 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2058 return nm;
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2059 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2060
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2061 // the dtrace method needs to convert java lang string to utf8 string.
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2062 void SharedRuntime::get_utf(oopDesc* src, address dst) {
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2063 typeArrayOop jlsValue = java_lang_String::value(src);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2064 int jlsOffset = java_lang_String::offset(src);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2065 int jlsLen = java_lang_String::length(src);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2066 jchar* jlsPos = (jlsLen == 0) ? NULL :
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2067 jlsValue->char_at_addr(jlsOffset);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2068 (void) UNICODE::as_utf8(jlsPos, jlsLen, (char *)dst, max_dtrace_string_size);
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2069 }
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2070 #endif // ndef HAVE_DTRACE_H
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 62
diff changeset
2071
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2072 // -------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2073 // Java-Java calling convention
a61af66fc99e Initial load
duke
parents:
diff changeset
2074 // (what you use when Java calls Java)
a61af66fc99e Initial load
duke
parents:
diff changeset
2075
a61af66fc99e Initial load
duke
parents:
diff changeset
2076 //------------------------------name_for_receiver----------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
2077 // For a given signature, return the VMReg for parameter 0.
a61af66fc99e Initial load
duke
parents:
diff changeset
2078 VMReg SharedRuntime::name_for_receiver() {
a61af66fc99e Initial load
duke
parents:
diff changeset
2079 VMRegPair regs;
a61af66fc99e Initial load
duke
parents:
diff changeset
2080 BasicType sig_bt = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2081 (void) java_calling_convention(&sig_bt, &regs, 1, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2082 // Return argument 0 register. In the LP64 build pointers
a61af66fc99e Initial load
duke
parents:
diff changeset
2083 // take 2 registers, but the VM wants only the 'main' name.
a61af66fc99e Initial load
duke
parents:
diff changeset
2084 return regs.first();
a61af66fc99e Initial load
duke
parents:
diff changeset
2085 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2086
a61af66fc99e Initial load
duke
parents:
diff changeset
2087 VMRegPair *SharedRuntime::find_callee_arguments(symbolOop sig, bool is_static, int* arg_size) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2088 // This method is returning a data structure allocating as a
a61af66fc99e Initial load
duke
parents:
diff changeset
2089 // ResourceObject, so do not put any ResourceMarks in here.
a61af66fc99e Initial load
duke
parents:
diff changeset
2090 char *s = sig->as_C_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
2091 int len = (int)strlen(s);
a61af66fc99e Initial load
duke
parents:
diff changeset
2092 *s++; len--; // Skip opening paren
a61af66fc99e Initial load
duke
parents:
diff changeset
2093 char *t = s+len;
a61af66fc99e Initial load
duke
parents:
diff changeset
2094 while( *(--t) != ')' ) ; // Find close paren
a61af66fc99e Initial load
duke
parents:
diff changeset
2095
a61af66fc99e Initial load
duke
parents:
diff changeset
2096 BasicType *sig_bt = NEW_RESOURCE_ARRAY( BasicType, 256 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2097 VMRegPair *regs = NEW_RESOURCE_ARRAY( VMRegPair, 256 );
a61af66fc99e Initial load
duke
parents:
diff changeset
2098 int cnt = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2099 if (!is_static) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2100 sig_bt[cnt++] = T_OBJECT; // Receiver is argument 0; not in signature
a61af66fc99e Initial load
duke
parents:
diff changeset
2101 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2102
a61af66fc99e Initial load
duke
parents:
diff changeset
2103 while( s < t ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2104 switch( *s++ ) { // Switch on signature character
a61af66fc99e Initial load
duke
parents:
diff changeset
2105 case 'B': sig_bt[cnt++] = T_BYTE; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2106 case 'C': sig_bt[cnt++] = T_CHAR; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2107 case 'D': sig_bt[cnt++] = T_DOUBLE; sig_bt[cnt++] = T_VOID; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2108 case 'F': sig_bt[cnt++] = T_FLOAT; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2109 case 'I': sig_bt[cnt++] = T_INT; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2110 case 'J': sig_bt[cnt++] = T_LONG; sig_bt[cnt++] = T_VOID; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2111 case 'S': sig_bt[cnt++] = T_SHORT; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2112 case 'Z': sig_bt[cnt++] = T_BOOLEAN; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2113 case 'V': sig_bt[cnt++] = T_VOID; break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2114 case 'L': // Oop
a61af66fc99e Initial load
duke
parents:
diff changeset
2115 while( *s++ != ';' ) ; // Skip signature
a61af66fc99e Initial load
duke
parents:
diff changeset
2116 sig_bt[cnt++] = T_OBJECT;
a61af66fc99e Initial load
duke
parents:
diff changeset
2117 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2118 case '[': { // Array
a61af66fc99e Initial load
duke
parents:
diff changeset
2119 do { // Skip optional size
a61af66fc99e Initial load
duke
parents:
diff changeset
2120 while( *s >= '0' && *s <= '9' ) s++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2121 } while( *s++ == '[' ); // Nested arrays?
a61af66fc99e Initial load
duke
parents:
diff changeset
2122 // Skip element type
a61af66fc99e Initial load
duke
parents:
diff changeset
2123 if( s[-1] == 'L' )
a61af66fc99e Initial load
duke
parents:
diff changeset
2124 while( *s++ != ';' ) ; // Skip signature
a61af66fc99e Initial load
duke
parents:
diff changeset
2125 sig_bt[cnt++] = T_ARRAY;
a61af66fc99e Initial load
duke
parents:
diff changeset
2126 break;
a61af66fc99e Initial load
duke
parents:
diff changeset
2127 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2128 default : ShouldNotReachHere();
a61af66fc99e Initial load
duke
parents:
diff changeset
2129 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2130 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2131 assert( cnt < 256, "grow table size" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2132
a61af66fc99e Initial load
duke
parents:
diff changeset
2133 int comp_args_on_stack;
a61af66fc99e Initial load
duke
parents:
diff changeset
2134 comp_args_on_stack = java_calling_convention(sig_bt, regs, cnt, true);
a61af66fc99e Initial load
duke
parents:
diff changeset
2135
a61af66fc99e Initial load
duke
parents:
diff changeset
2136 // the calling convention doesn't count out_preserve_stack_slots so
a61af66fc99e Initial load
duke
parents:
diff changeset
2137 // we must add that in to get "true" stack offsets.
a61af66fc99e Initial load
duke
parents:
diff changeset
2138
a61af66fc99e Initial load
duke
parents:
diff changeset
2139 if (comp_args_on_stack) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2140 for (int i = 0; i < cnt; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2141 VMReg reg1 = regs[i].first();
a61af66fc99e Initial load
duke
parents:
diff changeset
2142 if( reg1->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2143 // Yuck
a61af66fc99e Initial load
duke
parents:
diff changeset
2144 reg1 = reg1->bias(out_preserve_stack_slots());
a61af66fc99e Initial load
duke
parents:
diff changeset
2145 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2146 VMReg reg2 = regs[i].second();
a61af66fc99e Initial load
duke
parents:
diff changeset
2147 if( reg2->is_stack()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2148 // Yuck
a61af66fc99e Initial load
duke
parents:
diff changeset
2149 reg2 = reg2->bias(out_preserve_stack_slots());
a61af66fc99e Initial load
duke
parents:
diff changeset
2150 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2151 regs[i].set_pair(reg2, reg1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2152 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2153 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2154
a61af66fc99e Initial load
duke
parents:
diff changeset
2155 // results
a61af66fc99e Initial load
duke
parents:
diff changeset
2156 *arg_size = cnt;
a61af66fc99e Initial load
duke
parents:
diff changeset
2157 return regs;
a61af66fc99e Initial load
duke
parents:
diff changeset
2158 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2159
a61af66fc99e Initial load
duke
parents:
diff changeset
2160 // OSR Migration Code
a61af66fc99e Initial load
duke
parents:
diff changeset
2161 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2162 // This code is used convert interpreter frames into compiled frames. It is
a61af66fc99e Initial load
duke
parents:
diff changeset
2163 // called from very start of a compiled OSR nmethod. A temp array is
a61af66fc99e Initial load
duke
parents:
diff changeset
2164 // allocated to hold the interesting bits of the interpreter frame. All
a61af66fc99e Initial load
duke
parents:
diff changeset
2165 // active locks are inflated to allow them to move. The displaced headers and
a61af66fc99e Initial load
duke
parents:
diff changeset
2166 // active interpeter locals are copied into the temp buffer. Then we return
a61af66fc99e Initial load
duke
parents:
diff changeset
2167 // back to the compiled code. The compiled code then pops the current
a61af66fc99e Initial load
duke
parents:
diff changeset
2168 // interpreter frame off the stack and pushes a new compiled frame. Then it
a61af66fc99e Initial load
duke
parents:
diff changeset
2169 // copies the interpreter locals and displaced headers where it wants.
a61af66fc99e Initial load
duke
parents:
diff changeset
2170 // Finally it calls back to free the temp buffer.
a61af66fc99e Initial load
duke
parents:
diff changeset
2171 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2172 // All of this is done NOT at any Safepoint, nor is any safepoint or GC allowed.
a61af66fc99e Initial load
duke
parents:
diff changeset
2173
a61af66fc99e Initial load
duke
parents:
diff changeset
2174 JRT_LEAF(intptr_t*, SharedRuntime::OSR_migration_begin( JavaThread *thread) )
a61af66fc99e Initial load
duke
parents:
diff changeset
2175
a61af66fc99e Initial load
duke
parents:
diff changeset
2176 #ifdef IA64
a61af66fc99e Initial load
duke
parents:
diff changeset
2177 ShouldNotReachHere(); // NYI
a61af66fc99e Initial load
duke
parents:
diff changeset
2178 #endif /* IA64 */
a61af66fc99e Initial load
duke
parents:
diff changeset
2179
a61af66fc99e Initial load
duke
parents:
diff changeset
2180 //
a61af66fc99e Initial load
duke
parents:
diff changeset
2181 // This code is dependent on the memory layout of the interpreter local
a61af66fc99e Initial load
duke
parents:
diff changeset
2182 // array and the monitors. On all of our platforms the layout is identical
a61af66fc99e Initial load
duke
parents:
diff changeset
2183 // so this code is shared. If some platform lays the their arrays out
a61af66fc99e Initial load
duke
parents:
diff changeset
2184 // differently then this code could move to platform specific code or
a61af66fc99e Initial load
duke
parents:
diff changeset
2185 // the code here could be modified to copy items one at a time using
a61af66fc99e Initial load
duke
parents:
diff changeset
2186 // frame accessor methods and be platform independent.
a61af66fc99e Initial load
duke
parents:
diff changeset
2187
a61af66fc99e Initial load
duke
parents:
diff changeset
2188 frame fr = thread->last_frame();
a61af66fc99e Initial load
duke
parents:
diff changeset
2189 assert( fr.is_interpreted_frame(), "" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2190 assert( fr.interpreter_frame_expression_stack_size()==0, "only handle empty stacks" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2191
a61af66fc99e Initial load
duke
parents:
diff changeset
2192 // Figure out how many monitors are active.
a61af66fc99e Initial load
duke
parents:
diff changeset
2193 int active_monitor_count = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
2194 for( BasicObjectLock *kptr = fr.interpreter_frame_monitor_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
2195 kptr < fr.interpreter_frame_monitor_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
2196 kptr = fr.next_monitor_in_interpreter_frame(kptr) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2197 if( kptr->obj() != NULL ) active_monitor_count++;
a61af66fc99e Initial load
duke
parents:
diff changeset
2198 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2199
a61af66fc99e Initial load
duke
parents:
diff changeset
2200 // QQQ we could place number of active monitors in the array so that compiled code
a61af66fc99e Initial load
duke
parents:
diff changeset
2201 // could double check it.
a61af66fc99e Initial load
duke
parents:
diff changeset
2202
a61af66fc99e Initial load
duke
parents:
diff changeset
2203 methodOop moop = fr.interpreter_frame_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
2204 int max_locals = moop->max_locals();
a61af66fc99e Initial load
duke
parents:
diff changeset
2205 // Allocate temp buffer, 1 word per local & 2 per active monitor
a61af66fc99e Initial load
duke
parents:
diff changeset
2206 int buf_size_words = max_locals + active_monitor_count*2;
a61af66fc99e Initial load
duke
parents:
diff changeset
2207 intptr_t *buf = NEW_C_HEAP_ARRAY(intptr_t,buf_size_words);
a61af66fc99e Initial load
duke
parents:
diff changeset
2208
a61af66fc99e Initial load
duke
parents:
diff changeset
2209 // Copy the locals. Order is preserved so that loading of longs works.
a61af66fc99e Initial load
duke
parents:
diff changeset
2210 // Since there's no GC I can copy the oops blindly.
a61af66fc99e Initial load
duke
parents:
diff changeset
2211 assert( sizeof(HeapWord)==sizeof(intptr_t), "fix this code");
a61af66fc99e Initial load
duke
parents:
diff changeset
2212 if (TaggedStackInterpreter) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2213 for (int i = 0; i < max_locals; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2214 // copy only each local separately to the buffer avoiding the tag
a61af66fc99e Initial load
duke
parents:
diff changeset
2215 buf[i] = *fr.interpreter_frame_local_at(max_locals-i-1);
a61af66fc99e Initial load
duke
parents:
diff changeset
2216 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2217 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
2218 Copy::disjoint_words(
a61af66fc99e Initial load
duke
parents:
diff changeset
2219 (HeapWord*)fr.interpreter_frame_local_at(max_locals-1),
a61af66fc99e Initial load
duke
parents:
diff changeset
2220 (HeapWord*)&buf[0],
a61af66fc99e Initial load
duke
parents:
diff changeset
2221 max_locals);
a61af66fc99e Initial load
duke
parents:
diff changeset
2222 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2223
a61af66fc99e Initial load
duke
parents:
diff changeset
2224 // Inflate locks. Copy the displaced headers. Be careful, there can be holes.
a61af66fc99e Initial load
duke
parents:
diff changeset
2225 int i = max_locals;
a61af66fc99e Initial load
duke
parents:
diff changeset
2226 for( BasicObjectLock *kptr2 = fr.interpreter_frame_monitor_end();
a61af66fc99e Initial load
duke
parents:
diff changeset
2227 kptr2 < fr.interpreter_frame_monitor_begin();
a61af66fc99e Initial load
duke
parents:
diff changeset
2228 kptr2 = fr.next_monitor_in_interpreter_frame(kptr2) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2229 if( kptr2->obj() != NULL) { // Avoid 'holes' in the monitor array
a61af66fc99e Initial load
duke
parents:
diff changeset
2230 BasicLock *lock = kptr2->lock();
a61af66fc99e Initial load
duke
parents:
diff changeset
2231 // Inflate so the displaced header becomes position-independent
a61af66fc99e Initial load
duke
parents:
diff changeset
2232 if (lock->displaced_header()->is_unlocked())
a61af66fc99e Initial load
duke
parents:
diff changeset
2233 ObjectSynchronizer::inflate_helper(kptr2->obj());
a61af66fc99e Initial load
duke
parents:
diff changeset
2234 // Now the displaced header is free to move
a61af66fc99e Initial load
duke
parents:
diff changeset
2235 buf[i++] = (intptr_t)lock->displaced_header();
a61af66fc99e Initial load
duke
parents:
diff changeset
2236 buf[i++] = (intptr_t)kptr2->obj();
a61af66fc99e Initial load
duke
parents:
diff changeset
2237 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2238 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2239 assert( i - max_locals == active_monitor_count*2, "found the expected number of monitors" );
a61af66fc99e Initial load
duke
parents:
diff changeset
2240
a61af66fc99e Initial load
duke
parents:
diff changeset
2241 return buf;
a61af66fc99e Initial load
duke
parents:
diff changeset
2242 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
2243
a61af66fc99e Initial load
duke
parents:
diff changeset
2244 JRT_LEAF(void, SharedRuntime::OSR_migration_end( intptr_t* buf) )
a61af66fc99e Initial load
duke
parents:
diff changeset
2245 FREE_C_HEAP_ARRAY(intptr_t,buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
2246 JRT_END
a61af66fc99e Initial load
duke
parents:
diff changeset
2247
a61af66fc99e Initial load
duke
parents:
diff changeset
2248 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
2249 bool AdapterHandlerLibrary::contains(CodeBlob* b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2250
124
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 62
diff changeset
2251 if (_handlers == NULL) return false;
b130b98db9cf 6689060: Escape Analysis does not work with Compressed Oops
kvn
parents: 62
diff changeset
2252
0
a61af66fc99e Initial load
duke
parents:
diff changeset
2253 for (int i = 0 ; i < _handlers->length() ; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2254 AdapterHandlerEntry* a = get_entry(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2255 if ( a != NULL && b == CodeCache::find_blob(a->get_i2c_entry()) ) return true;
a61af66fc99e Initial load
duke
parents:
diff changeset
2256 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2257 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
2258 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2259
a61af66fc99e Initial load
duke
parents:
diff changeset
2260 void AdapterHandlerLibrary::print_handler(CodeBlob* b) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2261
a61af66fc99e Initial load
duke
parents:
diff changeset
2262 for (int i = 0 ; i < _handlers->length() ; i++) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2263 AdapterHandlerEntry* a = get_entry(i);
a61af66fc99e Initial load
duke
parents:
diff changeset
2264 if ( a != NULL && b == CodeCache::find_blob(a->get_i2c_entry()) ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
2265 tty->print("Adapter for signature: ");
a61af66fc99e Initial load
duke
parents:
diff changeset
2266 // Fingerprinter::print(_fingerprints->at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2267 tty->print("0x%" FORMAT64_MODIFIER "x", _fingerprints->at(i));
a61af66fc99e Initial load
duke
parents:
diff changeset
2268 tty->print_cr(" i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT,
a61af66fc99e Initial load
duke
parents:
diff changeset
2269 a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry());
a61af66fc99e Initial load
duke
parents:
diff changeset
2270
a61af66fc99e Initial load
duke
parents:
diff changeset
2271 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
2272 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2273 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2274 assert(false, "Should have found handler");
a61af66fc99e Initial load
duke
parents:
diff changeset
2275 }
a61af66fc99e Initial load
duke
parents:
diff changeset
2276 #endif /* PRODUCT */