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