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