annotate src/share/vm/runtime/sharedRuntime.cpp @ 94:0834225a7916

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