Mercurial > hg > graal-compiler
annotate src/share/vm/runtime/sharedRuntime.cpp @ 2607:008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
This is necessary to ensure correct continuation in the interpreter when the stateBefore is used as a deoptimization point.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Fri, 06 May 2011 17:47:17 +0200 |
parents | 98fa88528319 |
children | b1b58f908044 |
rev | line source |
---|---|
0 | 1 /* |
2142 | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1507
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "classfile/vmSymbols.hpp" | |
28 #include "code/compiledIC.hpp" | |
29 #include "code/scopeDesc.hpp" | |
30 #include "code/vtableStubs.hpp" | |
31 #include "compiler/abstractCompiler.hpp" | |
32 #include "compiler/compileBroker.hpp" | |
33 #include "compiler/compilerOracle.hpp" | |
34 #include "interpreter/interpreter.hpp" | |
35 #include "interpreter/interpreterRuntime.hpp" | |
36 #include "memory/gcLocker.inline.hpp" | |
37 #include "memory/universe.inline.hpp" | |
38 #include "oops/oop.inline.hpp" | |
39 #include "prims/forte.hpp" | |
40 #include "prims/jvmtiExport.hpp" | |
41 #include "prims/jvmtiRedefineClassesTrace.hpp" | |
42 #include "prims/methodHandles.hpp" | |
43 #include "prims/nativeLookup.hpp" | |
44 #include "runtime/arguments.hpp" | |
45 #include "runtime/biasedLocking.hpp" | |
46 #include "runtime/handles.inline.hpp" | |
47 #include "runtime/init.hpp" | |
48 #include "runtime/interfaceSupport.hpp" | |
49 #include "runtime/javaCalls.hpp" | |
50 #include "runtime/sharedRuntime.hpp" | |
51 #include "runtime/stubRoutines.hpp" | |
52 #include "runtime/vframe.hpp" | |
53 #include "runtime/vframeArray.hpp" | |
54 #include "utilities/copy.hpp" | |
55 #include "utilities/dtrace.hpp" | |
56 #include "utilities/events.hpp" | |
57 #include "utilities/hashtable.inline.hpp" | |
58 #include "utilities/xmlstream.hpp" | |
59 #ifdef TARGET_ARCH_x86 | |
60 # include "nativeInst_x86.hpp" | |
61 # include "vmreg_x86.inline.hpp" | |
62 #endif | |
63 #ifdef TARGET_ARCH_sparc | |
64 # include "nativeInst_sparc.hpp" | |
65 # include "vmreg_sparc.inline.hpp" | |
66 #endif | |
67 #ifdef TARGET_ARCH_zero | |
68 # include "nativeInst_zero.hpp" | |
69 # include "vmreg_zero.inline.hpp" | |
70 #endif | |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
71 #ifdef TARGET_ARCH_arm |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
72 # include "nativeInst_arm.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
73 # include "vmreg_arm.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
74 #endif |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
75 #ifdef TARGET_ARCH_ppc |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
76 # include "nativeInst_ppc.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
77 # include "vmreg_ppc.inline.hpp" |
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
78 #endif |
1972 | 79 #ifdef COMPILER1 |
80 #include "c1/c1_Runtime1.hpp" | |
81 #endif | |
82 | |
0 | 83 #include <math.h> |
84 | |
85 HS_DTRACE_PROBE_DECL4(hotspot, object__alloc, Thread*, char*, int, size_t); | |
86 HS_DTRACE_PROBE_DECL7(hotspot, method__entry, int, | |
87 char*, int, char*, int, char*, int); | |
88 HS_DTRACE_PROBE_DECL7(hotspot, method__return, int, | |
89 char*, int, char*, int, char*, int); | |
90 | |
91 // Implementation of SharedRuntime | |
92 | |
93 #ifndef PRODUCT | |
94 // For statistics | |
95 int SharedRuntime::_ic_miss_ctr = 0; | |
96 int SharedRuntime::_wrong_method_ctr = 0; | |
97 int SharedRuntime::_resolve_static_ctr = 0; | |
98 int SharedRuntime::_resolve_virtual_ctr = 0; | |
99 int SharedRuntime::_resolve_opt_virtual_ctr = 0; | |
100 int SharedRuntime::_implicit_null_throws = 0; | |
101 int SharedRuntime::_implicit_div0_throws = 0; | |
102 int SharedRuntime::_throw_null_ctr = 0; | |
103 | |
104 int SharedRuntime::_nof_normal_calls = 0; | |
105 int SharedRuntime::_nof_optimized_calls = 0; | |
106 int SharedRuntime::_nof_inlined_calls = 0; | |
107 int SharedRuntime::_nof_megamorphic_calls = 0; | |
108 int SharedRuntime::_nof_static_calls = 0; | |
109 int SharedRuntime::_nof_inlined_static_calls = 0; | |
110 int SharedRuntime::_nof_interface_calls = 0; | |
111 int SharedRuntime::_nof_optimized_interface_calls = 0; | |
112 int SharedRuntime::_nof_inlined_interface_calls = 0; | |
113 int SharedRuntime::_nof_megamorphic_interface_calls = 0; | |
114 int SharedRuntime::_nof_removable_exceptions = 0; | |
115 | |
116 int SharedRuntime::_new_instance_ctr=0; | |
117 int SharedRuntime::_new_array_ctr=0; | |
118 int SharedRuntime::_multi1_ctr=0; | |
119 int SharedRuntime::_multi2_ctr=0; | |
120 int SharedRuntime::_multi3_ctr=0; | |
121 int SharedRuntime::_multi4_ctr=0; | |
122 int SharedRuntime::_multi5_ctr=0; | |
123 int SharedRuntime::_mon_enter_stub_ctr=0; | |
124 int SharedRuntime::_mon_exit_stub_ctr=0; | |
125 int SharedRuntime::_mon_enter_ctr=0; | |
126 int SharedRuntime::_mon_exit_ctr=0; | |
127 int SharedRuntime::_partial_subtype_ctr=0; | |
128 int SharedRuntime::_jbyte_array_copy_ctr=0; | |
129 int SharedRuntime::_jshort_array_copy_ctr=0; | |
130 int SharedRuntime::_jint_array_copy_ctr=0; | |
131 int SharedRuntime::_jlong_array_copy_ctr=0; | |
132 int SharedRuntime::_oop_array_copy_ctr=0; | |
133 int SharedRuntime::_checkcast_array_copy_ctr=0; | |
134 int SharedRuntime::_unsafe_array_copy_ctr=0; | |
135 int SharedRuntime::_generic_array_copy_ctr=0; | |
136 int SharedRuntime::_slow_array_copy_ctr=0; | |
137 int SharedRuntime::_find_handler_ctr=0; | |
138 int SharedRuntime::_rethrow_ctr=0; | |
139 | |
140 int SharedRuntime::_ICmiss_index = 0; | |
141 int SharedRuntime::_ICmiss_count[SharedRuntime::maxICmiss_count]; | |
142 address SharedRuntime::_ICmiss_at[SharedRuntime::maxICmiss_count]; | |
143 | |
144 void SharedRuntime::trace_ic_miss(address at) { | |
145 for (int i = 0; i < _ICmiss_index; i++) { | |
146 if (_ICmiss_at[i] == at) { | |
147 _ICmiss_count[i]++; | |
148 return; | |
149 } | |
150 } | |
151 int index = _ICmiss_index++; | |
152 if (_ICmiss_index >= maxICmiss_count) _ICmiss_index = maxICmiss_count - 1; | |
153 _ICmiss_at[index] = at; | |
154 _ICmiss_count[index] = 1; | |
155 } | |
156 | |
157 void SharedRuntime::print_ic_miss_histogram() { | |
158 if (ICMissHistogram) { | |
159 tty->print_cr ("IC Miss Histogram:"); | |
160 int tot_misses = 0; | |
161 for (int i = 0; i < _ICmiss_index; i++) { | |
162 tty->print_cr(" at: " INTPTR_FORMAT " nof: %d", _ICmiss_at[i], _ICmiss_count[i]); | |
163 tot_misses += _ICmiss_count[i]; | |
164 } | |
165 tty->print_cr ("Total IC misses: %7d", tot_misses); | |
166 } | |
167 } | |
168 #endif // PRODUCT | |
169 | |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
170 #ifndef SERIALGC |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
171 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
172 // G1 write-barrier pre: executed before a pointer store. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
173 JRT_LEAF(void, SharedRuntime::g1_wb_pre(oopDesc* orig, JavaThread *thread)) |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
174 if (orig == NULL) { |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
175 assert(false, "should be optimized out"); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
176 return; |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
177 } |
845
df6caf649ff7
6700789: G1: Enable use of compressed oops with G1 heaps
ysr
parents:
742
diff
changeset
|
178 assert(orig->is_oop(true /* ignore mark word */), "Error"); |
342
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
179 // store the original value that was in the field reference |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
180 thread->satb_mark_queue().enqueue(orig); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
181 JRT_END |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
182 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
183 // G1 write-barrier post: executed after a pointer store. |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
184 JRT_LEAF(void, SharedRuntime::g1_wb_post(void* card_addr, JavaThread* thread)) |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
185 thread->dirty_card_queue().enqueue(card_addr); |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
186 JRT_END |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
187 |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
188 #endif // !SERIALGC |
37f87013dfd8
6711316: Open source the Garbage-First garbage collector
ysr
parents:
128
diff
changeset
|
189 |
0 | 190 |
191 JRT_LEAF(jlong, SharedRuntime::lmul(jlong y, jlong x)) | |
192 return x * y; | |
193 JRT_END | |
194 | |
195 | |
196 JRT_LEAF(jlong, SharedRuntime::ldiv(jlong y, jlong x)) | |
197 if (x == min_jlong && y == CONST64(-1)) { | |
198 return x; | |
199 } else { | |
200 return x / y; | |
201 } | |
202 JRT_END | |
203 | |
204 | |
205 JRT_LEAF(jlong, SharedRuntime::lrem(jlong y, jlong x)) | |
206 if (x == min_jlong && y == CONST64(-1)) { | |
207 return 0; | |
208 } else { | |
209 return x % y; | |
210 } | |
211 JRT_END | |
212 | |
213 | |
214 const juint float_sign_mask = 0x7FFFFFFF; | |
215 const juint float_infinity = 0x7F800000; | |
216 const julong double_sign_mask = CONST64(0x7FFFFFFFFFFFFFFF); | |
217 const julong double_infinity = CONST64(0x7FF0000000000000); | |
218 | |
219 JRT_LEAF(jfloat, SharedRuntime::frem(jfloat x, jfloat y)) | |
220 #ifdef _WIN64 | |
221 // 64-bit Windows on amd64 returns the wrong values for | |
222 // infinity operands. | |
223 union { jfloat f; juint i; } xbits, ybits; | |
224 xbits.f = x; | |
225 ybits.f = y; | |
226 // x Mod Infinity == x unless x is infinity | |
227 if ( ((xbits.i & float_sign_mask) != float_infinity) && | |
228 ((ybits.i & float_sign_mask) == float_infinity) ) { | |
229 return x; | |
230 } | |
231 #endif | |
232 return ((jfloat)fmod((double)x,(double)y)); | |
233 JRT_END | |
234 | |
235 | |
236 JRT_LEAF(jdouble, SharedRuntime::drem(jdouble x, jdouble y)) | |
237 #ifdef _WIN64 | |
238 union { jdouble d; julong l; } xbits, ybits; | |
239 xbits.d = x; | |
240 ybits.d = y; | |
241 // x Mod Infinity == x unless x is infinity | |
242 if ( ((xbits.l & double_sign_mask) != double_infinity) && | |
243 ((ybits.l & double_sign_mask) == double_infinity) ) { | |
244 return x; | |
245 } | |
246 #endif | |
247 return ((jdouble)fmod((double)x,(double)y)); | |
248 JRT_END | |
249 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
250 #ifdef __SOFTFP__ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
251 JRT_LEAF(jfloat, SharedRuntime::fadd(jfloat x, jfloat y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
252 return x + y; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
253 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
254 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
255 JRT_LEAF(jfloat, SharedRuntime::fsub(jfloat x, jfloat y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
256 return x - y; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
257 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
258 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
259 JRT_LEAF(jfloat, SharedRuntime::fmul(jfloat x, jfloat y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
260 return x * y; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
261 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
262 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
263 JRT_LEAF(jfloat, SharedRuntime::fdiv(jfloat x, jfloat y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
264 return x / y; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
265 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
266 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
267 JRT_LEAF(jdouble, SharedRuntime::dadd(jdouble x, jdouble y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
268 return x + y; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
269 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
270 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
271 JRT_LEAF(jdouble, SharedRuntime::dsub(jdouble x, jdouble y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
272 return x - y; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
273 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
274 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
275 JRT_LEAF(jdouble, SharedRuntime::dmul(jdouble x, jdouble y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
276 return x * y; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
277 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
278 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
279 JRT_LEAF(jdouble, SharedRuntime::ddiv(jdouble x, jdouble y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
280 return x / y; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
281 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
282 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
283 JRT_LEAF(jfloat, SharedRuntime::i2f(jint x)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
284 return (jfloat)x; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
285 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
286 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
287 JRT_LEAF(jdouble, SharedRuntime::i2d(jint x)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
288 return (jdouble)x; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
289 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
290 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
291 JRT_LEAF(jdouble, SharedRuntime::f2d(jfloat x)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
292 return (jdouble)x; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
293 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
294 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
295 JRT_LEAF(int, SharedRuntime::fcmpl(float x, float y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
296 return x>y ? 1 : (x==y ? 0 : -1); /* x<y or is_nan*/ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
297 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
298 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
299 JRT_LEAF(int, SharedRuntime::fcmpg(float x, float y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
300 return x<y ? -1 : (x==y ? 0 : 1); /* x>y or is_nan */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
301 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
302 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
303 JRT_LEAF(int, SharedRuntime::dcmpl(double x, double y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
304 return x>y ? 1 : (x==y ? 0 : -1); /* x<y or is_nan */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
305 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
306 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
307 JRT_LEAF(int, SharedRuntime::dcmpg(double x, double y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
308 return x<y ? -1 : (x==y ? 0 : 1); /* x>y or is_nan */ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
309 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
310 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
311 // Functions to return the opposite of the aeabi functions for nan. |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
312 JRT_LEAF(int, SharedRuntime::unordered_fcmplt(float x, float y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
313 return (x < y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
314 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
315 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
316 JRT_LEAF(int, SharedRuntime::unordered_dcmplt(double x, double y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
317 return (x < y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
318 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
319 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
320 JRT_LEAF(int, SharedRuntime::unordered_fcmple(float x, float y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
321 return (x <= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
322 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
323 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
324 JRT_LEAF(int, SharedRuntime::unordered_dcmple(double x, double y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
325 return (x <= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
326 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
327 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
328 JRT_LEAF(int, SharedRuntime::unordered_fcmpge(float x, float y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
329 return (x >= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
330 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
331 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
332 JRT_LEAF(int, SharedRuntime::unordered_dcmpge(double x, double y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
333 return (x >= y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
334 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
335 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
336 JRT_LEAF(int, SharedRuntime::unordered_fcmpgt(float x, float y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
337 return (x > y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
338 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
339 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
340 JRT_LEAF(int, SharedRuntime::unordered_dcmpgt(double x, double y)) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
341 return (x > y) ? 1 : ((g_isnan(x) || g_isnan(y)) ? 1 : 0); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
342 JRT_END |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
343 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
344 // Intrinsics make gcc generate code for these. |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
345 float SharedRuntime::fneg(float f) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
346 return -f; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
347 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
348 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
349 double SharedRuntime::dneg(double f) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
350 return -f; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
351 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
352 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
353 #endif // __SOFTFP__ |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
354 |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
355 #if defined(__SOFTFP__) || defined(E500V2) |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
356 // Intrinsics make gcc generate code for these. |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
357 double SharedRuntime::dabs(double f) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
358 return (f <= (double)0.0) ? (double)0.0 - f : f; |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
359 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
360 |
1868
3dc12ef8735e
6989297: Integrate additional portability improvements
bobv
parents:
1793
diff
changeset
|
361 #endif |
3dc12ef8735e
6989297: Integrate additional portability improvements
bobv
parents:
1793
diff
changeset
|
362 |
3dc12ef8735e
6989297: Integrate additional portability improvements
bobv
parents:
1793
diff
changeset
|
363 #if defined(__SOFTFP__) || defined(PPC) |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
364 double SharedRuntime::dsqrt(double f) { |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
365 return sqrt(f); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
366 } |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
367 #endif |
0 | 368 |
369 JRT_LEAF(jint, SharedRuntime::f2i(jfloat x)) | |
508
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
370 if (g_isnan(x)) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
371 return 0; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
372 if (x >= (jfloat) max_jint) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
373 return max_jint; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
374 if (x <= (jfloat) min_jint) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
375 return min_jint; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
376 return (jint) x; |
0 | 377 JRT_END |
378 | |
379 | |
380 JRT_LEAF(jlong, SharedRuntime::f2l(jfloat x)) | |
508
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
381 if (g_isnan(x)) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
382 return 0; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
383 if (x >= (jfloat) max_jlong) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
384 return max_jlong; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
385 if (x <= (jfloat) min_jlong) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
386 return min_jlong; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
387 return (jlong) x; |
0 | 388 JRT_END |
389 | |
390 | |
391 JRT_LEAF(jint, SharedRuntime::d2i(jdouble x)) | |
508
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
392 if (g_isnan(x)) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
393 return 0; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
394 if (x >= (jdouble) max_jint) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
395 return max_jint; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
396 if (x <= (jdouble) min_jint) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
397 return min_jint; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
398 return (jint) x; |
0 | 399 JRT_END |
400 | |
401 | |
402 JRT_LEAF(jlong, SharedRuntime::d2l(jdouble x)) | |
508
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
403 if (g_isnan(x)) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
404 return 0; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
405 if (x >= (jdouble) max_jlong) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
406 return max_jlong; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
407 if (x <= (jdouble) min_jlong) |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
408 return min_jlong; |
6d8fc951eb25
6778657: Casts in SharedRuntime::f2i, f2l, d2i and d2l rely on undefined C++ behaviour
kvn
parents:
465
diff
changeset
|
409 return (jlong) x; |
0 | 410 JRT_END |
411 | |
412 | |
413 JRT_LEAF(jfloat, SharedRuntime::d2f(jdouble x)) | |
414 return (jfloat)x; | |
415 JRT_END | |
416 | |
417 | |
418 JRT_LEAF(jfloat, SharedRuntime::l2f(jlong x)) | |
419 return (jfloat)x; | |
420 JRT_END | |
421 | |
422 | |
423 JRT_LEAF(jdouble, SharedRuntime::l2d(jlong x)) | |
424 return (jdouble)x; | |
425 JRT_END | |
426 | |
427 // Exception handling accross interpreter/compiler boundaries | |
428 // | |
429 // exception_handler_for_return_address(...) returns the continuation address. | |
430 // The continuation address is the entry point of the exception handler of the | |
431 // previous frame depending on the return address. | |
432 | |
1295 | 433 address SharedRuntime::raw_exception_handler_for_return_address(JavaThread* thread, address return_address) { |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
434 assert(frame::verify_return_pc(return_address), err_msg("must be a return address: " INTPTR_FORMAT, return_address)); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
435 |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
436 // Reset method handle flag. |
1368
93767e6a2dfd
6941529: SharedRuntime::raw_exception_handler_for_return_address must reset thread MethodHandle flag
twisti
parents:
1299
diff
changeset
|
437 thread->set_is_method_handle_return(false); |
93767e6a2dfd
6941529: SharedRuntime::raw_exception_handler_for_return_address must reset thread MethodHandle flag
twisti
parents:
1299
diff
changeset
|
438 |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
439 // The fastest case first |
0 | 440 CodeBlob* blob = CodeCache::find_blob(return_address); |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
441 nmethod* nm = (blob != NULL) ? blob->as_nmethod_or_null() : NULL; |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
442 if (nm != NULL) { |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
443 // Set flag if return address is a method handle call site. |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
444 thread->set_is_method_handle_return(nm->is_method_handle_return(return_address)); |
0 | 445 // native nmethods don't have exception handlers |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
446 assert(!nm->is_native_method(), "no exception handler"); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
447 assert(nm->header_begin() != nm->exception_begin(), "no exception handler"); |
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
448 if (nm->is_deopt_pc(return_address)) { |
0 | 449 return SharedRuntime::deopt_blob()->unpack_with_exception(); |
450 } else { | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
451 return nm->exception_begin(); |
0 | 452 } |
453 } | |
454 | |
455 // Entry code | |
456 if (StubRoutines::returns_to_call_stub(return_address)) { | |
457 return StubRoutines::catch_exception_entry(); | |
458 } | |
459 // Interpreted code | |
460 if (Interpreter::contains(return_address)) { | |
461 return Interpreter::rethrow_exception_entry(); | |
462 } | |
463 | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
464 guarantee(blob == NULL || !blob->is_runtime_stub(), "caller should have skipped stub"); |
0 | 465 guarantee(!VtableStubs::contains(return_address), "NULL exceptions in vtables should have been handled already!"); |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
466 |
0 | 467 #ifndef PRODUCT |
468 { ResourceMark rm; | |
469 tty->print_cr("No exception handler found for exception at " INTPTR_FORMAT " - potential problems:", return_address); | |
470 tty->print_cr("a) exception happened in (new?) code stubs/buffers that is not handled here"); | |
471 tty->print_cr("b) other problem"); | |
472 } | |
473 #endif // PRODUCT | |
2321
1b4e6a5d98e0
7012914: JSR 292 MethodHandlesTest C1: frame::verify_return_pc(return_address) failed: must be a return pc
twisti
parents:
2192
diff
changeset
|
474 |
0 | 475 ShouldNotReachHere(); |
476 return NULL; | |
477 } | |
478 | |
479 | |
1295 | 480 JRT_LEAF(address, SharedRuntime::exception_handler_for_return_address(JavaThread* thread, address return_address)) |
481 return raw_exception_handler_for_return_address(thread, return_address); | |
0 | 482 JRT_END |
483 | |
1295 | 484 |
0 | 485 address SharedRuntime::get_poll_stub(address pc) { |
486 address stub; | |
487 // Look up the code blob | |
488 CodeBlob *cb = CodeCache::find_blob(pc); | |
489 | |
490 // Should be an nmethod | |
491 assert( cb && cb->is_nmethod(), "safepoint polling: pc must refer to an nmethod" ); | |
492 | |
493 // Look up the relocation information | |
494 assert( ((nmethod*)cb)->is_at_poll_or_poll_return(pc), | |
495 "safepoint polling: type must be poll" ); | |
496 | |
497 assert( ((NativeInstruction*)pc)->is_safepoint_poll(), | |
498 "Only polling locations are used for safepoint"); | |
499 | |
500 bool at_poll_return = ((nmethod*)cb)->is_at_poll_return(pc); | |
501 if (at_poll_return) { | |
502 assert(SharedRuntime::polling_page_return_handler_blob() != NULL, | |
503 "polling page return stub not created yet"); | |
1748 | 504 stub = SharedRuntime::polling_page_return_handler_blob()->entry_point(); |
0 | 505 } else { |
506 assert(SharedRuntime::polling_page_safepoint_handler_blob() != NULL, | |
507 "polling page safepoint stub not created yet"); | |
1748 | 508 stub = SharedRuntime::polling_page_safepoint_handler_blob()->entry_point(); |
0 | 509 } |
510 #ifndef PRODUCT | |
511 if( TraceSafepoint ) { | |
512 char buf[256]; | |
513 jio_snprintf(buf, sizeof(buf), | |
514 "... found polling page %s exception at pc = " | |
515 INTPTR_FORMAT ", stub =" INTPTR_FORMAT, | |
516 at_poll_return ? "return" : "loop", | |
517 (intptr_t)pc, (intptr_t)stub); | |
518 tty->print_raw_cr(buf); | |
519 } | |
520 #endif // PRODUCT | |
521 return stub; | |
522 } | |
523 | |
524 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
525 oop SharedRuntime::retrieve_receiver( Symbol* sig, frame caller ) { |
0 | 526 assert(caller.is_interpreted_frame(), ""); |
527 int args_size = ArgumentSizeComputer(sig).size() + 1; | |
528 assert(args_size <= caller.interpreter_frame_expression_stack_size(), "receiver must be on interpreter stack"); | |
529 oop result = (oop) *caller.interpreter_frame_tos_at(args_size - 1); | |
530 assert(Universe::heap()->is_in(result) && result->is_oop(), "receiver must be an oop"); | |
531 return result; | |
532 } | |
533 | |
534 | |
535 void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, Handle h_exception) { | |
1213
6deeaebad47a
6902182: 4/4 Starting with jdwp agent should not incur performance penalty
dcubed
parents:
1187
diff
changeset
|
536 if (JvmtiExport::can_post_on_exceptions()) { |
0 | 537 vframeStream vfst(thread, true); |
538 methodHandle method = methodHandle(thread, vfst.method()); | |
539 address bcp = method()->bcp_from(vfst.bci()); | |
540 JvmtiExport::post_exception_throw(thread, method(), bcp, h_exception()); | |
541 } | |
542 Exceptions::_throw(thread, __FILE__, __LINE__, h_exception); | |
543 } | |
544 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
545 void SharedRuntime::throw_and_post_jvmti_exception(JavaThread *thread, Symbol* name, const char *message) { |
0 | 546 Handle h_exception = Exceptions::new_exception(thread, name, message); |
547 throw_and_post_jvmti_exception(thread, h_exception); | |
548 } | |
549 | |
610
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
550 // The interpreter code to call this tracing function is only |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
551 // called/generated when TraceRedefineClasses has the right bits |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
552 // set. Since obsolete methods are never compiled, we don't have |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
553 // to modify the compilers to generate calls to this function. |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
554 // |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
555 JRT_LEAF(int, SharedRuntime::rc_trace_method_entry( |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
556 JavaThread* thread, methodOopDesc* method)) |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
557 assert(RC_TRACE_IN_RANGE(0x00001000, 0x00002000), "wrong call"); |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
558 |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
559 if (method->is_obsolete()) { |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
560 // We are calling an obsolete method, but this is not necessarily |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
561 // an error. Our method could have been redefined just after we |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
562 // fetched the methodOop from the constant pool. |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
563 |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
564 // RC_TRACE macro has an embedded ResourceMark |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
565 RC_TRACE_WITH_THREAD(0x00001000, thread, |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
566 ("calling obsolete method '%s'", |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
567 method->name_and_sig_as_C_string())); |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
568 if (RC_TRACE_ENABLED(0x00002000)) { |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
569 // this option is provided to debug calls to obsolete methods |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
570 guarantee(false, "faulting at call to an obsolete method."); |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
571 } |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
572 } |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
573 return 0; |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
574 JRT_END |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
465
diff
changeset
|
575 |
0 | 576 // ret_pc points into caller; we are returning caller's exception handler |
577 // for given exception | |
578 address SharedRuntime::compute_compiled_exc_handler(nmethod* nm, address ret_pc, Handle& exception, | |
579 bool force_unwind, bool top_frame_only) { | |
580 assert(nm != NULL, "must exist"); | |
581 ResourceMark rm; | |
582 | |
583 ScopeDesc* sd = nm->scope_desc_at(ret_pc); | |
584 // determine handler bci, if any | |
585 EXCEPTION_MARK; | |
586 | |
587 int handler_bci = -1; | |
588 int scope_depth = 0; | |
589 if (!force_unwind) { | |
590 int bci = sd->bci(); | |
591 do { | |
592 bool skip_scope_increment = false; | |
593 // exception handler lookup | |
594 KlassHandle ek (THREAD, exception->klass()); | |
595 handler_bci = sd->method()->fast_exception_handler_bci_for(ek, bci, THREAD); | |
596 if (HAS_PENDING_EXCEPTION) { | |
597 // We threw an exception while trying to find the exception handler. | |
598 // Transfer the new exception to the exception handle which will | |
599 // be set into thread local storage, and do another lookup for an | |
600 // exception handler for this exception, this time starting at the | |
601 // BCI of the exception handler which caused the exception to be | |
602 // thrown (bugs 4307310 and 4546590). Set "exception" reference | |
603 // argument to ensure that the correct exception is thrown (4870175). | |
604 exception = Handle(THREAD, PENDING_EXCEPTION); | |
605 CLEAR_PENDING_EXCEPTION; | |
606 if (handler_bci >= 0) { | |
607 bci = handler_bci; | |
608 handler_bci = -1; | |
609 skip_scope_increment = true; | |
610 } | |
611 } | |
612 if (!top_frame_only && handler_bci < 0 && !skip_scope_increment) { | |
613 sd = sd->sender(); | |
614 if (sd != NULL) { | |
615 bci = sd->bci(); | |
616 } | |
617 ++scope_depth; | |
618 } | |
619 } while (!top_frame_only && handler_bci < 0 && sd != NULL); | |
620 } | |
621 | |
622 // found handling method => lookup exception handler | |
1748 | 623 int catch_pco = ret_pc - nm->code_begin(); |
0 | 624 |
625 ExceptionHandlerTable table(nm); | |
626 HandlerTableEntry *t = table.entry_for(catch_pco, handler_bci, scope_depth); | |
627 if (t == NULL && (nm->is_compiled_by_c1() || handler_bci != -1)) { | |
628 // Allow abbreviated catch tables. The idea is to allow a method | |
629 // to materialize its exceptions without committing to the exact | |
630 // routing of exceptions. In particular this is needed for adding | |
631 // a synthethic handler to unlock monitors when inlining | |
632 // synchonized methods since the unlock path isn't represented in | |
633 // the bytecodes. | |
634 t = table.entry_for(catch_pco, -1, 0); | |
635 } | |
636 | |
1378
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1368
diff
changeset
|
637 #ifdef COMPILER1 |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1368
diff
changeset
|
638 if (t == NULL && nm->is_compiled_by_c1()) { |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1368
diff
changeset
|
639 assert(nm->unwind_handler_begin() != NULL, ""); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1368
diff
changeset
|
640 return nm->unwind_handler_begin(); |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1368
diff
changeset
|
641 } |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1368
diff
changeset
|
642 #endif |
9f5b60a14736
6939930: exception unwind changes in 6919934 hurts compilation speed
never
parents:
1368
diff
changeset
|
643 |
0 | 644 if (t == NULL) { |
645 tty->print_cr("MISSING EXCEPTION HANDLER for pc " INTPTR_FORMAT " and handler bci %d", ret_pc, handler_bci); | |
646 tty->print_cr(" Exception:"); | |
647 exception->print(); | |
648 tty->cr(); | |
649 tty->print_cr(" Compiled exception table :"); | |
650 table.print(); | |
651 nm->print_code(); | |
652 guarantee(false, "missing exception handler"); | |
653 return NULL; | |
654 } | |
655 | |
1748 | 656 return nm->code_begin() + t->pco(); |
0 | 657 } |
658 | |
659 JRT_ENTRY(void, SharedRuntime::throw_AbstractMethodError(JavaThread* thread)) | |
660 // These errors occur only at call sites | |
661 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_AbstractMethodError()); | |
662 JRT_END | |
663 | |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
664 JRT_ENTRY(void, SharedRuntime::throw_IncompatibleClassChangeError(JavaThread* thread)) |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
665 // These errors occur only at call sites |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
666 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_IncompatibleClassChangeError(), "vtable stub"); |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
667 JRT_END |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
668 |
0 | 669 JRT_ENTRY(void, SharedRuntime::throw_ArithmeticException(JavaThread* thread)) |
670 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_ArithmeticException(), "/ by zero"); | |
671 JRT_END | |
672 | |
673 JRT_ENTRY(void, SharedRuntime::throw_NullPointerException(JavaThread* thread)) | |
674 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException()); | |
675 JRT_END | |
676 | |
677 JRT_ENTRY(void, SharedRuntime::throw_NullPointerException_at_call(JavaThread* thread)) | |
678 // This entry point is effectively only used for NullPointerExceptions which occur at inline | |
679 // cache sites (when the callee activation is not yet set up) so we are at a call site | |
680 throw_and_post_jvmti_exception(thread, vmSymbols::java_lang_NullPointerException()); | |
681 JRT_END | |
682 | |
683 JRT_ENTRY(void, SharedRuntime::throw_StackOverflowError(JavaThread* thread)) | |
684 // We avoid using the normal exception construction in this case because | |
685 // it performs an upcall to Java, and we're already out of stack space. | |
686 klassOop k = SystemDictionary::StackOverflowError_klass(); | |
687 oop exception_oop = instanceKlass::cast(k)->allocate_instance(CHECK); | |
688 Handle exception (thread, exception_oop); | |
689 if (StackTraceInThrowable) { | |
690 java_lang_Throwable::fill_in_stack_trace(exception); | |
691 } | |
692 throw_and_post_jvmti_exception(thread, exception); | |
693 JRT_END | |
694 | |
2607
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
695 address SharedRuntime::deoptimization_continuation(JavaThread* thread, address pc, nmethod* nm) |
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
696 { |
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
697 if (TraceSignals) { |
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
698 tty->print_cr(err_msg("Deoptimizing on implicit exception at relative pc=%d in method %s", pc - nm->entry_point(), nm->method()->name()->as_C_string())); |
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
699 } |
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
700 thread->_ScratchA = (intptr_t)pc; |
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
701 return (SharedRuntime::deopt_blob()->jmp_uncommon_trap()); |
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
702 } |
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
703 |
0 | 704 address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread, |
705 address pc, | |
706 SharedRuntime::ImplicitExceptionKind exception_kind) | |
707 { | |
708 address target_pc = NULL; | |
709 | |
2494
e88293edf07c
Fixed an issue with alignment of double/long values in the code buffer. Can now run Scimark again.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
2491
diff
changeset
|
710 if (TraceSignals) { |
2605
98fa88528319
Deopt on implicit null pointer exception.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2494
diff
changeset
|
711 tty->print_cr("Searching for continuation for implicit exception at %d!", pc); |
2494
e88293edf07c
Fixed an issue with alignment of double/long values in the code buffer. Can now run Scimark again.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
2491
diff
changeset
|
712 } |
e88293edf07c
Fixed an issue with alignment of double/long values in the code buffer. Can now run Scimark again.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
2491
diff
changeset
|
713 |
0 | 714 if (Interpreter::contains(pc)) { |
715 #ifdef CC_INTERP | |
716 // C++ interpreter doesn't throw implicit exceptions | |
717 ShouldNotReachHere(); | |
718 #else | |
719 switch (exception_kind) { | |
720 case IMPLICIT_NULL: return Interpreter::throw_NullPointerException_entry(); | |
721 case IMPLICIT_DIVIDE_BY_ZERO: return Interpreter::throw_ArithmeticException_entry(); | |
722 case STACK_OVERFLOW: return Interpreter::throw_StackOverflowError_entry(); | |
723 default: ShouldNotReachHere(); | |
724 } | |
725 #endif // !CC_INTERP | |
726 } else { | |
727 switch (exception_kind) { | |
728 case STACK_OVERFLOW: { | |
729 // Stack overflow only occurs upon frame setup; the callee is | |
730 // going to be unwound. Dispatch to a shared runtime stub | |
731 // which will cause the StackOverflowError to be fabricated | |
732 // and processed. | |
733 // For stack overflow in deoptimization blob, cleanup thread. | |
734 if (thread->deopt_mark() != NULL) { | |
735 Deoptimization::cleanup_deopt_info(thread, NULL); | |
736 } | |
737 return StubRoutines::throw_StackOverflowError_entry(); | |
738 } | |
739 | |
740 case IMPLICIT_NULL: { | |
741 if (VtableStubs::contains(pc)) { | |
742 // We haven't yet entered the callee frame. Fabricate an | |
743 // exception and begin dispatching it in the caller. Since | |
744 // the caller was at a call site, it's safe to destroy all | |
745 // caller-saved registers, as these entry points do. | |
746 VtableStub* vt_stub = VtableStubs::stub_containing(pc); | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
356
diff
changeset
|
747 |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
356
diff
changeset
|
748 // If vt_stub is NULL, then return NULL to signal handler to report the SEGV error. |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
356
diff
changeset
|
749 if (vt_stub == NULL) return NULL; |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
356
diff
changeset
|
750 |
0 | 751 if (vt_stub->is_abstract_method_error(pc)) { |
752 assert(!vt_stub->is_vtable_stub(), "should never see AbstractMethodErrors from vtable-type VtableStubs"); | |
753 return StubRoutines::throw_AbstractMethodError_entry(); | |
754 } else { | |
755 return StubRoutines::throw_NullPointerException_at_call_entry(); | |
756 } | |
757 } else { | |
758 CodeBlob* cb = CodeCache::find_blob(pc); | |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
356
diff
changeset
|
759 |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
356
diff
changeset
|
760 // If code blob is NULL, then return NULL to signal handler to report the SEGV error. |
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
356
diff
changeset
|
761 if (cb == NULL) return NULL; |
0 | 762 |
763 // Exception happened in CodeCache. Must be either: | |
764 // 1. Inline-cache check in C2I handler blob, | |
765 // 2. Inline-cache check in nmethod, or | |
766 // 3. Implict null exception in nmethod | |
767 | |
768 if (!cb->is_nmethod()) { | |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1295
diff
changeset
|
769 guarantee(cb->is_adapter_blob() || cb->is_method_handles_adapter_blob(), |
465
dc16daa0329d
6739363: Xcheck jni doesn't check native function arguments
poonam
parents:
356
diff
changeset
|
770 "exception happened outside interpreter, nmethods and vtable stubs (1)"); |
0 | 771 // There is no handler here, so we will simply unwind. |
772 return StubRoutines::throw_NullPointerException_at_call_entry(); | |
773 } | |
774 | |
775 // Otherwise, it's an nmethod. Consult its exception handlers. | |
776 nmethod* nm = (nmethod*)cb; | |
777 if (nm->inlinecache_check_contains(pc)) { | |
778 // exception happened inside inline-cache check code | |
779 // => the nmethod is not yet active (i.e., the frame | |
780 // is not set up yet) => use return address pushed by | |
781 // caller => don't push another return address | |
782 return StubRoutines::throw_NullPointerException_at_call_entry(); | |
783 } | |
784 | |
785 #ifndef PRODUCT | |
786 _implicit_null_throws++; | |
787 #endif | |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1378
diff
changeset
|
788 if (UseC1X) { |
2607
008adfd6d850
Fixed the stateBefore of invokes and monitorenter instructions to include the arguments of the instruction.
Thomas Wuerthinger <thomas@wuerthinger.net>
parents:
2605
diff
changeset
|
789 target_pc = deoptimization_continuation(thread, pc, nm); |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1378
diff
changeset
|
790 } else { |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1378
diff
changeset
|
791 target_pc = nm->continuation_for_implicit_exception(pc); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1378
diff
changeset
|
792 } |
1250 | 793 // If there's an unexpected fault, target_pc might be NULL, |
794 // in which case we want to fall through into the normal | |
795 // error handling code. | |
0 | 796 } |
797 | |
798 break; // fall through | |
799 } | |
800 | |
801 | |
802 case IMPLICIT_DIVIDE_BY_ZERO: { | |
803 nmethod* nm = CodeCache::find_nmethod(pc); | |
804 guarantee(nm != NULL, "must have containing nmethod for implicit division-by-zero exceptions"); | |
805 #ifndef PRODUCT | |
806 _implicit_div0_throws++; | |
807 #endif | |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1378
diff
changeset
|
808 if (UseC1X) { |
2494
e88293edf07c
Fixed an issue with alignment of double/long values in the code buffer. Can now run Scimark again.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
2491
diff
changeset
|
809 if (TraceSignals) { |
e88293edf07c
Fixed an issue with alignment of double/long values in the code buffer. Can now run Scimark again.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
2491
diff
changeset
|
810 tty->print_cr("c1x implicit div0"); |
e88293edf07c
Fixed an issue with alignment of double/long values in the code buffer. Can now run Scimark again.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
2491
diff
changeset
|
811 } |
1429
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1378
diff
changeset
|
812 target_pc = Runtime1::entry_for(Runtime1::c1x_throw_div0_exception_id); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1378
diff
changeset
|
813 } else { |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1378
diff
changeset
|
814 target_pc = nm->continuation_for_implicit_exception(pc); |
abc670a709dc
* -XX:TraceC1X=0...5 controls the native c1x tracing
Lukas Stadler <lukas.stadler@oracle.com>
parents:
1378
diff
changeset
|
815 } |
1250 | 816 // If there's an unexpected fault, target_pc might be NULL, |
817 // in which case we want to fall through into the normal | |
818 // error handling code. | |
0 | 819 break; // fall through |
820 } | |
821 | |
822 default: ShouldNotReachHere(); | |
823 } | |
824 | |
825 assert(exception_kind == IMPLICIT_NULL || exception_kind == IMPLICIT_DIVIDE_BY_ZERO, "wrong implicit exception kind"); | |
826 | |
827 // for AbortVMOnException flag | |
828 NOT_PRODUCT(Exceptions::debug_check_abort("java.lang.NullPointerException")); | |
829 if (exception_kind == IMPLICIT_NULL) { | |
830 Events::log("Implicit null exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc); | |
831 } else { | |
832 Events::log("Implicit division by zero exception at " INTPTR_FORMAT " to " INTPTR_FORMAT, pc, target_pc); | |
833 } | |
834 return target_pc; | |
835 } | |
836 | |
837 ShouldNotReachHere(); | |
838 return NULL; | |
839 } | |
840 | |
841 | |
842 JNI_ENTRY(void, throw_unsatisfied_link_error(JNIEnv* env, ...)) | |
843 { | |
844 THROW(vmSymbols::java_lang_UnsatisfiedLinkError()); | |
845 } | |
846 JNI_END | |
847 | |
848 | |
849 address SharedRuntime::native_method_throw_unsatisfied_link_error_entry() { | |
850 return CAST_FROM_FN_PTR(address, &throw_unsatisfied_link_error); | |
851 } | |
852 | |
853 | |
854 #ifndef PRODUCT | |
855 JRT_ENTRY(intptr_t, SharedRuntime::trace_bytecode(JavaThread* thread, intptr_t preserve_this_value, intptr_t tos, intptr_t tos2)) | |
856 const frame f = thread->last_frame(); | |
857 assert(f.is_interpreted_frame(), "must be an interpreted frame"); | |
858 #ifndef PRODUCT | |
859 methodHandle mh(THREAD, f.interpreter_frame_method()); | |
860 BytecodeTracer::trace(mh, f.interpreter_frame_bcp(), tos, tos2); | |
861 #endif // !PRODUCT | |
862 return preserve_this_value; | |
863 JRT_END | |
864 #endif // !PRODUCT | |
865 | |
866 | |
867 JRT_ENTRY(void, SharedRuntime::yield_all(JavaThread* thread, int attempts)) | |
868 os::yield_all(attempts); | |
869 JRT_END | |
870 | |
871 | |
872 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::register_finalizer(JavaThread* thread, oopDesc* obj)) | |
873 assert(obj->is_oop(), "must be a valid oop"); | |
874 assert(obj->klass()->klass_part()->has_finalizer(), "shouldn't be here otherwise"); | |
875 instanceKlass::register_finalizer(instanceOop(obj), CHECK); | |
876 JRT_END | |
877 | |
878 | |
879 jlong SharedRuntime::get_java_tid(Thread* thread) { | |
880 if (thread != NULL) { | |
881 if (thread->is_Java_thread()) { | |
882 oop obj = ((JavaThread*)thread)->threadObj(); | |
883 return (obj == NULL) ? 0 : java_lang_Thread::thread_id(obj); | |
884 } | |
885 } | |
886 return 0; | |
887 } | |
888 | |
889 /** | |
890 * This function ought to be a void function, but cannot be because | |
891 * it gets turned into a tail-call on sparc, which runs into dtrace bug | |
892 * 6254741. Once that is fixed we can remove the dummy return value. | |
893 */ | |
894 int SharedRuntime::dtrace_object_alloc(oopDesc* o) { | |
895 return dtrace_object_alloc_base(Thread::current(), o); | |
896 } | |
897 | |
898 int SharedRuntime::dtrace_object_alloc_base(Thread* thread, oopDesc* o) { | |
899 assert(DTraceAllocProbes, "wrong call"); | |
900 Klass* klass = o->blueprint(); | |
901 int size = o->size(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
902 Symbol* name = klass->name(); |
0 | 903 HS_DTRACE_PROBE4(hotspot, object__alloc, get_java_tid(thread), |
904 name->bytes(), name->utf8_length(), size * HeapWordSize); | |
905 return 0; | |
906 } | |
907 | |
908 JRT_LEAF(int, SharedRuntime::dtrace_method_entry( | |
909 JavaThread* thread, methodOopDesc* method)) | |
910 assert(DTraceMethodProbes, "wrong call"); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
911 Symbol* kname = method->klass_name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
912 Symbol* name = method->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
913 Symbol* sig = method->signature(); |
0 | 914 HS_DTRACE_PROBE7(hotspot, method__entry, get_java_tid(thread), |
915 kname->bytes(), kname->utf8_length(), | |
916 name->bytes(), name->utf8_length(), | |
917 sig->bytes(), sig->utf8_length()); | |
918 return 0; | |
919 JRT_END | |
920 | |
921 JRT_LEAF(int, SharedRuntime::dtrace_method_exit( | |
922 JavaThread* thread, methodOopDesc* method)) | |
923 assert(DTraceMethodProbes, "wrong call"); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
924 Symbol* kname = method->klass_name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
925 Symbol* name = method->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
926 Symbol* sig = method->signature(); |
0 | 927 HS_DTRACE_PROBE7(hotspot, method__return, get_java_tid(thread), |
928 kname->bytes(), kname->utf8_length(), | |
929 name->bytes(), name->utf8_length(), | |
930 sig->bytes(), sig->utf8_length()); | |
931 return 0; | |
932 JRT_END | |
933 | |
934 | |
935 // Finds receiver, CallInfo (i.e. receiver method), and calling bytecode) | |
936 // for a call current in progress, i.e., arguments has been pushed on stack | |
937 // put callee has not been invoked yet. Used by: resolve virtual/static, | |
938 // vtable updates, etc. Caller frame must be compiled. | |
939 Handle SharedRuntime::find_callee_info(JavaThread* thread, Bytecodes::Code& bc, CallInfo& callinfo, TRAPS) { | |
940 ResourceMark rm(THREAD); | |
941 | |
942 // last java frame on stack (which includes native call frames) | |
943 vframeStream vfst(thread, true); // Do not skip and javaCalls | |
944 | |
945 return find_callee_info_helper(thread, vfst, bc, callinfo, CHECK_(Handle())); | |
946 } | |
947 | |
948 | |
949 // Finds receiver, CallInfo (i.e. receiver method), and calling bytecode | |
950 // for a call current in progress, i.e., arguments has been pushed on stack | |
951 // but callee has not been invoked yet. Caller frame must be compiled. | |
952 Handle SharedRuntime::find_callee_info_helper(JavaThread* thread, | |
953 vframeStream& vfst, | |
954 Bytecodes::Code& bc, | |
955 CallInfo& callinfo, TRAPS) { | |
956 Handle receiver; | |
957 Handle nullHandle; //create a handy null handle for exception returns | |
958 | |
959 assert(!vfst.at_end(), "Java frame must exist"); | |
960 | |
961 // Find caller and bci from vframe | |
962 methodHandle caller (THREAD, vfst.method()); | |
963 int bci = vfst.bci(); | |
964 | |
965 // Find bytecode | |
2142 | 966 Bytecode_invoke bytecode(caller, bci); |
967 bc = bytecode.java_code(); | |
968 int bytecode_index = bytecode.index(); | |
0 | 969 |
970 // Find receiver for non-static call | |
971 if (bc != Bytecodes::_invokestatic) { | |
972 // This register map must be update since we need to find the receiver for | |
973 // compiled frames. The receiver might be in a register. | |
974 RegisterMap reg_map2(thread); | |
975 frame stubFrame = thread->last_frame(); | |
976 // Caller-frame is a compiled frame | |
977 frame callerFrame = stubFrame.sender(®_map2); | |
978 | |
2142 | 979 methodHandle callee = bytecode.static_target(CHECK_(nullHandle)); |
0 | 980 if (callee.is_null()) { |
981 THROW_(vmSymbols::java_lang_NoSuchMethodException(), nullHandle); | |
982 } | |
983 // Retrieve from a compiled argument list | |
984 receiver = Handle(THREAD, callerFrame.retrieve_receiver(®_map2)); | |
985 | |
986 if (receiver.is_null()) { | |
987 THROW_(vmSymbols::java_lang_NullPointerException(), nullHandle); | |
988 } | |
989 } | |
990 | |
991 // Resolve method. This is parameterized by bytecode. | |
992 constantPoolHandle constants (THREAD, caller->constants()); | |
993 assert (receiver.is_null() || receiver->is_oop(), "wrong receiver"); | |
994 LinkResolver::resolve_invoke(callinfo, receiver, constants, bytecode_index, bc, CHECK_(nullHandle)); | |
995 | |
996 #ifdef ASSERT | |
997 // Check that the receiver klass is of the right subtype and that it is initialized for virtual calls | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
845
diff
changeset
|
998 if (bc != Bytecodes::_invokestatic && bc != Bytecodes::_invokedynamic) { |
0 | 999 assert(receiver.not_null(), "should have thrown exception"); |
1000 KlassHandle receiver_klass (THREAD, receiver->klass()); | |
1001 klassOop rk = constants->klass_ref_at(bytecode_index, CHECK_(nullHandle)); | |
1002 // klass is already loaded | |
1003 KlassHandle static_receiver_klass (THREAD, rk); | |
1004 assert(receiver_klass->is_subtype_of(static_receiver_klass()), "actual receiver must be subclass of static receiver klass"); | |
1005 if (receiver_klass->oop_is_instance()) { | |
1006 if (instanceKlass::cast(receiver_klass())->is_not_initialized()) { | |
1007 tty->print_cr("ERROR: Klass not yet initialized!!"); | |
1008 receiver_klass.print(); | |
1009 } | |
1010 assert (!instanceKlass::cast(receiver_klass())->is_not_initialized(), "receiver_klass must be initialized"); | |
1011 } | |
1012 } | |
1013 #endif | |
1014 | |
1015 return receiver; | |
1016 } | |
1017 | |
1018 methodHandle SharedRuntime::find_callee_method(JavaThread* thread, TRAPS) { | |
1019 ResourceMark rm(THREAD); | |
1020 // We need first to check if any Java activations (compiled, interpreted) | |
1021 // exist on the stack since last JavaCall. If not, we need | |
1022 // to get the target method from the JavaCall wrapper. | |
1023 vframeStream vfst(thread, true); // Do not skip any javaCalls | |
1024 methodHandle callee_method; | |
1025 if (vfst.at_end()) { | |
1026 // No Java frames were found on stack since we did the JavaCall. | |
1027 // Hence the stack can only contain an entry_frame. We need to | |
1028 // find the target method from the stub frame. | |
1029 RegisterMap reg_map(thread, false); | |
1030 frame fr = thread->last_frame(); | |
1031 assert(fr.is_runtime_frame(), "must be a runtimeStub"); | |
1032 fr = fr.sender(®_map); | |
1033 assert(fr.is_entry_frame(), "must be"); | |
1034 // fr is now pointing to the entry frame. | |
1035 callee_method = methodHandle(THREAD, fr.entry_frame_call_wrapper()->callee_method()); | |
1036 assert(fr.entry_frame_call_wrapper()->receiver() == NULL || !callee_method->is_static(), "non-null receiver for static call??"); | |
1037 } else { | |
1038 Bytecodes::Code bc; | |
1039 CallInfo callinfo; | |
1040 find_callee_info_helper(thread, vfst, bc, callinfo, CHECK_(methodHandle())); | |
1041 callee_method = callinfo.selected_method(); | |
1042 } | |
1043 assert(callee_method()->is_method(), "must be"); | |
1044 return callee_method; | |
1045 } | |
1046 | |
1047 // Resolves a call. | |
1048 methodHandle SharedRuntime::resolve_helper(JavaThread *thread, | |
1049 bool is_virtual, | |
1050 bool is_optimized, TRAPS) { | |
1051 methodHandle callee_method; | |
1052 callee_method = resolve_sub_helper(thread, is_virtual, is_optimized, THREAD); | |
1053 if (JvmtiExport::can_hotswap_or_post_breakpoint()) { | |
1054 int retry_count = 0; | |
1055 while (!HAS_PENDING_EXCEPTION && callee_method->is_old() && | |
1142 | 1056 callee_method->method_holder() != SystemDictionary::Object_klass()) { |
0 | 1057 // If has a pending exception then there is no need to re-try to |
1058 // resolve this method. | |
1059 // If the method has been redefined, we need to try again. | |
1060 // Hack: we have no way to update the vtables of arrays, so don't | |
1061 // require that java.lang.Object has been updated. | |
1062 | |
1063 // It is very unlikely that method is redefined more than 100 times | |
1064 // in the middle of resolve. If it is looping here more than 100 times | |
1065 // means then there could be a bug here. | |
1066 guarantee((retry_count++ < 100), | |
1067 "Could not resolve to latest version of redefined method"); | |
1068 // method is redefined in the middle of resolve so re-try. | |
1069 callee_method = resolve_sub_helper(thread, is_virtual, is_optimized, THREAD); | |
1070 } | |
1071 } | |
1072 return callee_method; | |
1073 } | |
1074 | |
1075 // Resolves a call. The compilers generate code for calls that go here | |
1076 // and are patched with the real destination of the call. | |
1077 methodHandle SharedRuntime::resolve_sub_helper(JavaThread *thread, | |
1078 bool is_virtual, | |
1079 bool is_optimized, TRAPS) { | |
1080 | |
1081 ResourceMark rm(thread); | |
1082 RegisterMap cbl_map(thread, false); | |
1083 frame caller_frame = thread->last_frame().sender(&cbl_map); | |
1084 | |
1295 | 1085 CodeBlob* caller_cb = caller_frame.cb(); |
1086 guarantee(caller_cb != NULL && caller_cb->is_nmethod(), "must be called from nmethod"); | |
1087 nmethod* caller_nm = caller_cb->as_nmethod_or_null(); | |
0 | 1088 // make sure caller is not getting deoptimized |
1089 // and removed before we are done with it. | |
1090 // CLEANUP - with lazy deopt shouldn't need this lock | |
1295 | 1091 nmethodLocker caller_lock(caller_nm); |
0 | 1092 |
1093 | |
1094 // determine call info & receiver | |
1095 // note: a) receiver is NULL for static calls | |
1096 // b) an exception is thrown if receiver is NULL for non-static calls | |
1097 CallInfo call_info; | |
1098 Bytecodes::Code invoke_code = Bytecodes::_illegal; | |
1099 Handle receiver = find_callee_info(thread, invoke_code, | |
1100 call_info, CHECK_(methodHandle())); | |
1101 methodHandle callee_method = call_info.selected_method(); | |
1102 | |
1103 assert((!is_virtual && invoke_code == Bytecodes::_invokestatic) || | |
1104 ( is_virtual && invoke_code != Bytecodes::_invokestatic), "inconsistent bytecode"); | |
1105 | |
1106 #ifndef PRODUCT | |
1107 // tracing/debugging/statistics | |
1108 int *addr = (is_optimized) ? (&_resolve_opt_virtual_ctr) : | |
1109 (is_virtual) ? (&_resolve_virtual_ctr) : | |
1110 (&_resolve_static_ctr); | |
1111 Atomic::inc(addr); | |
1112 | |
1113 if (TraceCallFixup) { | |
1114 ResourceMark rm(thread); | |
1115 tty->print("resolving %s%s (%s) call to", | |
1116 (is_optimized) ? "optimized " : "", (is_virtual) ? "virtual" : "static", | |
1117 Bytecodes::name(invoke_code)); | |
1118 callee_method->print_short_name(tty); | |
1119 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code()); | |
1120 } | |
1121 #endif | |
1122 | |
1295 | 1123 // JSR 292 |
1124 // If the resolved method is a MethodHandle invoke target the call | |
1125 // site must be a MethodHandle call site. | |
1126 if (callee_method->is_method_handle_invoke()) { | |
1127 assert(caller_nm->is_method_handle_return(caller_frame.pc()), "must be MH call site"); | |
1128 } | |
1129 | |
0 | 1130 // Compute entry points. This might require generation of C2I converter |
1131 // frames, so we cannot be holding any locks here. Furthermore, the | |
1132 // computation of the entry points is independent of patching the call. We | |
1133 // always return the entry-point, but we only patch the stub if the call has | |
1134 // not been deoptimized. Return values: For a virtual call this is an | |
1135 // (cached_oop, destination address) pair. For a static call/optimized | |
1136 // virtual this is just a destination address. | |
1137 | |
1138 StaticCallInfo static_call_info; | |
1139 CompiledICInfo virtual_call_info; | |
1140 | |
1141 // Make sure the callee nmethod does not get deoptimized and removed before | |
1142 // we are done patching the code. | |
1295 | 1143 nmethod* callee_nm = callee_method->code(); |
1144 nmethodLocker nl_callee(callee_nm); | |
0 | 1145 #ifdef ASSERT |
1295 | 1146 address dest_entry_point = callee_nm == NULL ? 0 : callee_nm->entry_point(); // used below |
0 | 1147 #endif |
1148 | |
1149 if (is_virtual) { | |
1150 assert(receiver.not_null(), "sanity check"); | |
1151 bool static_bound = call_info.resolved_method()->can_be_statically_bound(); | |
1152 KlassHandle h_klass(THREAD, receiver->klass()); | |
1153 CompiledIC::compute_monomorphic_entry(callee_method, h_klass, | |
1154 is_optimized, static_bound, virtual_call_info, | |
1155 CHECK_(methodHandle())); | |
1156 } else { | |
1157 // static call | |
1158 CompiledStaticCall::compute_entry(callee_method, static_call_info); | |
1159 } | |
1160 | |
1161 // grab lock, check for deoptimization and potentially patch caller | |
1162 { | |
1163 MutexLocker ml_patch(CompiledIC_lock); | |
1164 | |
1165 // Now that we are ready to patch if the methodOop was redefined then | |
1166 // don't update call site and let the caller retry. | |
1167 | |
1168 if (!callee_method->is_old()) { | |
1169 #ifdef ASSERT | |
1170 // We must not try to patch to jump to an already unloaded method. | |
1171 if (dest_entry_point != 0) { | |
1172 assert(CodeCache::find_blob(dest_entry_point) != NULL, | |
1173 "should not unload nmethod while locked"); | |
1174 } | |
1175 #endif | |
1176 if (is_virtual) { | |
1177 CompiledIC* inline_cache = CompiledIC_before(caller_frame.pc()); | |
1178 if (inline_cache->is_clean()) { | |
1179 inline_cache->set_to_monomorphic(virtual_call_info); | |
1180 } | |
1181 } else { | |
1182 CompiledStaticCall* ssc = compiledStaticCall_before(caller_frame.pc()); | |
1183 if (ssc->is_clean()) ssc->set(static_call_info); | |
1184 } | |
1185 } | |
1186 | |
1187 } // unlock CompiledIC_lock | |
1188 | |
1189 return callee_method; | |
1190 } | |
1191 | |
1192 | |
1193 // Inline caches exist only in compiled code | |
1194 JRT_BLOCK_ENTRY(address, SharedRuntime::handle_wrong_method_ic_miss(JavaThread* thread)) | |
1195 #ifdef ASSERT | |
1196 RegisterMap reg_map(thread, false); | |
1197 frame stub_frame = thread->last_frame(); | |
1198 assert(stub_frame.is_runtime_frame(), "sanity check"); | |
1199 frame caller_frame = stub_frame.sender(®_map); | |
1200 assert(!caller_frame.is_interpreted_frame() && !caller_frame.is_entry_frame(), "unexpected frame"); | |
1201 #endif /* ASSERT */ | |
1202 | |
1203 methodHandle callee_method; | |
1204 JRT_BLOCK | |
1205 callee_method = SharedRuntime::handle_ic_miss_helper(thread, CHECK_NULL); | |
1206 // Return methodOop through TLS | |
1207 thread->set_vm_result(callee_method()); | |
1208 JRT_BLOCK_END | |
1209 // return compiled code entry point after potential safepoints | |
1210 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!"); | |
1211 return callee_method->verified_code_entry(); | |
1212 JRT_END | |
1213 | |
1214 | |
1215 // Handle call site that has been made non-entrant | |
1216 JRT_BLOCK_ENTRY(address, SharedRuntime::handle_wrong_method(JavaThread* thread)) | |
1217 // 6243940 We might end up in here if the callee is deoptimized | |
1218 // as we race to call it. We don't want to take a safepoint if | |
1219 // the caller was interpreted because the caller frame will look | |
1220 // interpreted to the stack walkers and arguments are now | |
1221 // "compiled" so it is much better to make this transition | |
1222 // invisible to the stack walking code. The i2c path will | |
1223 // place the callee method in the callee_target. It is stashed | |
1224 // there because if we try and find the callee by normal means a | |
1225 // safepoint is possible and have trouble gc'ing the compiled args. | |
1226 RegisterMap reg_map(thread, false); | |
1227 frame stub_frame = thread->last_frame(); | |
1228 assert(stub_frame.is_runtime_frame(), "sanity check"); | |
1229 frame caller_frame = stub_frame.sender(®_map); | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
845
diff
changeset
|
1230 |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
845
diff
changeset
|
1231 // MethodHandle invokes don't have a CompiledIC and should always |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
845
diff
changeset
|
1232 // simply redispatch to the callee_target. |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
845
diff
changeset
|
1233 address sender_pc = caller_frame.pc(); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
845
diff
changeset
|
1234 CodeBlob* sender_cb = caller_frame.cb(); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
845
diff
changeset
|
1235 nmethod* sender_nm = sender_cb->as_nmethod_or_null(); |
1204 | 1236 bool is_mh_invoke_via_adapter = false; // Direct c2c call or via adapter? |
1237 if (sender_nm != NULL && sender_nm->is_method_handle_return(sender_pc)) { | |
1238 // If the callee_target is set, then we have come here via an i2c | |
1239 // adapter. | |
1240 methodOop callee = thread->callee_target(); | |
1241 if (callee != NULL) { | |
1242 assert(callee->is_method(), "sanity"); | |
1243 is_mh_invoke_via_adapter = true; | |
1244 } | |
1245 } | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
845
diff
changeset
|
1246 |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
845
diff
changeset
|
1247 if (caller_frame.is_interpreted_frame() || |
1204 | 1248 caller_frame.is_entry_frame() || |
1249 is_mh_invoke_via_adapter) { | |
0 | 1250 methodOop callee = thread->callee_target(); |
1251 guarantee(callee != NULL && callee->is_method(), "bad handshake"); | |
1252 thread->set_vm_result(callee); | |
1253 thread->set_callee_target(NULL); | |
1254 return callee->get_c2i_entry(); | |
1255 } | |
1256 | |
1257 // Must be compiled to compiled path which is safe to stackwalk | |
1258 methodHandle callee_method; | |
1259 JRT_BLOCK | |
1260 // Force resolving of caller (if we called from compiled frame) | |
1261 callee_method = SharedRuntime::reresolve_call_site(thread, CHECK_NULL); | |
1262 thread->set_vm_result(callee_method()); | |
1263 JRT_BLOCK_END | |
1264 // return compiled code entry point after potential safepoints | |
1265 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!"); | |
1266 return callee_method->verified_code_entry(); | |
1267 JRT_END | |
1268 | |
1269 | |
1270 // resolve a static call and patch code | |
1271 JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_static_call_C(JavaThread *thread )) | |
1272 methodHandle callee_method; | |
1273 JRT_BLOCK | |
1274 callee_method = SharedRuntime::resolve_helper(thread, false, false, CHECK_NULL); | |
1275 thread->set_vm_result(callee_method()); | |
1276 JRT_BLOCK_END | |
1277 // return compiled code entry point after potential safepoints | |
1278 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!"); | |
1279 return callee_method->verified_code_entry(); | |
1280 JRT_END | |
1281 | |
1282 | |
1283 // resolve virtual call and update inline cache to monomorphic | |
1284 JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_virtual_call_C(JavaThread *thread )) | |
1285 methodHandle callee_method; | |
1286 JRT_BLOCK | |
1287 callee_method = SharedRuntime::resolve_helper(thread, true, false, CHECK_NULL); | |
1288 thread->set_vm_result(callee_method()); | |
1289 JRT_BLOCK_END | |
1290 // return compiled code entry point after potential safepoints | |
1291 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!"); | |
1292 return callee_method->verified_code_entry(); | |
1293 JRT_END | |
1294 | |
1295 | |
1296 // Resolve a virtual call that can be statically bound (e.g., always | |
1297 // monomorphic, so it has no inline cache). Patch code to resolved target. | |
1298 JRT_BLOCK_ENTRY(address, SharedRuntime::resolve_opt_virtual_call_C(JavaThread *thread)) | |
1299 methodHandle callee_method; | |
1300 JRT_BLOCK | |
1301 callee_method = SharedRuntime::resolve_helper(thread, true, true, CHECK_NULL); | |
1302 thread->set_vm_result(callee_method()); | |
1303 JRT_BLOCK_END | |
1304 // return compiled code entry point after potential safepoints | |
1305 assert(callee_method->verified_code_entry() != NULL, " Jump to zero!"); | |
1306 return callee_method->verified_code_entry(); | |
1307 JRT_END | |
1308 | |
1309 | |
1310 | |
1311 | |
1312 | |
1313 methodHandle SharedRuntime::handle_ic_miss_helper(JavaThread *thread, TRAPS) { | |
1314 ResourceMark rm(thread); | |
1315 CallInfo call_info; | |
1316 Bytecodes::Code bc; | |
1317 | |
1318 // receiver is NULL for static calls. An exception is thrown for NULL | |
1319 // receivers for non-static calls | |
1320 Handle receiver = find_callee_info(thread, bc, call_info, | |
1321 CHECK_(methodHandle())); | |
1322 // Compiler1 can produce virtual call sites that can actually be statically bound | |
1323 // If we fell thru to below we would think that the site was going megamorphic | |
1324 // when in fact the site can never miss. Worse because we'd think it was megamorphic | |
1325 // we'd try and do a vtable dispatch however methods that can be statically bound | |
1326 // don't have vtable entries (vtable_index < 0) and we'd blow up. So we force a | |
1327 // reresolution of the call site (as if we did a handle_wrong_method and not an | |
1328 // plain ic_miss) and the site will be converted to an optimized virtual call site | |
1329 // never to miss again. I don't believe C2 will produce code like this but if it | |
1330 // did this would still be the correct thing to do for it too, hence no ifdef. | |
1331 // | |
1332 if (call_info.resolved_method()->can_be_statically_bound()) { | |
1333 methodHandle callee_method = SharedRuntime::reresolve_call_site(thread, CHECK_(methodHandle())); | |
1334 if (TraceCallFixup) { | |
1335 RegisterMap reg_map(thread, false); | |
1336 frame caller_frame = thread->last_frame().sender(®_map); | |
1337 ResourceMark rm(thread); | |
1338 tty->print("converting IC miss to reresolve (%s) call to", Bytecodes::name(bc)); | |
1339 callee_method->print_short_name(tty); | |
1340 tty->print_cr(" from pc: " INTPTR_FORMAT, caller_frame.pc()); | |
1341 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code()); | |
1342 } | |
1343 return callee_method; | |
1344 } | |
1345 | |
1346 methodHandle callee_method = call_info.selected_method(); | |
1347 | |
1348 bool should_be_mono = false; | |
1349 | |
1350 #ifndef PRODUCT | |
1351 Atomic::inc(&_ic_miss_ctr); | |
1352 | |
1353 // Statistics & Tracing | |
1354 if (TraceCallFixup) { | |
1355 ResourceMark rm(thread); | |
1356 tty->print("IC miss (%s) call to", Bytecodes::name(bc)); | |
1357 callee_method->print_short_name(tty); | |
1358 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code()); | |
1359 } | |
1360 | |
1361 if (ICMissHistogram) { | |
1362 MutexLocker m(VMStatistic_lock); | |
1363 RegisterMap reg_map(thread, false); | |
1364 frame f = thread->last_frame().real_sender(®_map);// skip runtime stub | |
1365 // produce statistics under the lock | |
1366 trace_ic_miss(f.pc()); | |
1367 } | |
1368 #endif | |
1369 | |
1370 // install an event collector so that when a vtable stub is created the | |
1371 // profiler can be notified via a DYNAMIC_CODE_GENERATED event. The | |
1372 // event can't be posted when the stub is created as locks are held | |
1373 // - instead the event will be deferred until the event collector goes | |
1374 // out of scope. | |
1375 JvmtiDynamicCodeEventCollector event_collector; | |
1376 | |
1377 // Update inline cache to megamorphic. Skip update if caller has been | |
1378 // made non-entrant or we are called from interpreted. | |
1379 { MutexLocker ml_patch (CompiledIC_lock); | |
1380 RegisterMap reg_map(thread, false); | |
1381 frame caller_frame = thread->last_frame().sender(®_map); | |
1382 CodeBlob* cb = caller_frame.cb(); | |
1383 if (cb->is_nmethod() && ((nmethod*)cb)->is_in_use()) { | |
1384 // Not a non-entrant nmethod, so find inline_cache | |
1385 CompiledIC* inline_cache = CompiledIC_before(caller_frame.pc()); | |
1386 bool should_be_mono = false; | |
1387 if (inline_cache->is_optimized()) { | |
1388 if (TraceCallFixup) { | |
1389 ResourceMark rm(thread); | |
1390 tty->print("OPTIMIZED IC miss (%s) call to", Bytecodes::name(bc)); | |
1391 callee_method->print_short_name(tty); | |
1392 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code()); | |
1393 } | |
1394 should_be_mono = true; | |
1395 } else { | |
1396 compiledICHolderOop ic_oop = (compiledICHolderOop) inline_cache->cached_oop(); | |
1397 if ( ic_oop != NULL && ic_oop->is_compiledICHolder()) { | |
1398 | |
1399 if (receiver()->klass() == ic_oop->holder_klass()) { | |
1400 // This isn't a real miss. We must have seen that compiled code | |
1401 // is now available and we want the call site converted to a | |
1402 // monomorphic compiled call site. | |
1403 // We can't assert for callee_method->code() != NULL because it | |
1404 // could have been deoptimized in the meantime | |
1405 if (TraceCallFixup) { | |
1406 ResourceMark rm(thread); | |
1407 tty->print("FALSE IC miss (%s) converting to compiled call to", Bytecodes::name(bc)); | |
1408 callee_method->print_short_name(tty); | |
1409 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code()); | |
1410 } | |
1411 should_be_mono = true; | |
1412 } | |
1413 } | |
1414 } | |
1415 | |
1416 if (should_be_mono) { | |
1417 | |
1418 // We have a path that was monomorphic but was going interpreted | |
1419 // and now we have (or had) a compiled entry. We correct the IC | |
1420 // by using a new icBuffer. | |
1421 CompiledICInfo info; | |
1422 KlassHandle receiver_klass(THREAD, receiver()->klass()); | |
1423 inline_cache->compute_monomorphic_entry(callee_method, | |
1424 receiver_klass, | |
1425 inline_cache->is_optimized(), | |
1426 false, | |
1427 info, CHECK_(methodHandle())); | |
1428 inline_cache->set_to_monomorphic(info); | |
1429 } else if (!inline_cache->is_megamorphic() && !inline_cache->is_clean()) { | |
1430 // Change to megamorphic | |
1431 inline_cache->set_to_megamorphic(&call_info, bc, CHECK_(methodHandle())); | |
1432 } else { | |
1433 // Either clean or megamorphic | |
1434 } | |
1435 } | |
1436 } // Release CompiledIC_lock | |
1437 | |
1438 return callee_method; | |
1439 } | |
1440 | |
1441 // | |
1442 // Resets a call-site in compiled code so it will get resolved again. | |
1443 // This routines handles both virtual call sites, optimized virtual call | |
1444 // sites, and static call sites. Typically used to change a call sites | |
1445 // destination from compiled to interpreted. | |
1446 // | |
1447 methodHandle SharedRuntime::reresolve_call_site(JavaThread *thread, TRAPS) { | |
1448 ResourceMark rm(thread); | |
1449 RegisterMap reg_map(thread, false); | |
1450 frame stub_frame = thread->last_frame(); | |
1451 assert(stub_frame.is_runtime_frame(), "must be a runtimeStub"); | |
1452 frame caller = stub_frame.sender(®_map); | |
1453 | |
1454 // Do nothing if the frame isn't a live compiled frame. | |
1455 // nmethod could be deoptimized by the time we get here | |
1456 // so no update to the caller is needed. | |
1457 | |
1458 if (caller.is_compiled_frame() && !caller.is_deoptimized_frame()) { | |
1459 | |
1460 address pc = caller.pc(); | |
1461 Events::log("update call-site at pc " INTPTR_FORMAT, pc); | |
1462 | |
1463 // Default call_addr is the location of the "basic" call. | |
1464 // Determine the address of the call we a reresolving. With | |
1465 // Inline Caches we will always find a recognizable call. | |
1466 // With Inline Caches disabled we may or may not find a | |
1467 // recognizable call. We will always find a call for static | |
1468 // calls and for optimized virtual calls. For vanilla virtual | |
1469 // calls it depends on the state of the UseInlineCaches switch. | |
1470 // | |
1471 // With Inline Caches disabled we can get here for a virtual call | |
1472 // for two reasons: | |
1473 // 1 - calling an abstract method. The vtable for abstract methods | |
1474 // will run us thru handle_wrong_method and we will eventually | |
1475 // end up in the interpreter to throw the ame. | |
1476 // 2 - a racing deoptimization. We could be doing a vanilla vtable | |
1477 // call and between the time we fetch the entry address and | |
1478 // we jump to it the target gets deoptimized. Similar to 1 | |
1479 // we will wind up in the interprter (thru a c2i with c2). | |
1480 // | |
1481 address call_addr = NULL; | |
1482 { | |
1483 // Get call instruction under lock because another thread may be | |
1484 // busy patching it. | |
1485 MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag); | |
1486 // Location of call instruction | |
1487 if (NativeCall::is_call_before(pc)) { | |
1488 NativeCall *ncall = nativeCall_before(pc); | |
1489 call_addr = ncall->instruction_address(); | |
1490 } | |
1491 } | |
1492 | |
1493 // Check for static or virtual call | |
1494 bool is_static_call = false; | |
1495 nmethod* caller_nm = CodeCache::find_nmethod(pc); | |
1496 // Make sure nmethod doesn't get deoptimized and removed until | |
1497 // this is done with it. | |
1498 // CLEANUP - with lazy deopt shouldn't need this lock | |
1499 nmethodLocker nmlock(caller_nm); | |
1500 | |
1501 if (call_addr != NULL) { | |
1502 RelocIterator iter(caller_nm, call_addr, call_addr+1); | |
1503 int ret = iter.next(); // Get item | |
1504 if (ret) { | |
1505 assert(iter.addr() == call_addr, "must find call"); | |
1506 if (iter.type() == relocInfo::static_call_type) { | |
1507 is_static_call = true; | |
1508 } else { | |
1509 assert(iter.type() == relocInfo::virtual_call_type || | |
1510 iter.type() == relocInfo::opt_virtual_call_type | |
1511 , "unexpected relocInfo. type"); | |
1512 } | |
1513 } else { | |
1514 assert(!UseInlineCaches, "relocation info. must exist for this address"); | |
1515 } | |
1516 | |
1517 // Cleaning the inline cache will force a new resolve. This is more robust | |
1518 // than directly setting it to the new destination, since resolving of calls | |
1519 // is always done through the same code path. (experience shows that it | |
1520 // leads to very hard to track down bugs, if an inline cache gets updated | |
1521 // to a wrong method). It should not be performance critical, since the | |
1522 // resolve is only done once. | |
1523 | |
1524 MutexLocker ml(CompiledIC_lock); | |
1525 // | |
1526 // We do not patch the call site if the nmethod has been made non-entrant | |
1527 // as it is a waste of time | |
1528 // | |
1529 if (caller_nm->is_in_use()) { | |
1530 if (is_static_call) { | |
1531 CompiledStaticCall* ssc= compiledStaticCall_at(call_addr); | |
1532 ssc->set_to_clean(); | |
1533 } else { | |
1534 // compiled, dispatched call (which used to call an interpreted method) | |
1535 CompiledIC* inline_cache = CompiledIC_at(call_addr); | |
1536 inline_cache->set_to_clean(); | |
1537 } | |
1538 } | |
1539 } | |
1540 | |
1541 } | |
1542 | |
1543 methodHandle callee_method = find_callee_method(thread, CHECK_(methodHandle())); | |
1544 | |
1545 | |
1546 #ifndef PRODUCT | |
1547 Atomic::inc(&_wrong_method_ctr); | |
1548 | |
1549 if (TraceCallFixup) { | |
1550 ResourceMark rm(thread); | |
1551 tty->print("handle_wrong_method reresolving call to"); | |
1552 callee_method->print_short_name(tty); | |
1553 tty->print_cr(" code: " INTPTR_FORMAT, callee_method->code()); | |
1554 } | |
1555 #endif | |
1556 | |
1557 return callee_method; | |
1558 } | |
1559 | |
1560 // --------------------------------------------------------------------------- | |
1561 // We are calling the interpreter via a c2i. Normally this would mean that | |
1562 // we were called by a compiled method. However we could have lost a race | |
1563 // where we went int -> i2c -> c2i and so the caller could in fact be | |
1205 | 1564 // interpreted. If the caller is compiled we attempt to patch the caller |
0 | 1565 // so he no longer calls into the interpreter. |
1566 IRT_LEAF(void, SharedRuntime::fixup_callers_callsite(methodOopDesc* method, address caller_pc)) | |
1567 methodOop moop(method); | |
1568 | |
1569 address entry_point = moop->from_compiled_entry(); | |
1570 | |
1571 // It's possible that deoptimization can occur at a call site which hasn't | |
1572 // been resolved yet, in which case this function will be called from | |
1573 // an nmethod that has been patched for deopt and we can ignore the | |
1574 // request for a fixup. | |
1575 // Also it is possible that we lost a race in that from_compiled_entry | |
1576 // is now back to the i2c in that case we don't need to patch and if | |
1577 // we did we'd leap into space because the callsite needs to use | |
1578 // "to interpreter" stub in order to load up the methodOop. Don't | |
1579 // ask me how I know this... | |
1580 | |
1581 CodeBlob* cb = CodeCache::find_blob(caller_pc); | |
1205 | 1582 if (!cb->is_nmethod() || entry_point == moop->get_c2i_entry()) { |
1583 return; | |
1584 } | |
1585 | |
1586 // The check above makes sure this is a nmethod. | |
1587 nmethod* nm = cb->as_nmethod_or_null(); | |
1588 assert(nm, "must be"); | |
1589 | |
1590 // Don't fixup MethodHandle call sites as c2i/i2c adapters are used | |
1591 // to implement MethodHandle actions. | |
1592 if (nm->is_method_handle_return(caller_pc)) { | |
0 | 1593 return; |
1594 } | |
1595 | |
1596 // There is a benign race here. We could be attempting to patch to a compiled | |
1597 // entry point at the same time the callee is being deoptimized. If that is | |
1598 // the case then entry_point may in fact point to a c2i and we'd patch the | |
1599 // call site with the same old data. clear_code will set code() to NULL | |
1600 // at the end of it. If we happen to see that NULL then we can skip trying | |
1601 // to patch. If we hit the window where the callee has a c2i in the | |
1602 // from_compiled_entry and the NULL isn't present yet then we lose the race | |
1603 // and patch the code with the same old data. Asi es la vida. | |
1604 | |
1605 if (moop->code() == NULL) return; | |
1606 | |
1205 | 1607 if (nm->is_in_use()) { |
0 | 1608 |
1609 // Expect to find a native call there (unless it was no-inline cache vtable dispatch) | |
1610 MutexLockerEx ml_patch(Patching_lock, Mutex::_no_safepoint_check_flag); | |
1611 if (NativeCall::is_call_before(caller_pc + frame::pc_return_offset)) { | |
1612 NativeCall *call = nativeCall_before(caller_pc + frame::pc_return_offset); | |
1613 // | |
1614 // bug 6281185. We might get here after resolving a call site to a vanilla | |
1615 // virtual call. Because the resolvee uses the verified entry it may then | |
1616 // see compiled code and attempt to patch the site by calling us. This would | |
1617 // then incorrectly convert the call site to optimized and its downhill from | |
1618 // there. If you're lucky you'll get the assert in the bugid, if not you've | |
1619 // just made a call site that could be megamorphic into a monomorphic site | |
1620 // for the rest of its life! Just another racing bug in the life of | |
1621 // fixup_callers_callsite ... | |
1622 // | |
1563
1a5913bf5e19
6951083: oops and relocations should part of nmethod not CodeBlob
twisti
parents:
1507
diff
changeset
|
1623 RelocIterator iter(nm, call->instruction_address(), call->next_instruction_address()); |
0 | 1624 iter.next(); |
1625 assert(iter.has_current(), "must have a reloc at java call site"); | |
1626 relocInfo::relocType typ = iter.reloc()->type(); | |
1627 if ( typ != relocInfo::static_call_type && | |
1628 typ != relocInfo::opt_virtual_call_type && | |
1629 typ != relocInfo::static_stub_type) { | |
1630 return; | |
1631 } | |
1632 address destination = call->destination(); | |
1633 if (destination != entry_point) { | |
1634 CodeBlob* callee = CodeCache::find_blob(destination); | |
1635 // callee == cb seems weird. It means calling interpreter thru stub. | |
1636 if (callee == cb || callee->is_adapter_blob()) { | |
1637 // static call or optimized virtual | |
1638 if (TraceCallFixup) { | |
1204 | 1639 tty->print("fixup callsite at " INTPTR_FORMAT " to compiled code for", caller_pc); |
0 | 1640 moop->print_short_name(tty); |
1641 tty->print_cr(" to " INTPTR_FORMAT, entry_point); | |
1642 } | |
1643 call->set_destination_mt_safe(entry_point); | |
1644 } else { | |
1645 if (TraceCallFixup) { | |
1646 tty->print("failed to fixup callsite at " INTPTR_FORMAT " to compiled code for", caller_pc); | |
1647 moop->print_short_name(tty); | |
1648 tty->print_cr(" to " INTPTR_FORMAT, entry_point); | |
1649 } | |
1650 // assert is too strong could also be resolve destinations. | |
1651 // assert(InlineCacheBuffer::contains(destination) || VtableStubs::contains(destination), "must be"); | |
1652 } | |
1653 } else { | |
1654 if (TraceCallFixup) { | |
1204 | 1655 tty->print("already patched callsite at " INTPTR_FORMAT " to compiled code for", caller_pc); |
0 | 1656 moop->print_short_name(tty); |
1657 tty->print_cr(" to " INTPTR_FORMAT, entry_point); | |
1658 } | |
1659 } | |
1660 } | |
1661 } | |
1662 | |
1663 IRT_END | |
1664 | |
1665 | |
1666 // same as JVM_Arraycopy, but called directly from compiled code | |
1667 JRT_ENTRY(void, SharedRuntime::slow_arraycopy_C(oopDesc* src, jint src_pos, | |
1668 oopDesc* dest, jint dest_pos, | |
1669 jint length, | |
1670 JavaThread* thread)) { | |
1671 #ifndef PRODUCT | |
1672 _slow_array_copy_ctr++; | |
1673 #endif | |
1674 // Check if we have null pointers | |
1675 if (src == NULL || dest == NULL) { | |
1676 THROW(vmSymbols::java_lang_NullPointerException()); | |
1677 } | |
1678 // Do the copy. The casts to arrayOop are necessary to the copy_array API, | |
1679 // even though the copy_array API also performs dynamic checks to ensure | |
1680 // that src and dest are truly arrays (and are conformable). | |
1681 // The copy_array mechanism is awkward and could be removed, but | |
1682 // the compilers don't call this function except as a last resort, | |
1683 // so it probably doesn't matter. | |
1684 Klass::cast(src->klass())->copy_array((arrayOopDesc*)src, src_pos, | |
1685 (arrayOopDesc*)dest, dest_pos, | |
1686 length, thread); | |
1687 } | |
1688 JRT_END | |
1689 | |
1690 char* SharedRuntime::generate_class_cast_message( | |
1691 JavaThread* thread, const char* objName) { | |
1692 | |
1693 // Get target class name from the checkcast instruction | |
1694 vframeStream vfst(thread, true); | |
1695 assert(!vfst.at_end(), "Java frame must exist"); | |
2142 | 1696 Bytecode_checkcast cc(vfst.method(), vfst.method()->bcp_from(vfst.bci())); |
0 | 1697 Klass* targetKlass = Klass::cast(vfst.method()->constants()->klass_at( |
2142 | 1698 cc.index(), thread)); |
0 | 1699 return generate_class_cast_message(objName, targetKlass->external_name()); |
1700 } | |
1701 | |
710 | 1702 char* SharedRuntime::generate_wrong_method_type_message(JavaThread* thread, |
1703 oopDesc* required, | |
1704 oopDesc* actual) { | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1705 if (TraceMethodHandles) { |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1706 tty->print_cr("WrongMethodType thread="PTR_FORMAT" req="PTR_FORMAT" act="PTR_FORMAT"", |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1707 thread, required, actual); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1708 } |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2405
diff
changeset
|
1709 assert(EnableInvokeDynamic, ""); |
710 | 1710 oop singleKlass = wrong_method_type_is_for_single_argument(thread, required); |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1711 char* message = NULL; |
710 | 1712 if (singleKlass != NULL) { |
1713 const char* objName = "argument or return value"; | |
1714 if (actual != NULL) { | |
1715 // be flexible about the junk passed in: | |
1716 klassOop ak = (actual->is_klass() | |
1717 ? (klassOop)actual | |
1718 : actual->klass()); | |
1719 objName = Klass::cast(ak)->external_name(); | |
1720 } | |
1721 Klass* targetKlass = Klass::cast(required->is_klass() | |
1722 ? (klassOop)required | |
1723 : java_lang_Class::as_klassOop(required)); | |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1724 message = generate_class_cast_message(objName, targetKlass->external_name()); |
710 | 1725 } else { |
1726 // %%% need to get the MethodType string, without messing around too much | |
2461
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1727 const char* desc = NULL; |
710 | 1728 // Get a signature from the invoke instruction |
1729 const char* mhName = "method handle"; | |
1730 const char* targetType = "the required signature"; | |
2461
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1731 int targetArity = -1, mhArity = -1; |
710 | 1732 vframeStream vfst(thread, true); |
1733 if (!vfst.at_end()) { | |
2142 | 1734 Bytecode_invoke call(vfst.method(), vfst.bci()); |
710 | 1735 methodHandle target; |
1736 { | |
1737 EXCEPTION_MARK; | |
2142 | 1738 target = call.static_target(THREAD); |
710 | 1739 if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; } |
1740 } | |
1741 if (target.not_null() | |
1742 && target->is_method_handle_invoke() | |
1743 && required == target->method_handle_type()) { | |
1744 targetType = target->signature()->as_C_string(); | |
2461
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1745 targetArity = ArgumentCount(target->signature()).size(); |
710 | 1746 } |
1747 } | |
2461
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1748 klassOop kignore; int dmf_flags = 0; |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1749 methodOop actual_method = MethodHandles::decode_method(actual, kignore, dmf_flags); |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1750 if ((dmf_flags & ~(MethodHandles::_dmf_has_receiver | |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1751 MethodHandles::_dmf_does_dispatch | |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1752 MethodHandles::_dmf_from_interface)) != 0) |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1753 actual_method = NULL; // MH does extra binds, drops, etc. |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1754 bool has_receiver = ((dmf_flags & MethodHandles::_dmf_has_receiver) != 0); |
710 | 1755 if (actual_method != NULL) { |
2461
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1756 mhName = actual_method->signature()->as_C_string(); |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1757 mhArity = ArgumentCount(actual_method->signature()).size(); |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1758 if (!actual_method->is_static()) mhArity += 1; |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1759 } else if (java_lang_invoke_MethodHandle::is_instance(actual)) { |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1760 oopDesc* mhType = java_lang_invoke_MethodHandle::type(actual); |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1761 mhArity = java_lang_invoke_MethodType::ptype_count(mhType); |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1762 stringStream st; |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1763 java_lang_invoke_MethodType::print_signature(mhType, &st); |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1764 mhName = st.as_string(); |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1765 } |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1766 if (targetArity != -1 && targetArity != mhArity) { |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1767 if (has_receiver && targetArity == mhArity-1) |
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1768 desc = " cannot be called without a receiver argument as "; |
710 | 1769 else |
2461
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1770 desc = " cannot be called with a different arity as "; |
710 | 1771 } |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1772 message = generate_class_cast_message(mhName, targetType, |
2461
758ba0bf7bcc
7012087: JSR 292 Misleading exception message for a non-bound MH for a virtual method
jrose
parents:
2416
diff
changeset
|
1773 desc != NULL ? desc : |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1774 " cannot be called as "); |
710 | 1775 } |
1793
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1776 if (TraceMethodHandles) { |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1777 tty->print_cr("WrongMethodType => message=%s", message); |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1778 } |
d257356e35f0
6939224: MethodHandle.invokeGeneric needs to perform the correct set of conversions
jrose
parents:
1748
diff
changeset
|
1779 return message; |
710 | 1780 } |
1781 | |
1782 oop SharedRuntime::wrong_method_type_is_for_single_argument(JavaThread* thr, | |
1783 oopDesc* required) { | |
1784 if (required == NULL) return NULL; | |
1142 | 1785 if (required->klass() == SystemDictionary::Class_klass()) |
710 | 1786 return required; |
1787 if (required->is_klass()) | |
1788 return Klass::cast(klassOop(required))->java_mirror(); | |
1789 return NULL; | |
1790 } | |
1791 | |
1792 | |
0 | 1793 char* SharedRuntime::generate_class_cast_message( |
710 | 1794 const char* objName, const char* targetKlassName, const char* desc) { |
0 | 1795 size_t msglen = strlen(objName) + strlen(desc) + strlen(targetKlassName) + 1; |
1796 | |
53 | 1797 char* message = NEW_RESOURCE_ARRAY(char, msglen); |
0 | 1798 if (NULL == message) { |
53 | 1799 // Shouldn't happen, but don't cause even more problems if it does |
0 | 1800 message = const_cast<char*>(objName); |
1801 } else { | |
1802 jio_snprintf(message, msglen, "%s%s%s", objName, desc, targetKlassName); | |
1803 } | |
1804 return message; | |
1805 } | |
1806 | |
1807 JRT_LEAF(void, SharedRuntime::reguard_yellow_pages()) | |
1808 (void) JavaThread::current()->reguard_stack(); | |
1809 JRT_END | |
1810 | |
1811 | |
1812 // Handles the uncommon case in locking, i.e., contention or an inflated lock. | |
1813 #ifndef PRODUCT | |
1814 int SharedRuntime::_monitor_enter_ctr=0; | |
1815 #endif | |
1816 JRT_ENTRY_NO_ASYNC(void, SharedRuntime::complete_monitor_locking_C(oopDesc* _obj, BasicLock* lock, JavaThread* thread)) | |
1817 oop obj(_obj); | |
1818 #ifndef PRODUCT | |
1819 _monitor_enter_ctr++; // monitor enter slow | |
1820 #endif | |
1821 if (PrintBiasedLockingStatistics) { | |
1822 Atomic::inc(BiasedLocking::slow_path_entry_count_addr()); | |
1823 } | |
1824 Handle h_obj(THREAD, obj); | |
1825 if (UseBiasedLocking) { | |
1826 // Retry fast entry if bias is revoked to avoid unnecessary inflation | |
1827 ObjectSynchronizer::fast_enter(h_obj, lock, true, CHECK); | |
1828 } else { | |
1829 ObjectSynchronizer::slow_enter(h_obj, lock, CHECK); | |
1830 } | |
1831 assert(!HAS_PENDING_EXCEPTION, "Should have no exception here"); | |
1832 JRT_END | |
1833 | |
1834 #ifndef PRODUCT | |
1835 int SharedRuntime::_monitor_exit_ctr=0; | |
1836 #endif | |
1837 // Handles the uncommon cases of monitor unlocking in compiled code | |
1838 JRT_LEAF(void, SharedRuntime::complete_monitor_unlocking_C(oopDesc* _obj, BasicLock* lock)) | |
1839 oop obj(_obj); | |
1840 #ifndef PRODUCT | |
1841 _monitor_exit_ctr++; // monitor exit slow | |
1842 #endif | |
1843 Thread* THREAD = JavaThread::current(); | |
1844 // I'm not convinced we need the code contained by MIGHT_HAVE_PENDING anymore | |
1845 // testing was unable to ever fire the assert that guarded it so I have removed it. | |
1846 assert(!HAS_PENDING_EXCEPTION, "Do we need code below anymore?"); | |
1847 #undef MIGHT_HAVE_PENDING | |
1848 #ifdef MIGHT_HAVE_PENDING | |
1849 // Save and restore any pending_exception around the exception mark. | |
1850 // While the slow_exit must not throw an exception, we could come into | |
1851 // this routine with one set. | |
1852 oop pending_excep = NULL; | |
1853 const char* pending_file; | |
1854 int pending_line; | |
1855 if (HAS_PENDING_EXCEPTION) { | |
1856 pending_excep = PENDING_EXCEPTION; | |
1857 pending_file = THREAD->exception_file(); | |
1858 pending_line = THREAD->exception_line(); | |
1859 CLEAR_PENDING_EXCEPTION; | |
1860 } | |
1861 #endif /* MIGHT_HAVE_PENDING */ | |
1862 | |
1863 { | |
1864 // Exit must be non-blocking, and therefore no exceptions can be thrown. | |
1865 EXCEPTION_MARK; | |
1866 ObjectSynchronizer::slow_exit(obj, lock, THREAD); | |
1867 } | |
1868 | |
1869 #ifdef MIGHT_HAVE_PENDING | |
1870 if (pending_excep != NULL) { | |
1871 THREAD->set_pending_exception(pending_excep, pending_file, pending_line); | |
1872 } | |
1873 #endif /* MIGHT_HAVE_PENDING */ | |
1874 JRT_END | |
1875 | |
1876 #ifndef PRODUCT | |
1877 | |
1878 void SharedRuntime::print_statistics() { | |
1879 ttyLocker ttyl; | |
1880 if (xtty != NULL) xtty->head("statistics type='SharedRuntime'"); | |
1881 | |
1882 if (_monitor_enter_ctr ) tty->print_cr("%5d monitor enter slow", _monitor_enter_ctr); | |
1883 if (_monitor_exit_ctr ) tty->print_cr("%5d monitor exit slow", _monitor_exit_ctr); | |
1884 if (_throw_null_ctr) tty->print_cr("%5d implicit null throw", _throw_null_ctr); | |
1885 | |
1886 SharedRuntime::print_ic_miss_histogram(); | |
1887 | |
1888 if (CountRemovableExceptions) { | |
1889 if (_nof_removable_exceptions > 0) { | |
1890 Unimplemented(); // this counter is not yet incremented | |
1891 tty->print_cr("Removable exceptions: %d", _nof_removable_exceptions); | |
1892 } | |
1893 } | |
1894 | |
1895 // Dump the JRT_ENTRY counters | |
1896 if( _new_instance_ctr ) tty->print_cr("%5d new instance requires GC", _new_instance_ctr); | |
1897 if( _new_array_ctr ) tty->print_cr("%5d new array requires GC", _new_array_ctr); | |
1898 if( _multi1_ctr ) tty->print_cr("%5d multianewarray 1 dim", _multi1_ctr); | |
1899 if( _multi2_ctr ) tty->print_cr("%5d multianewarray 2 dim", _multi2_ctr); | |
1900 if( _multi3_ctr ) tty->print_cr("%5d multianewarray 3 dim", _multi3_ctr); | |
1901 if( _multi4_ctr ) tty->print_cr("%5d multianewarray 4 dim", _multi4_ctr); | |
1902 if( _multi5_ctr ) tty->print_cr("%5d multianewarray 5 dim", _multi5_ctr); | |
1903 | |
1904 tty->print_cr("%5d inline cache miss in compiled", _ic_miss_ctr ); | |
1905 tty->print_cr("%5d wrong method", _wrong_method_ctr ); | |
1906 tty->print_cr("%5d unresolved static call site", _resolve_static_ctr ); | |
1907 tty->print_cr("%5d unresolved virtual call site", _resolve_virtual_ctr ); | |
1908 tty->print_cr("%5d unresolved opt virtual call site", _resolve_opt_virtual_ctr ); | |
1909 | |
1910 if( _mon_enter_stub_ctr ) tty->print_cr("%5d monitor enter stub", _mon_enter_stub_ctr ); | |
1911 if( _mon_exit_stub_ctr ) tty->print_cr("%5d monitor exit stub", _mon_exit_stub_ctr ); | |
1912 if( _mon_enter_ctr ) tty->print_cr("%5d monitor enter slow", _mon_enter_ctr ); | |
1913 if( _mon_exit_ctr ) tty->print_cr("%5d monitor exit slow", _mon_exit_ctr ); | |
1914 if( _partial_subtype_ctr) tty->print_cr("%5d slow partial subtype", _partial_subtype_ctr ); | |
1915 if( _jbyte_array_copy_ctr ) tty->print_cr("%5d byte array copies", _jbyte_array_copy_ctr ); | |
1916 if( _jshort_array_copy_ctr ) tty->print_cr("%5d short array copies", _jshort_array_copy_ctr ); | |
1917 if( _jint_array_copy_ctr ) tty->print_cr("%5d int array copies", _jint_array_copy_ctr ); | |
1918 if( _jlong_array_copy_ctr ) tty->print_cr("%5d long array copies", _jlong_array_copy_ctr ); | |
1919 if( _oop_array_copy_ctr ) tty->print_cr("%5d oop array copies", _oop_array_copy_ctr ); | |
1920 if( _checkcast_array_copy_ctr ) tty->print_cr("%5d checkcast array copies", _checkcast_array_copy_ctr ); | |
1921 if( _unsafe_array_copy_ctr ) tty->print_cr("%5d unsafe array copies", _unsafe_array_copy_ctr ); | |
1922 if( _generic_array_copy_ctr ) tty->print_cr("%5d generic array copies", _generic_array_copy_ctr ); | |
1923 if( _slow_array_copy_ctr ) tty->print_cr("%5d slow array copies", _slow_array_copy_ctr ); | |
1924 if( _find_handler_ctr ) tty->print_cr("%5d find exception handler", _find_handler_ctr ); | |
1925 if( _rethrow_ctr ) tty->print_cr("%5d rethrow handler", _rethrow_ctr ); | |
1926 | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
1927 AdapterHandlerLibrary::print_statistics(); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
1928 |
0 | 1929 if (xtty != NULL) xtty->tail("statistics"); |
1930 } | |
1931 | |
1932 inline double percent(int x, int y) { | |
1933 return 100.0 * x / MAX2(y, 1); | |
1934 } | |
1935 | |
1936 class MethodArityHistogram { | |
1937 public: | |
1938 enum { MAX_ARITY = 256 }; | |
1939 private: | |
1940 static int _arity_histogram[MAX_ARITY]; // histogram of #args | |
1941 static int _size_histogram[MAX_ARITY]; // histogram of arg size in words | |
1942 static int _max_arity; // max. arity seen | |
1943 static int _max_size; // max. arg size seen | |
1944 | |
1945 static void add_method_to_histogram(nmethod* nm) { | |
1946 methodOop m = nm->method(); | |
1947 ArgumentCount args(m->signature()); | |
1948 int arity = args.size() + (m->is_static() ? 0 : 1); | |
1949 int argsize = m->size_of_parameters(); | |
1950 arity = MIN2(arity, MAX_ARITY-1); | |
1951 argsize = MIN2(argsize, MAX_ARITY-1); | |
1952 int count = nm->method()->compiled_invocation_count(); | |
1953 _arity_histogram[arity] += count; | |
1954 _size_histogram[argsize] += count; | |
1955 _max_arity = MAX2(_max_arity, arity); | |
1956 _max_size = MAX2(_max_size, argsize); | |
1957 } | |
1958 | |
1959 void print_histogram_helper(int n, int* histo, const char* name) { | |
1960 const int N = MIN2(5, n); | |
1961 tty->print_cr("\nHistogram of call arity (incl. rcvr, calls to compiled methods only):"); | |
1962 double sum = 0; | |
1963 double weighted_sum = 0; | |
1964 int i; | |
1965 for (i = 0; i <= n; i++) { sum += histo[i]; weighted_sum += i*histo[i]; } | |
1966 double rest = sum; | |
1967 double percent = sum / 100; | |
1968 for (i = 0; i <= N; i++) { | |
1969 rest -= histo[i]; | |
1970 tty->print_cr("%4d: %7d (%5.1f%%)", i, histo[i], histo[i] / percent); | |
1971 } | |
1972 tty->print_cr("rest: %7d (%5.1f%%))", (int)rest, rest / percent); | |
1973 tty->print_cr("(avg. %s = %3.1f, max = %d)", name, weighted_sum / sum, n); | |
1974 } | |
1975 | |
1976 void print_histogram() { | |
1977 tty->print_cr("\nHistogram of call arity (incl. rcvr, calls to compiled methods only):"); | |
1978 print_histogram_helper(_max_arity, _arity_histogram, "arity"); | |
1979 tty->print_cr("\nSame for parameter size (in words):"); | |
1980 print_histogram_helper(_max_size, _size_histogram, "size"); | |
1981 tty->cr(); | |
1982 } | |
1983 | |
1984 public: | |
1985 MethodArityHistogram() { | |
1986 MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); | |
1987 _max_arity = _max_size = 0; | |
1988 for (int i = 0; i < MAX_ARITY; i++) _arity_histogram[i] = _size_histogram [i] = 0; | |
1989 CodeCache::nmethods_do(add_method_to_histogram); | |
1990 print_histogram(); | |
1991 } | |
1992 }; | |
1993 | |
1994 int MethodArityHistogram::_arity_histogram[MethodArityHistogram::MAX_ARITY]; | |
1995 int MethodArityHistogram::_size_histogram[MethodArityHistogram::MAX_ARITY]; | |
1996 int MethodArityHistogram::_max_arity; | |
1997 int MethodArityHistogram::_max_size; | |
1998 | |
1999 void SharedRuntime::print_call_statistics(int comp_total) { | |
2000 tty->print_cr("Calls from compiled code:"); | |
2001 int total = _nof_normal_calls + _nof_interface_calls + _nof_static_calls; | |
2002 int mono_c = _nof_normal_calls - _nof_optimized_calls - _nof_megamorphic_calls; | |
2003 int mono_i = _nof_interface_calls - _nof_optimized_interface_calls - _nof_megamorphic_interface_calls; | |
2004 tty->print_cr("\t%9d (%4.1f%%) total non-inlined ", total, percent(total, total)); | |
2005 tty->print_cr("\t%9d (%4.1f%%) virtual calls ", _nof_normal_calls, percent(_nof_normal_calls, total)); | |
2006 tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_calls, percent(_nof_inlined_calls, _nof_normal_calls)); | |
2007 tty->print_cr("\t %9d (%3.0f%%) optimized ", _nof_optimized_calls, percent(_nof_optimized_calls, _nof_normal_calls)); | |
2008 tty->print_cr("\t %9d (%3.0f%%) monomorphic ", mono_c, percent(mono_c, _nof_normal_calls)); | |
2009 tty->print_cr("\t %9d (%3.0f%%) megamorphic ", _nof_megamorphic_calls, percent(_nof_megamorphic_calls, _nof_normal_calls)); | |
2010 tty->print_cr("\t%9d (%4.1f%%) interface calls ", _nof_interface_calls, percent(_nof_interface_calls, total)); | |
2011 tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_interface_calls, percent(_nof_inlined_interface_calls, _nof_interface_calls)); | |
2012 tty->print_cr("\t %9d (%3.0f%%) optimized ", _nof_optimized_interface_calls, percent(_nof_optimized_interface_calls, _nof_interface_calls)); | |
2013 tty->print_cr("\t %9d (%3.0f%%) monomorphic ", mono_i, percent(mono_i, _nof_interface_calls)); | |
2014 tty->print_cr("\t %9d (%3.0f%%) megamorphic ", _nof_megamorphic_interface_calls, percent(_nof_megamorphic_interface_calls, _nof_interface_calls)); | |
2015 tty->print_cr("\t%9d (%4.1f%%) static/special calls", _nof_static_calls, percent(_nof_static_calls, total)); | |
2016 tty->print_cr("\t %9d (%3.0f%%) inlined ", _nof_inlined_static_calls, percent(_nof_inlined_static_calls, _nof_static_calls)); | |
2017 tty->cr(); | |
2018 tty->print_cr("Note 1: counter updates are not MT-safe."); | |
2019 tty->print_cr("Note 2: %% in major categories are relative to total non-inlined calls;"); | |
2020 tty->print_cr(" %% in nested categories are relative to their category"); | |
2021 tty->print_cr(" (and thus add up to more than 100%% with inlining)"); | |
2022 tty->cr(); | |
2023 | |
2024 MethodArityHistogram h; | |
2025 } | |
2026 #endif | |
2027 | |
2028 | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2029 // A simple wrapper class around the calling convention information |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2030 // that allows sharing of adapters for the same calling convention. |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2031 class AdapterFingerPrint : public CHeapObj { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2032 private: |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2033 union { |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2034 int _compact[3]; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2035 int* _fingerprint; |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2036 } _value; |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2037 int _length; // A negative length indicates the fingerprint is in the compact form, |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2038 // Otherwise _value._fingerprint is the array. |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2039 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2040 // Remap BasicTypes that are handled equivalently by the adapters. |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2041 // These are correct for the current system but someday it might be |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2042 // necessary to make this mapping platform dependent. |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2043 static BasicType adapter_encoding(BasicType in) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2044 assert((~0xf & in) == 0, "must fit in 4 bits"); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2045 switch(in) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2046 case T_BOOLEAN: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2047 case T_BYTE: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2048 case T_SHORT: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2049 case T_CHAR: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2050 // There are all promoted to T_INT in the calling convention |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2051 return T_INT; |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2052 |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2053 case T_OBJECT: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2054 case T_ARRAY: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2055 #ifdef _LP64 |
1506 | 2056 return T_LONG; |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2057 #else |
1506 | 2058 return T_INT; |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2059 #endif |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2060 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2061 case T_INT: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2062 case T_LONG: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2063 case T_FLOAT: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2064 case T_DOUBLE: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2065 case T_VOID: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2066 return in; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2067 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2068 default: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2069 ShouldNotReachHere(); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2070 return T_CONFLICT; |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2071 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2072 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2073 |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2074 public: |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2075 AdapterFingerPrint(int total_args_passed, BasicType* sig_bt) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2076 // The fingerprint is based on the BasicType signature encoded |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2077 // into an array of ints with four entries per int. |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2078 int* ptr; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2079 int len = (total_args_passed + 3) >> 2; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2080 if (len <= (int)(sizeof(_value._compact) / sizeof(int))) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2081 _value._compact[0] = _value._compact[1] = _value._compact[2] = 0; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2082 // Storing the signature encoded as signed chars hits about 98% |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2083 // of the time. |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2084 _length = -len; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2085 ptr = _value._compact; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2086 } else { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2087 _length = len; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2088 _value._fingerprint = NEW_C_HEAP_ARRAY(int, _length); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2089 ptr = _value._fingerprint; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2090 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2091 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2092 // Now pack the BasicTypes with 4 per int |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2093 int sig_index = 0; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2094 for (int index = 0; index < len; index++) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2095 int value = 0; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2096 for (int byte = 0; byte < 4; byte++) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2097 if (sig_index < total_args_passed) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2098 value = (value << 4) | adapter_encoding(sig_bt[sig_index++]); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2099 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2100 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2101 ptr[index] = value; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2102 } |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2103 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2104 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2105 ~AdapterFingerPrint() { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2106 if (_length > 0) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2107 FREE_C_HEAP_ARRAY(int, _value._fingerprint); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2108 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2109 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2110 |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2111 int value(int index) { |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2112 if (_length < 0) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2113 return _value._compact[index]; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2114 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2115 return _value._fingerprint[index]; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2116 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2117 int length() { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2118 if (_length < 0) return -_length; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2119 return _length; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2120 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2121 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2122 bool is_compact() { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2123 return _length <= 0; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2124 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2125 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2126 unsigned int compute_hash() { |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2127 int hash = 0; |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2128 for (int i = 0; i < length(); i++) { |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2129 int v = value(i); |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2130 hash = (hash << 8) ^ v ^ (hash >> 5); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2131 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2132 return (unsigned int)hash; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2133 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2134 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2135 const char* as_string() { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2136 stringStream st; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2137 for (int i = 0; i < length(); i++) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2138 st.print(PTR_FORMAT, value(i)); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2139 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2140 return st.as_string(); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2141 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2142 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2143 bool equals(AdapterFingerPrint* other) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2144 if (other->_length != _length) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2145 return false; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2146 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2147 if (_length < 0) { |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2148 return _value._compact[0] == other->_value._compact[0] && |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2149 _value._compact[1] == other->_value._compact[1] && |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2150 _value._compact[2] == other->_value._compact[2]; |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2151 } else { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2152 for (int i = 0; i < _length; i++) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2153 if (_value._fingerprint[i] != other->_value._fingerprint[i]) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2154 return false; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2155 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2156 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2157 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2158 return true; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2159 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2160 }; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2161 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2162 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2163 // A hashtable mapping from AdapterFingerPrints to AdapterHandlerEntries |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2164 class AdapterHandlerTable : public BasicHashtable { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2165 friend class AdapterHandlerTableIterator; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2166 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2167 private: |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2168 |
1263
e7b1cc79bd25
6926697: "optimized" VM build failed: The type "AdapterHandlerTableIterator" is incomplete
kvn
parents:
1257
diff
changeset
|
2169 #ifndef PRODUCT |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2170 static int _lookups; // number of calls to lookup |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2171 static int _buckets; // number of buckets checked |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2172 static int _equals; // number of buckets checked with matching hash |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2173 static int _hits; // number of successful lookups |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2174 static int _compact; // number of equals calls with compact signature |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2175 #endif |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2176 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2177 AdapterHandlerEntry* bucket(int i) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2178 return (AdapterHandlerEntry*)BasicHashtable::bucket(i); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2179 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2180 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2181 public: |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2182 AdapterHandlerTable() |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2183 : BasicHashtable(293, sizeof(AdapterHandlerEntry)) { } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2184 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2185 // Create a new entry suitable for insertion in the table |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2186 AdapterHandlerEntry* new_entry(AdapterFingerPrint* fingerprint, address i2c_entry, address c2i_entry, address c2i_unverified_entry) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2187 AdapterHandlerEntry* entry = (AdapterHandlerEntry*)BasicHashtable::new_entry(fingerprint->compute_hash()); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2188 entry->init(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2189 return entry; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2190 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2191 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2192 // Insert an entry into the table |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2193 void add(AdapterHandlerEntry* entry) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2194 int index = hash_to_index(entry->hash()); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2195 add_entry(index, entry); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2196 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2197 |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2198 void free_entry(AdapterHandlerEntry* entry) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2199 entry->deallocate(); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2200 BasicHashtable::free_entry(entry); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2201 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2202 |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2203 // Find a entry with the same fingerprint if it exists |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2204 AdapterHandlerEntry* lookup(int total_args_passed, BasicType* sig_bt) { |
1263
e7b1cc79bd25
6926697: "optimized" VM build failed: The type "AdapterHandlerTableIterator" is incomplete
kvn
parents:
1257
diff
changeset
|
2205 NOT_PRODUCT(_lookups++); |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2206 AdapterFingerPrint fp(total_args_passed, sig_bt); |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2207 unsigned int hash = fp.compute_hash(); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2208 int index = hash_to_index(hash); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2209 for (AdapterHandlerEntry* e = bucket(index); e != NULL; e = e->next()) { |
1263
e7b1cc79bd25
6926697: "optimized" VM build failed: The type "AdapterHandlerTableIterator" is incomplete
kvn
parents:
1257
diff
changeset
|
2210 NOT_PRODUCT(_buckets++); |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2211 if (e->hash() == hash) { |
1263
e7b1cc79bd25
6926697: "optimized" VM build failed: The type "AdapterHandlerTableIterator" is incomplete
kvn
parents:
1257
diff
changeset
|
2212 NOT_PRODUCT(_equals++); |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2213 if (fp.equals(e->fingerprint())) { |
1263
e7b1cc79bd25
6926697: "optimized" VM build failed: The type "AdapterHandlerTableIterator" is incomplete
kvn
parents:
1257
diff
changeset
|
2214 #ifndef PRODUCT |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2215 if (fp.is_compact()) _compact++; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2216 _hits++; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2217 #endif |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2218 return e; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2219 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2220 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2221 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2222 return NULL; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2223 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2224 |
1263
e7b1cc79bd25
6926697: "optimized" VM build failed: The type "AdapterHandlerTableIterator" is incomplete
kvn
parents:
1257
diff
changeset
|
2225 #ifndef PRODUCT |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2226 void print_statistics() { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2227 ResourceMark rm; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2228 int longest = 0; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2229 int empty = 0; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2230 int total = 0; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2231 int nonempty = 0; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2232 for (int index = 0; index < table_size(); index++) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2233 int count = 0; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2234 for (AdapterHandlerEntry* e = bucket(index); e != NULL; e = e->next()) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2235 count++; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2236 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2237 if (count != 0) nonempty++; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2238 if (count == 0) empty++; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2239 if (count > longest) longest = count; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2240 total += count; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2241 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2242 tty->print_cr("AdapterHandlerTable: empty %d longest %d total %d average %f", |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2243 empty, longest, total, total / (double)nonempty); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2244 tty->print_cr("AdapterHandlerTable: lookups %d buckets %d equals %d hits %d compact %d", |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2245 _lookups, _buckets, _equals, _hits, _compact); |
1263
e7b1cc79bd25
6926697: "optimized" VM build failed: The type "AdapterHandlerTableIterator" is incomplete
kvn
parents:
1257
diff
changeset
|
2246 } |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2247 #endif |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2248 }; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2249 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2250 |
1263
e7b1cc79bd25
6926697: "optimized" VM build failed: The type "AdapterHandlerTableIterator" is incomplete
kvn
parents:
1257
diff
changeset
|
2251 #ifndef PRODUCT |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2252 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2253 int AdapterHandlerTable::_lookups; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2254 int AdapterHandlerTable::_buckets; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2255 int AdapterHandlerTable::_equals; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2256 int AdapterHandlerTable::_hits; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2257 int AdapterHandlerTable::_compact; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2258 |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2259 #endif |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2260 |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2261 class AdapterHandlerTableIterator : public StackObj { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2262 private: |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2263 AdapterHandlerTable* _table; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2264 int _index; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2265 AdapterHandlerEntry* _current; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2266 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2267 void scan() { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2268 while (_index < _table->table_size()) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2269 AdapterHandlerEntry* a = _table->bucket(_index); |
1564 | 2270 _index++; |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2271 if (a != NULL) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2272 _current = a; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2273 return; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2274 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2275 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2276 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2277 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2278 public: |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2279 AdapterHandlerTableIterator(AdapterHandlerTable* table): _table(table), _index(0), _current(NULL) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2280 scan(); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2281 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2282 bool has_next() { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2283 return _current != NULL; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2284 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2285 AdapterHandlerEntry* next() { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2286 if (_current != NULL) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2287 AdapterHandlerEntry* result = _current; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2288 _current = _current->next(); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2289 if (_current == NULL) scan(); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2290 return result; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2291 } else { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2292 return NULL; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2293 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2294 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2295 }; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2296 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2297 |
0 | 2298 // --------------------------------------------------------------------------- |
2299 // Implementation of AdapterHandlerLibrary | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2300 AdapterHandlerTable* AdapterHandlerLibrary::_adapters = NULL; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2301 AdapterHandlerEntry* AdapterHandlerLibrary::_abstract_method_handler = NULL; |
0 | 2302 const int AdapterHandlerLibrary_size = 16*K; |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2303 BufferBlob* AdapterHandlerLibrary::_buffer = NULL; |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2304 |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2305 BufferBlob* AdapterHandlerLibrary::buffer_blob() { |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2306 // Should be called only when AdapterHandlerLibrary_lock is active. |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2307 if (_buffer == NULL) // Initialize lazily |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2308 _buffer = BufferBlob::create("adapters", AdapterHandlerLibrary_size); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2309 return _buffer; |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2310 } |
0 | 2311 |
2312 void AdapterHandlerLibrary::initialize() { | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2313 if (_adapters != NULL) return; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2314 _adapters = new AdapterHandlerTable(); |
0 | 2315 |
2316 // Create a special handler for abstract methods. Abstract methods | |
2317 // are never compiled so an i2c entry is somewhat meaningless, but | |
2318 // fill it in with something appropriate just in case. Pass handle | |
2319 // wrong method for the c2i transitions. | |
2320 address wrong_method = SharedRuntime::get_handle_wrong_method_stub(); | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2321 _abstract_method_handler = AdapterHandlerLibrary::new_entry(new AdapterFingerPrint(0, NULL), |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2322 StubRoutines::throw_AbstractMethodError_entry(), |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2323 wrong_method, wrong_method); |
0 | 2324 } |
2325 | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2326 AdapterHandlerEntry* AdapterHandlerLibrary::new_entry(AdapterFingerPrint* fingerprint, |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2327 address i2c_entry, |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2328 address c2i_entry, |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2329 address c2i_unverified_entry) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2330 return _adapters->new_entry(fingerprint, i2c_entry, c2i_entry, c2i_unverified_entry); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2331 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2332 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2333 AdapterHandlerEntry* AdapterHandlerLibrary::get_adapter(methodHandle method) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2334 // Use customized signature handler. Need to lock around updates to |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2335 // the AdapterHandlerTable (it is not safe for concurrent readers |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2336 // and a single writer: this could be fixed if it becomes a |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2337 // problem). |
0 | 2338 |
2339 // Get the address of the ic_miss handlers before we grab the | |
2340 // AdapterHandlerLibrary_lock. This fixes bug 6236259 which | |
2341 // was caused by the initialization of the stubs happening | |
2342 // while we held the lock and then notifying jvmti while | |
2343 // holding it. This just forces the initialization to be a little | |
2344 // earlier. | |
2345 address ic_miss = SharedRuntime::get_ic_miss_stub(); | |
2346 assert(ic_miss != NULL, "must have handler"); | |
2347 | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2348 ResourceMark rm; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2349 |
1748 | 2350 NOT_PRODUCT(int insts_size); |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1295
diff
changeset
|
2351 AdapterBlob* B = NULL; |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2352 AdapterHandlerEntry* entry = NULL; |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2353 AdapterFingerPrint* fingerprint = NULL; |
0 | 2354 { |
2355 MutexLocker mu(AdapterHandlerLibrary_lock); | |
2356 // make sure data structure is initialized | |
2357 initialize(); | |
2358 | |
2359 if (method->is_abstract()) { | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2360 return _abstract_method_handler; |
0 | 2361 } |
2362 | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2363 // Fill in the signature array, for the calling-convention call. |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2364 int total_args_passed = method->size_of_parameters(); // All args on stack |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2365 |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2366 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType, total_args_passed); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2367 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair, total_args_passed); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2368 int i = 0; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2369 if (!method->is_static()) // Pass in receiver first |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2370 sig_bt[i++] = T_OBJECT; |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2371 for (SignatureStream ss(method->signature()); !ss.at_return_type(); ss.next()) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2372 sig_bt[i++] = ss.type(); // Collect remaining bits of signature |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2373 if (ss.type() == T_LONG || ss.type() == T_DOUBLE) |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2374 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2375 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2376 assert(i == total_args_passed, ""); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2377 |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2378 // Lookup method signature's fingerprint |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2379 entry = _adapters->lookup(total_args_passed, sig_bt); |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2380 |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2381 #ifdef ASSERT |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2382 AdapterHandlerEntry* shared_entry = NULL; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2383 if (VerifyAdapterSharing && entry != NULL) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2384 shared_entry = entry; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2385 entry = NULL; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2386 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2387 #endif |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2388 |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2389 if (entry != NULL) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2390 return entry; |
0 | 2391 } |
2392 | |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2393 // Get a description of the compiled java calling convention and the largest used (VMReg) stack slot usage |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2394 int comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2395 |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2396 // Make a C heap allocated version of the fingerprint to store in the adapter |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2397 fingerprint = new AdapterFingerPrint(total_args_passed, sig_bt); |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2398 |
0 | 2399 // Create I2C & C2I handlers |
2400 | |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1295
diff
changeset
|
2401 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2402 if (buf != NULL) { |
1748 | 2403 CodeBuffer buffer(buf); |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2404 short buffer_locs[20]; |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2405 buffer.insts()->initialize_shared_locs((relocInfo*)buffer_locs, |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2406 sizeof(buffer_locs)/sizeof(relocInfo)); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2407 MacroAssembler _masm(&buffer); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2408 |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2409 entry = SharedRuntime::generate_i2c2i_adapters(&_masm, |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2410 total_args_passed, |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2411 comp_args_on_stack, |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2412 sig_bt, |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2413 regs, |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2414 fingerprint); |
0 | 2415 |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2416 #ifdef ASSERT |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2417 if (VerifyAdapterSharing) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2418 if (shared_entry != NULL) { |
1748 | 2419 assert(shared_entry->compare_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt), |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2420 "code must match"); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2421 // Release the one just created and return the original |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2422 _adapters->free_entry(entry); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2423 return shared_entry; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2424 } else { |
1748 | 2425 entry->save_code(buf->code_begin(), buffer.insts_size(), total_args_passed, sig_bt); |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2426 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2427 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2428 #endif |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2429 |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1295
diff
changeset
|
2430 B = AdapterBlob::create(&buffer); |
1748 | 2431 NOT_PRODUCT(insts_size = buffer.insts_size()); |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2432 } |
28 | 2433 if (B == NULL) { |
2434 // CodeCache is full, disable compilation | |
2435 // Ought to log this but compile log is only per compile thread | |
2436 // and we're some non descript Java thread. | |
1202 | 2437 MutexUnlocker mu(AdapterHandlerLibrary_lock); |
2438 CompileBroker::handle_full_code_cache(); | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2439 return NULL; // Out of CodeCache space |
28 | 2440 } |
1748 | 2441 entry->relocate(B->content_begin()); |
0 | 2442 #ifndef PRODUCT |
2443 // debugging suppport | |
2444 if (PrintAdapterHandlers) { | |
2445 tty->cr(); | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2446 tty->print_cr("i2c argument handler #%d for: %s %s (fingerprint = %s, %d bytes generated)", |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2447 _adapters->number_of_entries(), (method->is_static() ? "static" : "receiver"), |
1748 | 2448 method->signature()->as_C_string(), fingerprint->as_string(), insts_size ); |
0 | 2449 tty->print_cr("c2i argument handler starts at %p",entry->get_c2i_entry()); |
1748 | 2450 Disassembler::decode(entry->get_i2c_entry(), entry->get_i2c_entry() + insts_size); |
0 | 2451 } |
2452 #endif | |
2453 | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2454 _adapters->add(entry); |
0 | 2455 } |
2456 // Outside of the lock | |
2457 if (B != NULL) { | |
2458 char blob_id[256]; | |
2459 jio_snprintf(blob_id, | |
2460 sizeof(blob_id), | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2461 "%s(%s)@" PTR_FORMAT, |
1299
9eba43136cb5
6934494: JSR 292 MethodHandles adapters should be generated into their own CodeBlob
twisti
parents:
1295
diff
changeset
|
2462 B->name(), |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2463 fingerprint->as_string(), |
1748 | 2464 B->content_begin()); |
2465 Forte::register_stub(blob_id, B->content_begin(), B->content_end()); | |
0 | 2466 |
2467 if (JvmtiExport::should_post_dynamic_code_generated()) { | |
1748 | 2468 JvmtiExport::post_dynamic_code_generated(blob_id, B->content_begin(), B->content_end()); |
0 | 2469 } |
2470 } | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2471 return entry; |
0 | 2472 } |
2473 | |
2474 void AdapterHandlerEntry::relocate(address new_base) { | |
2475 ptrdiff_t delta = new_base - _i2c_entry; | |
2476 _i2c_entry += delta; | |
2477 _c2i_entry += delta; | |
2478 _c2i_unverified_entry += delta; | |
2479 } | |
2480 | |
1207
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2481 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2482 void AdapterHandlerEntry::deallocate() { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2483 delete _fingerprint; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2484 #ifdef ASSERT |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2485 if (_saved_code) FREE_C_HEAP_ARRAY(unsigned char, _saved_code); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2486 if (_saved_sig) FREE_C_HEAP_ARRAY(Basictype, _saved_sig); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2487 #endif |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2488 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2489 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2490 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2491 #ifdef ASSERT |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2492 // Capture the code before relocation so that it can be compared |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2493 // against other versions. If the code is captured after relocation |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2494 // then relative instructions won't be equivalent. |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2495 void AdapterHandlerEntry::save_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2496 _saved_code = NEW_C_HEAP_ARRAY(unsigned char, length); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2497 _code_length = length; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2498 memcpy(_saved_code, buffer, length); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2499 _total_args_passed = total_args_passed; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2500 _saved_sig = NEW_C_HEAP_ARRAY(BasicType, _total_args_passed); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2501 memcpy(_saved_sig, sig_bt, _total_args_passed * sizeof(BasicType)); |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2502 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2503 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2504 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2505 bool AdapterHandlerEntry::compare_code(unsigned char* buffer, int length, int total_args_passed, BasicType* sig_bt) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2506 if (length != _code_length) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2507 return false; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2508 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2509 for (int i = 0; i < length; i++) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2510 if (buffer[i] != _saved_code[i]) { |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2511 return false; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2512 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2513 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2514 return true; |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2515 } |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2516 #endif |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2517 |
74c848d437ab
6921922: fix for 6911204 breaks tagged stack interpreter
never
parents:
1205
diff
changeset
|
2518 |
0 | 2519 // Create a native wrapper for this native method. The wrapper converts the |
2520 // java compiled calling convention to the native convention, handlizes | |
2521 // arguments, and transitions to native. On return from the native we transition | |
2522 // back to java blocking if a safepoint is in progress. | |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2321
diff
changeset
|
2523 nmethod *AdapterHandlerLibrary::create_native_wrapper(methodHandle method, int compile_id) { |
0 | 2524 ResourceMark rm; |
2525 nmethod* nm = NULL; | |
2526 | |
2527 assert(method->has_native_function(), "must have something valid to call!"); | |
2528 | |
2529 { | |
2530 // perform the work while holding the lock, but perform any printing outside the lock | |
2531 MutexLocker mu(AdapterHandlerLibrary_lock); | |
2532 // See if somebody beat us to it | |
2533 nm = method->code(); | |
2534 if (nm) { | |
2535 return nm; | |
2536 } | |
2537 | |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2538 ResourceMark rm; |
0 | 2539 |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2540 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2541 if (buf != NULL) { |
1748 | 2542 CodeBuffer buffer(buf); |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2543 double locs_buf[20]; |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2544 buffer.insts()->initialize_shared_locs((relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo)); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2545 MacroAssembler _masm(&buffer); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2546 |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2547 // Fill in the signature array, for the calling-convention call. |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2548 int total_args_passed = method->size_of_parameters(); |
0 | 2549 |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2550 BasicType* sig_bt = NEW_RESOURCE_ARRAY(BasicType,total_args_passed); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2551 VMRegPair* regs = NEW_RESOURCE_ARRAY(VMRegPair,total_args_passed); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2552 int i=0; |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2553 if( !method->is_static() ) // Pass in receiver first |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2554 sig_bt[i++] = T_OBJECT; |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2555 SignatureStream ss(method->signature()); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2556 for( ; !ss.at_return_type(); ss.next()) { |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2557 sig_bt[i++] = ss.type(); // Collect remaining bits of signature |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2558 if( ss.type() == T_LONG || ss.type() == T_DOUBLE ) |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2559 sig_bt[i++] = T_VOID; // Longs & doubles take 2 Java slots |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2560 } |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2561 assert( i==total_args_passed, "" ); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2562 BasicType ret_type = ss.type(); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2563 |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2564 // Now get the compiled-Java layout as input arguments |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2565 int comp_args_on_stack; |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2566 comp_args_on_stack = SharedRuntime::java_calling_convention(sig_bt, regs, total_args_passed, false); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2567 |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2568 // Generate the compiled-to-native wrapper code |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2569 nm = SharedRuntime::generate_native_wrapper(&_masm, |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2570 method, |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2321
diff
changeset
|
2571 compile_id, |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2572 total_args_passed, |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2573 comp_args_on_stack, |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2574 sig_bt,regs, |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2575 ret_type); |
0 | 2576 } |
2577 } | |
2578 | |
2579 // Must unlock before calling set_code | |
1728
a62d332029cf
6976372: # assert(_owner == Thread::current()) failed: invariant
never
parents:
1681
diff
changeset
|
2580 |
0 | 2581 // Install the generated code. |
2582 if (nm != NULL) { | |
2405
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2321
diff
changeset
|
2583 if (PrintCompilation) { |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2321
diff
changeset
|
2584 ttyLocker ttyl; |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2321
diff
changeset
|
2585 CompileTask::print_compilation(tty, nm, method->is_static() ? "(static)" : ""); |
3d58a4983660
7022998: JSR 292 recursive method handle calls inline themselves infinitely
twisti
parents:
2321
diff
changeset
|
2586 } |
0 | 2587 method->set_code(method, nm); |
2588 nm->post_compiled_method_load_event(); | |
2589 } else { | |
2590 // CodeCache is full, disable compilation | |
1202 | 2591 CompileBroker::handle_full_code_cache(); |
0 | 2592 } |
2593 return nm; | |
2594 } | |
2595 | |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2596 #ifdef HAVE_DTRACE_H |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2597 // Create a dtrace nmethod for this method. The wrapper converts the |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2598 // java compiled calling convention to the native convention, makes a dummy call |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2599 // (actually nops for the size of the call instruction, which become a trap if |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2600 // probe is enabled). The returns to the caller. Since this all looks like a |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2601 // leaf no thread transition is needed. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2602 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2603 nmethod *AdapterHandlerLibrary::create_dtrace_nmethod(methodHandle method) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2604 ResourceMark rm; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2605 nmethod* nm = NULL; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2606 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2607 if (PrintCompilation) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2608 ttyLocker ttyl; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2609 tty->print("--- n%s "); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2610 method->print_short_name(tty); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2611 if (method->is_static()) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2612 tty->print(" (static)"); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2613 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2614 tty->cr(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2615 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2616 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2617 { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2618 // perform the work while holding the lock, but perform any printing |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2619 // outside the lock |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2620 MutexLocker mu(AdapterHandlerLibrary_lock); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2621 // See if somebody beat us to it |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2622 nm = method->code(); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2623 if (nm) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2624 return nm; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2625 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2626 |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2627 ResourceMark rm; |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2628 |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2629 BufferBlob* buf = buffer_blob(); // the temporary code buffer in CodeCache |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2630 if (buf != NULL) { |
1748 | 2631 CodeBuffer buffer(buf); |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2632 // Need a few relocation entries |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2633 double locs_buf[20]; |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2634 buffer.insts()->initialize_shared_locs( |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2635 (relocInfo*)locs_buf, sizeof(locs_buf) / sizeof(relocInfo)); |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2636 MacroAssembler _masm(&buffer); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2637 |
742
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2638 // Generate the compiled-to-native wrapper code |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2639 nm = SharedRuntime::generate_dtrace_nmethod(&_masm, method); |
45463a04ca27
6834177: Running jsynprog on Solaris Nevada can cause JVM crash
kvn
parents:
710
diff
changeset
|
2640 } |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2641 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2642 return nm; |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2643 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2644 |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2645 // the dtrace method needs to convert java lang string to utf8 string. |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2646 void SharedRuntime::get_utf(oopDesc* src, address dst) { |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2647 typeArrayOop jlsValue = java_lang_String::value(src); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2648 int jlsOffset = java_lang_String::offset(src); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2649 int jlsLen = java_lang_String::length(src); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2650 jchar* jlsPos = (jlsLen == 0) ? NULL : |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2651 jlsValue->char_at_addr(jlsOffset); |
2192
b92c45f2bc75
7016023: Enable building ARM and PPC from src/closed repository
bobv
parents:
2177
diff
changeset
|
2652 assert(typeArrayKlass::cast(jlsValue->klass())->element_type() == T_CHAR, "compressed string"); |
116
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2653 (void) UNICODE::as_utf8(jlsPos, jlsLen, (char *)dst, max_dtrace_string_size); |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2654 } |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2655 #endif // ndef HAVE_DTRACE_H |
018d5b58dd4f
6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents:
62
diff
changeset
|
2656 |
0 | 2657 // ------------------------------------------------------------------------- |
2658 // Java-Java calling convention | |
2659 // (what you use when Java calls Java) | |
2660 | |
2661 //------------------------------name_for_receiver---------------------------------- | |
2662 // For a given signature, return the VMReg for parameter 0. | |
2663 VMReg SharedRuntime::name_for_receiver() { | |
2664 VMRegPair regs; | |
2665 BasicType sig_bt = T_OBJECT; | |
2666 (void) java_calling_convention(&sig_bt, ®s, 1, true); | |
2667 // Return argument 0 register. In the LP64 build pointers | |
2668 // take 2 registers, but the VM wants only the 'main' name. | |
2669 return regs.first(); | |
2670 } | |
2671 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2142
diff
changeset
|
2672 VMRegPair *SharedRuntime::find_callee_arguments(Symbol* sig, bool has_receiver, int* arg_size) { |
0 | 2673 // This method is returning a data structure allocating as a |
2674 // ResourceObject, so do not put any ResourceMarks in here. | |
2675 char *s = sig->as_C_string(); | |
2676 int len = (int)strlen(s); | |
2677 *s++; len--; // Skip opening paren | |
2678 char *t = s+len; | |
2679 while( *(--t) != ')' ) ; // Find close paren | |
2680 | |
2681 BasicType *sig_bt = NEW_RESOURCE_ARRAY( BasicType, 256 ); | |
2682 VMRegPair *regs = NEW_RESOURCE_ARRAY( VMRegPair, 256 ); | |
2683 int cnt = 0; | |
1138
dd57230ba8fe
6893268: additional dynamic language related optimizations in C2
twisti
parents:
1135
diff
changeset
|
2684 if (has_receiver) { |
0 | 2685 sig_bt[cnt++] = T_OBJECT; // Receiver is argument 0; not in signature |
2686 } | |
2687 | |
2688 while( s < t ) { | |
2689 switch( *s++ ) { // Switch on signature character | |
2690 case 'B': sig_bt[cnt++] = T_BYTE; break; | |
2691 case 'C': sig_bt[cnt++] = T_CHAR; break; | |
2692 case 'D': sig_bt[cnt++] = T_DOUBLE; sig_bt[cnt++] = T_VOID; break; | |
2693 case 'F': sig_bt[cnt++] = T_FLOAT; break; | |
2694 case 'I': sig_bt[cnt++] = T_INT; break; | |
2695 case 'J': sig_bt[cnt++] = T_LONG; sig_bt[cnt++] = T_VOID; break; | |
2696 case 'S': sig_bt[cnt++] = T_SHORT; break; | |
2697 case 'Z': sig_bt[cnt++] = T_BOOLEAN; break; | |
2698 case 'V': sig_bt[cnt++] = T_VOID; break; | |
2699 case 'L': // Oop | |
2700 while( *s++ != ';' ) ; // Skip signature | |
2701 sig_bt[cnt++] = T_OBJECT; | |
2702 break; | |
2703 case '[': { // Array | |
2704 do { // Skip optional size | |
2705 while( *s >= '0' && *s <= '9' ) s++; | |
2706 } while( *s++ == '[' ); // Nested arrays? | |
2707 // Skip element type | |
2708 if( s[-1] == 'L' ) | |
2709 while( *s++ != ';' ) ; // Skip signature | |
2710 sig_bt[cnt++] = T_ARRAY; | |
2711 break; | |
2712 } | |
2713 default : ShouldNotReachHere(); | |
2714 } | |
2715 } | |
2716 assert( cnt < 256, "grow table size" ); | |
2717 | |
2718 int comp_args_on_stack; | |
2719 comp_args_on_stack = java_calling_convention(sig_bt, regs, cnt, true); | |
2720 | |
2721 // the calling convention doesn't count out_preserve_stack_slots so | |
2722 // we must add that in to get "true" stack offsets. | |
2723 | |
2724 if (comp_args_on_stack) { | |
2725 for (int i = 0; i < cnt; i++) { | |
2726 VMReg reg1 = regs[i].first(); | |
2727 if( reg1->is_stack()) { | |
2728 // Yuck | |
2729 reg1 = reg1->bias(out_preserve_stack_slots()); | |
2730 } | |
2731 VMReg reg2 = regs[i].second(); | |
2732 if( reg2->is_stack()) { | |
2733 // Yuck | |
2734 reg2 = reg2->bias(out_preserve_stack_slots()); | |
2735 } | |
2736 regs[i].set_pair(reg2, reg1); | |
2737 } | |
2738 } | |
2739 | |
2740 // results | |
2741 *arg_size = cnt; | |
2742 return regs; | |
2743 } | |
2744 | |
2745 // OSR Migration Code | |
2746 // | |
2747 // This code is used convert interpreter frames into compiled frames. It is | |
2748 // called from very start of a compiled OSR nmethod. A temp array is | |
2749 // allocated to hold the interesting bits of the interpreter frame. All | |
2750 // active locks are inflated to allow them to move. The displaced headers and | |
2751 // active interpeter locals are copied into the temp buffer. Then we return | |
2752 // back to the compiled code. The compiled code then pops the current | |
2753 // interpreter frame off the stack and pushes a new compiled frame. Then it | |
2754 // copies the interpreter locals and displaced headers where it wants. | |
2755 // Finally it calls back to free the temp buffer. | |
2756 // | |
2757 // All of this is done NOT at any Safepoint, nor is any safepoint or GC allowed. | |
2758 | |
2759 JRT_LEAF(intptr_t*, SharedRuntime::OSR_migration_begin( JavaThread *thread) ) | |
2760 | |
2761 #ifdef IA64 | |
2762 ShouldNotReachHere(); // NYI | |
2763 #endif /* IA64 */ | |
2764 | |
2765 // | |
2766 // This code is dependent on the memory layout of the interpreter local | |
2767 // array and the monitors. On all of our platforms the layout is identical | |
2768 // so this code is shared. If some platform lays the their arrays out | |
2769 // differently then this code could move to platform specific code or | |
2770 // the code here could be modified to copy items one at a time using | |
2771 // frame accessor methods and be platform independent. | |
2772 | |
2773 frame fr = thread->last_frame(); | |
2774 assert( fr.is_interpreted_frame(), "" ); | |
2775 assert( fr.interpreter_frame_expression_stack_size()==0, "only handle empty stacks" ); | |
2776 | |
2777 // Figure out how many monitors are active. | |
2778 int active_monitor_count = 0; | |
2779 for( BasicObjectLock *kptr = fr.interpreter_frame_monitor_end(); | |
2780 kptr < fr.interpreter_frame_monitor_begin(); | |
2781 kptr = fr.next_monitor_in_interpreter_frame(kptr) ) { | |
2782 if( kptr->obj() != NULL ) active_monitor_count++; | |
2783 } | |
2784 | |
2785 // QQQ we could place number of active monitors in the array so that compiled code | |
2786 // could double check it. | |
2787 | |
2788 methodOop moop = fr.interpreter_frame_method(); | |
2789 int max_locals = moop->max_locals(); | |
2790 // Allocate temp buffer, 1 word per local & 2 per active monitor | |
2791 int buf_size_words = max_locals + active_monitor_count*2; | |
2792 intptr_t *buf = NEW_C_HEAP_ARRAY(intptr_t,buf_size_words); | |
2793 | |
2794 // Copy the locals. Order is preserved so that loading of longs works. | |
2795 // Since there's no GC I can copy the oops blindly. | |
2796 assert( sizeof(HeapWord)==sizeof(intptr_t), "fix this code"); | |
1506 | 2797 Copy::disjoint_words((HeapWord*)fr.interpreter_frame_local_at(max_locals-1), |
0 | 2798 (HeapWord*)&buf[0], |
2799 max_locals); | |
2800 | |
2801 // Inflate locks. Copy the displaced headers. Be careful, there can be holes. | |
2802 int i = max_locals; | |
2803 for( BasicObjectLock *kptr2 = fr.interpreter_frame_monitor_end(); | |
2804 kptr2 < fr.interpreter_frame_monitor_begin(); | |
2805 kptr2 = fr.next_monitor_in_interpreter_frame(kptr2) ) { | |
2806 if( kptr2->obj() != NULL) { // Avoid 'holes' in the monitor array | |
2807 BasicLock *lock = kptr2->lock(); | |
2808 // Inflate so the displaced header becomes position-independent | |
2809 if (lock->displaced_header()->is_unlocked()) | |
2810 ObjectSynchronizer::inflate_helper(kptr2->obj()); | |
2811 // Now the displaced header is free to move | |
2812 buf[i++] = (intptr_t)lock->displaced_header(); | |
2813 buf[i++] = (intptr_t)kptr2->obj(); | |
2814 } | |
2815 } | |
2816 assert( i - max_locals == active_monitor_count*2, "found the expected number of monitors" ); | |
2817 | |
2818 return buf; | |
2819 JRT_END | |
2820 | |
2821 JRT_LEAF(void, SharedRuntime::OSR_migration_end( intptr_t* buf) ) | |
2822 FREE_C_HEAP_ARRAY(intptr_t,buf); | |
2823 JRT_END | |
2824 | |
2825 bool AdapterHandlerLibrary::contains(CodeBlob* b) { | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2826 AdapterHandlerTableIterator iter(_adapters); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2827 while (iter.has_next()) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2828 AdapterHandlerEntry* a = iter.next(); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2829 if ( b == CodeCache::find_blob(a->get_i2c_entry()) ) return true; |
0 | 2830 } |
2831 return false; | |
2832 } | |
2833 | |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2834 void AdapterHandlerLibrary::print_handler_on(outputStream* st, CodeBlob* b) { |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2835 AdapterHandlerTableIterator iter(_adapters); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2836 while (iter.has_next()) { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2837 AdapterHandlerEntry* a = iter.next(); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2838 if ( b == CodeCache::find_blob(a->get_i2c_entry()) ) { |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2839 st->print("Adapter for signature: "); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2840 st->print_cr("%s i2c: " INTPTR_FORMAT " c2i: " INTPTR_FORMAT " c2iUV: " INTPTR_FORMAT, |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2841 a->fingerprint()->as_string(), |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2842 a->get_i2c_entry(), a->get_c2i_entry(), a->get_c2i_unverified_entry()); |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2843 |
0 | 2844 return; |
2845 } | |
2846 } | |
2847 assert(false, "Should have found handler"); | |
2848 } | |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2849 |
1681
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2850 #ifndef PRODUCT |
126ea7725993
6953477: Increase portability and flexibility of building Hotspot
bobv
parents:
1644
diff
changeset
|
2851 |
1187
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2852 void AdapterHandlerLibrary::print_statistics() { |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2853 _adapters->print_statistics(); |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2854 } |
cf0685d550f1
6911204: generated adapters with large signatures can fill up the code cache
never
parents:
1142
diff
changeset
|
2855 |
0 | 2856 #endif /* PRODUCT */ |