Mercurial > hg > graal-compiler
annotate src/share/vm/interpreter/linkResolver.cpp @ 3992:d1bdeef3e3e2
7098282: G1: assert(interval >= 0) failed: Sanity check, referencePolicy.cpp: 76
Summary: There is a race between one thread successfully forwarding and copying the klass mirror for the SoftReference class (including the static master clock) and another thread attempting to use the master clock while attempting to discover a soft reference object. Maintain a shadow copy of the soft reference master clock and use the shadow during reference discovery and reference processing.
Reviewed-by: tonyp, brutisso, ysr
author | johnc |
---|---|
date | Wed, 12 Oct 2011 10:25:51 -0700 |
parents | f08d439fab8c |
children | 1d7922586cf6 |
rev | line source |
---|---|
0 | 1 /* |
2356
72dee110246f
6839872: remove implementation inheritance from JSR 292 APIs
jrose
parents:
2177
diff
changeset
|
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:
1508
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1508
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:
1508
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 "compiler/compileBroker.hpp" | |
29 #include "gc_interface/collectedHeap.inline.hpp" | |
30 #include "interpreter/bytecode.hpp" | |
31 #include "interpreter/interpreterRuntime.hpp" | |
32 #include "interpreter/linkResolver.hpp" | |
33 #include "memory/resourceArea.hpp" | |
34 #include "memory/universe.inline.hpp" | |
35 #include "oops/instanceKlass.hpp" | |
36 #include "oops/objArrayOop.hpp" | |
37 #include "prims/methodHandles.hpp" | |
38 #include "prims/nativeLookup.hpp" | |
39 #include "runtime/compilationPolicy.hpp" | |
40 #include "runtime/fieldDescriptor.hpp" | |
41 #include "runtime/frame.inline.hpp" | |
42 #include "runtime/handles.inline.hpp" | |
43 #include "runtime/reflection.hpp" | |
44 #include "runtime/signature.hpp" | |
45 #include "runtime/vmThread.hpp" | |
46 #ifdef TARGET_OS_FAMILY_linux | |
47 # include "thread_linux.inline.hpp" | |
48 #endif | |
49 #ifdef TARGET_OS_FAMILY_solaris | |
50 # include "thread_solaris.inline.hpp" | |
51 #endif | |
52 #ifdef TARGET_OS_FAMILY_windows | |
53 # include "thread_windows.inline.hpp" | |
54 #endif | |
3960 | 55 #ifdef TARGET_OS_FAMILY_bsd |
56 # include "thread_bsd.inline.hpp" | |
57 #endif | |
0 | 58 |
59 //------------------------------------------------------------------------------------------------------------------------ | |
60 // Implementation of FieldAccessInfo | |
61 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
62 void FieldAccessInfo::set(KlassHandle klass, Symbol* name, int field_index, int field_offset, |
0 | 63 BasicType field_type, AccessFlags access_flags) { |
64 _klass = klass; | |
65 _name = name; | |
66 _field_index = field_index; | |
67 _field_offset = field_offset; | |
68 _field_type = field_type; | |
69 _access_flags = access_flags; | |
70 } | |
71 | |
72 | |
73 //------------------------------------------------------------------------------------------------------------------------ | |
74 // Implementation of CallInfo | |
75 | |
76 | |
77 void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) { | |
78 int vtable_index = methodOopDesc::nonvirtual_vtable_index; | |
79 set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK); | |
80 } | |
81 | |
82 | |
83 void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) { | |
84 // This is only called for interface methods. If the resolved_method | |
85 // comes from java/lang/Object, it can be the subject of a virtual call, so | |
86 // we should pick the vtable index from the resolved method. | |
87 // Other than that case, there is no valid vtable index to specify. | |
88 int vtable_index = methodOopDesc::invalid_vtable_index; | |
1142 | 89 if (resolved_method->method_holder() == SystemDictionary::Object_klass()) { |
0 | 90 assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check"); |
91 vtable_index = resolved_method->vtable_index(); | |
92 } | |
93 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); | |
94 } | |
95 | |
96 void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { | |
97 assert(vtable_index >= 0 || vtable_index == methodOopDesc::nonvirtual_vtable_index, "valid index"); | |
98 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK); | |
99 } | |
100 | |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
101 void CallInfo::set_dynamic(methodHandle resolved_method, TRAPS) { |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
102 assert(resolved_method->is_method_handle_invoke(), ""); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
103 KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
104 assert(resolved_klass == resolved_method->method_holder(), ""); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
105 int vtable_index = methodOopDesc::nonvirtual_vtable_index; |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
106 assert(resolved_method->vtable_index() == vtable_index, ""); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
107 set_common(resolved_klass, KlassHandle(), resolved_method, resolved_method, vtable_index, CHECK); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
108 } |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
109 |
0 | 110 void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) { |
111 assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond"); | |
112 _resolved_klass = resolved_klass; | |
113 _selected_klass = selected_klass; | |
114 _resolved_method = resolved_method; | |
115 _selected_method = selected_method; | |
116 _vtable_index = vtable_index; | |
1783 | 117 if (CompilationPolicy::must_be_compiled(selected_method)) { |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
118 // This path is unusual, mostly used by the '-Xcomp' stress test mode. |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
119 |
1783 | 120 // Note: with several active threads, the must_be_compiled may be true |
121 // while can_be_compiled is false; remove assert | |
122 // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile"); | |
0 | 123 if (THREAD->is_Compiler_thread()) { |
124 // don't force compilation, resolve was on behalf of compiler | |
125 return; | |
126 } | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
127 if (instanceKlass::cast(selected_method->method_holder())->is_not_initialized()) { |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
128 // 'is_not_initialized' means not only '!is_initialized', but also that |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
129 // initialization has not been started yet ('!being_initialized') |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
130 // Do not force compilation of methods in uninitialized classes. |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
131 // Note that doing this would throw an assert later, |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
132 // in CompileBroker::compile_method. |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
133 // We sometimes use the link resolver to do reflective lookups |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
134 // even before classes are initialized. |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
135 return; |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
136 } |
0 | 137 CompileBroker::compile_method(selected_method, InvocationEntryBci, |
3837
43f9d800f276
7066339: Tiered: policy should make consistent decisions about osr levels
iveresov
parents:
3785
diff
changeset
|
138 CompilationPolicy::policy()->initial_compile_level(), |
1783 | 139 methodHandle(), 0, "must_be_compiled", CHECK); |
0 | 140 } |
141 } | |
142 | |
143 | |
144 //------------------------------------------------------------------------------------------------------------------------ | |
145 // Klass resolution | |
146 | |
147 void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) { | |
148 if (!Reflection::verify_class_access(ref_klass->as_klassOop(), | |
149 sel_klass->as_klassOop(), | |
150 true)) { | |
151 ResourceMark rm(THREAD); | |
152 Exceptions::fthrow( | |
153 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
154 vmSymbols::java_lang_IllegalAccessError(), |
0 | 155 "tried to access class %s from class %s", |
156 sel_klass->external_name(), | |
157 ref_klass->external_name() | |
158 ); | |
159 return; | |
160 } | |
161 } | |
162 | |
163 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { | |
164 klassOop result_oop = pool->klass_ref_at(index, CHECK); | |
165 result = KlassHandle(THREAD, result_oop); | |
166 } | |
167 | |
168 void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) { | |
169 klassOop result_oop = | |
170 constantPoolOopDesc::klass_ref_at_if_loaded_check(pool, index, CHECK); | |
171 result = KlassHandle(THREAD, result_oop); | |
172 } | |
173 | |
174 | |
175 //------------------------------------------------------------------------------------------------------------------------ | |
176 // Method resolution | |
177 // | |
178 // According to JVM spec. $5.4.3c & $5.4.3d | |
179 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
180 void LinkResolver::lookup_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
181 methodOop result_oop = klass->uncached_lookup_method(name, signature); |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2359
diff
changeset
|
182 if (EnableInvokeDynamic && result_oop != NULL) { |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
183 switch (result_oop->intrinsic_id()) { |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
184 case vmIntrinsics::_invokeExact: |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
185 case vmIntrinsics::_invokeGeneric: |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
186 case vmIntrinsics::_invokeDynamic: |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
187 // Do not link directly to these. The VM must produce a synthetic one using lookup_implicit_method. |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
188 return; |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
189 } |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
190 } |
0 | 191 result = methodHandle(THREAD, result_oop); |
192 } | |
193 | |
194 // returns first instance method | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
195 void LinkResolver::lookup_instance_method_in_klasses(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
196 methodOop result_oop = klass->uncached_lookup_method(name, signature); |
0 | 197 result = methodHandle(THREAD, result_oop); |
198 while (!result.is_null() && result->is_static()) { | |
199 klass = KlassHandle(THREAD, Klass::cast(result->method_holder())->super()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
200 result = methodHandle(THREAD, klass->uncached_lookup_method(name, signature)); |
0 | 201 } |
202 } | |
203 | |
204 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
205 int LinkResolver::vtable_index_of_miranda_method(KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
0 | 206 ResourceMark rm(THREAD); |
207 klassVtable *vt = instanceKlass::cast(klass())->vtable(); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
208 return vt->index_of_miranda(name, signature); |
0 | 209 } |
210 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
211 void LinkResolver::lookup_method_in_interfaces(methodHandle& result, KlassHandle klass, Symbol* name, Symbol* signature, TRAPS) { |
0 | 212 instanceKlass *ik = instanceKlass::cast(klass()); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
213 result = methodHandle(THREAD, ik->lookup_method_in_all_interfaces(name, signature)); |
0 | 214 } |
215 | |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
216 void LinkResolver::lookup_implicit_method(methodHandle& result, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
217 KlassHandle klass, Symbol* name, Symbol* signature, |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
218 KlassHandle current_klass, |
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
219 TRAPS) { |
2416
38fea01eb669
6817525: turn on method handle functionality by default for JSR 292
twisti
parents:
2359
diff
changeset
|
220 if (EnableInvokeDynamic && |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
221 klass() == SystemDictionary::MethodHandle_klass() && |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
222 methodOopDesc::is_method_handle_invoke_name(name)) { |
2359
d2134498fd3f
7011865: JSR 292 CTW fails: !THREAD->is_Compiler_thread() failed: Can not load classes with the Compiler thre
jrose
parents:
2357
diff
changeset
|
223 if (!THREAD->is_Compiler_thread() && !MethodHandles::enabled()) { |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
224 // Make sure the Java part of the runtime has been booted up. |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
225 klassOop natives = SystemDictionary::MethodHandleNatives_klass(); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
226 if (natives == NULL || instanceKlass::cast(natives)->is_not_initialized()) { |
2460 | 227 SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(), |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
228 Handle(), |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
229 Handle(), |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
230 true, |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
231 CHECK); |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
232 } |
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
233 } |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
234 methodOop result_oop = SystemDictionary::find_method_handle_invoke(name, |
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
235 signature, |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
236 current_klass, |
710 | 237 CHECK); |
238 if (result_oop != NULL) { | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
239 assert(result_oop->is_method_handle_invoke() && result_oop->signature() == signature, "consistent"); |
710 | 240 result = methodHandle(THREAD, result_oop); |
241 } | |
242 } | |
243 } | |
244 | |
0 | 245 void LinkResolver::check_method_accessability(KlassHandle ref_klass, |
246 KlassHandle resolved_klass, | |
247 KlassHandle sel_klass, | |
248 methodHandle sel_method, | |
249 TRAPS) { | |
250 | |
251 AccessFlags flags = sel_method->access_flags(); | |
252 | |
253 // Special case: arrays always override "clone". JVMS 2.15. | |
254 // If the resolved klass is an array class, and the declaring class | |
255 // is java.lang.Object and the method is "clone", set the flags | |
256 // to public. | |
257 // | |
258 // We'll check for the method name first, as that's most likely | |
259 // to be false (so we'll short-circuit out of these tests). | |
260 if (sel_method->name() == vmSymbols::clone_name() && | |
1142 | 261 sel_klass() == SystemDictionary::Object_klass() && |
0 | 262 resolved_klass->oop_is_array()) { |
263 // We need to change "protected" to "public". | |
264 assert(flags.is_protected(), "clone not protected?"); | |
265 jint new_flags = flags.as_int(); | |
266 new_flags = new_flags & (~JVM_ACC_PROTECTED); | |
267 new_flags = new_flags | JVM_ACC_PUBLIC; | |
268 flags.set_flags(new_flags); | |
269 } | |
270 | |
271 if (!Reflection::verify_field_access(ref_klass->as_klassOop(), | |
272 resolved_klass->as_klassOop(), | |
273 sel_klass->as_klassOop(), | |
274 flags, | |
275 true)) { | |
276 ResourceMark rm(THREAD); | |
277 Exceptions::fthrow( | |
278 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
279 vmSymbols::java_lang_IllegalAccessError(), |
0 | 280 "tried to access method %s.%s%s from class %s", |
281 sel_klass->external_name(), | |
282 sel_method->name()->as_C_string(), | |
283 sel_method->signature()->as_C_string(), | |
284 ref_klass->external_name() | |
285 ); | |
286 return; | |
287 } | |
288 } | |
289 | |
290 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle& resolved_klass, | |
291 constantPoolHandle pool, int index, TRAPS) { | |
292 | |
293 // resolve klass | |
294 resolve_klass(resolved_klass, pool, index, CHECK); | |
295 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
296 Symbol* method_name = pool->name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
297 Symbol* method_signature = pool->signature_ref_at(index); |
0 | 298 KlassHandle current_klass(THREAD, pool->pool_holder()); |
299 | |
3785
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
300 if (pool->has_preresolution() |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
301 || (resolved_klass() == SystemDictionary::MethodHandle_klass() && |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
302 methodOopDesc::is_method_handle_invoke_name(method_name))) { |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
303 methodOop result_oop = constantPoolOopDesc::method_at_if_loaded(pool, index); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
304 if (result_oop != NULL) { |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
305 resolved_method = methodHandle(THREAD, result_oop); |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
306 return; |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
307 } |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
308 } |
ddd894528dbc
7056328: JSR 292 invocation sometimes fails in adapters for types not on boot class path
jrose
parents:
3744
diff
changeset
|
309 |
0 | 310 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); |
311 } | |
312 | |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
313 void LinkResolver::resolve_dynamic_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) { |
2357
8033953d67ff
7012648: move JSR 292 to package java.lang.invoke and adjust names
jrose
parents:
2356
diff
changeset
|
314 // The class is java.lang.invoke.MethodHandle |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
315 resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
316 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
317 Symbol* method_name = vmSymbols::invokeExact_name(); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
318 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
319 Symbol* method_signature = pool->signature_ref_at(index); |
1135
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
320 KlassHandle current_klass (THREAD, pool->pool_holder()); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
321 |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
322 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
323 } |
e66fd840cb6b
6893081: method handle & invokedynamic code needs additional cleanup (post 6815692, 6858164)
twisti
parents:
1059
diff
changeset
|
324 |
0 | 325 void LinkResolver::resolve_interface_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) { |
326 | |
327 // resolve klass | |
328 resolve_klass(resolved_klass, pool, index, CHECK); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
329 Symbol* method_name = pool->name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
330 Symbol* method_signature = pool->signature_ref_at(index); |
0 | 331 KlassHandle current_klass(THREAD, pool->pool_holder()); |
332 | |
333 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK); | |
334 } | |
335 | |
336 | |
337 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
338 Symbol* method_name, Symbol* method_signature, |
0 | 339 KlassHandle current_klass, bool check_access, TRAPS) { |
340 | |
341 // 1. check if klass is not interface | |
342 if (resolved_klass->is_interface()) { | |
3324
acf5e660c71a
6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents:
2460
diff
changeset
|
343 ResourceMark rm(THREAD); |
0 | 344 char buf[200]; |
345 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name()); | |
346 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
347 } | |
348 | |
349 // 2. lookup method in resolved klass and its super klasses | |
350 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); | |
351 | |
352 if (resolved_method.is_null()) { // not found in the class hierarchy | |
353 // 3. lookup method in all the interfaces implemented by the resolved klass | |
354 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); | |
355 | |
356 if (resolved_method.is_null()) { | |
710 | 357 // JSR 292: see if this is an implicitly generated method MethodHandle.invoke(*...) |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
358 lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, CHECK); |
710 | 359 } |
360 | |
361 if (resolved_method.is_null()) { | |
0 | 362 // 4. method lookup failed |
363 ResourceMark rm(THREAD); | |
364 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), | |
365 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
366 method_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
367 method_signature)); |
0 | 368 } |
369 } | |
370 | |
371 // 5. check if method is concrete | |
372 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) { | |
373 ResourceMark rm(THREAD); | |
374 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
375 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
376 method_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
377 method_signature)); |
0 | 378 } |
379 | |
380 // 6. access checks, access checking may be turned off when calling from within the VM. | |
381 if (check_access) { | |
382 assert(current_klass.not_null() , "current_klass should not be null"); | |
383 | |
384 // check if method can be accessed by the referring class | |
385 check_method_accessability(current_klass, | |
386 resolved_klass, | |
387 KlassHandle(THREAD, resolved_method->method_holder()), | |
388 resolved_method, | |
389 CHECK); | |
390 | |
391 // check loader constraints | |
392 Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader()); | |
393 Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader()); | |
394 { | |
395 ResourceMark rm(THREAD); | |
396 char* failed_type_name = | |
397 SystemDictionary::check_signature_loaders(method_signature, loader, | |
398 class_loader, true, CHECK); | |
399 if (failed_type_name != NULL) { | |
400 const char* msg = "loader constraint violation: when resolving method" | |
401 " \"%s\" the class loader (instance of %s) of the current class, %s," | |
402 " and the class loader (instance of %s) for resolved class, %s, have" | |
403 " different Class objects for the type %s used in the signature"; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
404 char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); |
0 | 405 const char* loader1 = SystemDictionary::loader_name(loader()); |
406 char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); | |
407 const char* loader2 = SystemDictionary::loader_name(class_loader()); | |
408 char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string(); | |
409 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + | |
410 strlen(current) + strlen(loader2) + strlen(resolved) + | |
411 strlen(failed_type_name); | |
412 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); | |
413 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, | |
414 resolved, failed_type_name); | |
415 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); | |
416 } | |
417 } | |
418 } | |
419 } | |
420 | |
421 void LinkResolver::resolve_interface_method(methodHandle& resolved_method, | |
422 KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
423 Symbol* method_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
424 Symbol* method_signature, |
0 | 425 KlassHandle current_klass, |
426 bool check_access, TRAPS) { | |
427 | |
428 // check if klass is interface | |
429 if (!resolved_klass->is_interface()) { | |
3324
acf5e660c71a
6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents:
2460
diff
changeset
|
430 ResourceMark rm(THREAD); |
0 | 431 char buf[200]; |
432 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", Klass::cast(resolved_klass())->external_name()); | |
433 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
434 } | |
435 | |
436 // lookup method in this interface or its super, java.lang.Object | |
437 lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK); | |
438 | |
439 if (resolved_method.is_null()) { | |
440 // lookup method in all the super-interfaces | |
441 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK); | |
442 if (resolved_method.is_null()) { | |
443 // no method found | |
444 ResourceMark rm(THREAD); | |
445 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(), | |
446 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
447 method_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
448 method_signature)); |
0 | 449 } |
450 } | |
451 | |
452 if (check_access) { | |
453 HandleMark hm(THREAD); | |
454 Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader()); | |
455 Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader()); | |
456 { | |
457 ResourceMark rm(THREAD); | |
458 char* failed_type_name = | |
459 SystemDictionary::check_signature_loaders(method_signature, loader, | |
460 class_loader, true, CHECK); | |
461 if (failed_type_name != NULL) { | |
462 const char* msg = "loader constraint violation: when resolving " | |
463 "interface method \"%s\" the class loader (instance of %s) of the " | |
464 "current class, %s, and the class loader (instance of %s) for " | |
465 "resolved class, %s, have different Class objects for the type %s " | |
466 "used in the signature"; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
467 char* sig = methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),method_name,method_signature); |
0 | 468 const char* loader1 = SystemDictionary::loader_name(loader()); |
469 char* current = instanceKlass::cast(current_klass())->name()->as_C_string(); | |
470 const char* loader2 = SystemDictionary::loader_name(class_loader()); | |
471 char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string(); | |
472 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + | |
473 strlen(current) + strlen(loader2) + strlen(resolved) + | |
474 strlen(failed_type_name); | |
475 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); | |
476 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, | |
477 resolved, failed_type_name); | |
478 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); | |
479 } | |
480 } | |
481 } | |
482 } | |
483 | |
484 //------------------------------------------------------------------------------------------------------------------------ | |
485 // Field resolution | |
486 | |
487 void LinkResolver::check_field_accessability(KlassHandle ref_klass, | |
488 KlassHandle resolved_klass, | |
489 KlassHandle sel_klass, | |
490 fieldDescriptor& fd, | |
491 TRAPS) { | |
492 if (!Reflection::verify_field_access(ref_klass->as_klassOop(), | |
493 resolved_klass->as_klassOop(), | |
494 sel_klass->as_klassOop(), | |
495 fd.access_flags(), | |
496 true)) { | |
497 ResourceMark rm(THREAD); | |
498 Exceptions::fthrow( | |
499 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
500 vmSymbols::java_lang_IllegalAccessError(), |
0 | 501 "tried to access field %s.%s from class %s", |
502 sel_klass->external_name(), | |
503 fd.name()->as_C_string(), | |
504 ref_klass->external_name() | |
505 ); | |
506 return; | |
507 } | |
508 } | |
509 | |
510 void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) { | |
511 resolve_field(result, pool, index, byte, check_only, true, CHECK); | |
512 } | |
513 | |
514 void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS) { | |
515 assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic || | |
516 byte == Bytecodes::_getfield || byte == Bytecodes::_putfield, "bad bytecode"); | |
517 | |
518 bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic); | |
519 bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic); | |
520 | |
521 // resolve specified klass | |
522 KlassHandle resolved_klass; | |
523 if (update_pool) { | |
524 resolve_klass(resolved_klass, pool, index, CHECK); | |
525 } else { | |
526 resolve_klass_no_update(resolved_klass, pool, index, CHECK); | |
527 } | |
528 // Load these early in case the resolve of the containing klass fails | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
529 Symbol* field = pool->name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
530 Symbol* sig = pool->signature_ref_at(index); |
0 | 531 // Check if there's a resolved klass containing the field |
532 if( resolved_klass.is_null() ) { | |
533 ResourceMark rm(THREAD); | |
534 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); | |
535 } | |
536 | |
537 // Resolve instance field | |
538 fieldDescriptor fd; // find_field initializes fd if found | |
539 KlassHandle sel_klass(THREAD, instanceKlass::cast(resolved_klass())->find_field(field, sig, &fd)); | |
540 // check if field exists; i.e., if a klass containing the field def has been selected | |
541 if (sel_klass.is_null()){ | |
542 ResourceMark rm(THREAD); | |
543 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string()); | |
544 } | |
545 | |
546 // check access | |
547 KlassHandle ref_klass(THREAD, pool->pool_holder()); | |
548 check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK); | |
549 | |
550 // check for errors | |
551 if (is_static != fd.is_static()) { | |
3324
acf5e660c71a
6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents:
2460
diff
changeset
|
552 ResourceMark rm(THREAD); |
0 | 553 char msg[200]; |
554 jio_snprintf(msg, sizeof(msg), "Expected %s field %s.%s", is_static ? "static" : "non-static", Klass::cast(resolved_klass())->external_name(), fd.name()->as_C_string()); | |
555 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg); | |
556 } | |
557 | |
558 // Final fields can only be accessed from its own class. | |
559 if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) { | |
560 THROW(vmSymbols::java_lang_IllegalAccessError()); | |
561 } | |
562 | |
563 // initialize resolved_klass if necessary | |
564 // note 1: the klass which declared the field must be initialized (i.e, sel_klass) | |
565 // according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99) | |
566 // | |
567 // note 2: we don't want to force initialization if we are just checking | |
568 // if the field access is legal; e.g., during compilation | |
569 if (is_static && !check_only) { | |
570 sel_klass->initialize(CHECK); | |
571 } | |
572 | |
573 { | |
574 HandleMark hm(THREAD); | |
575 Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader()); | |
576 Handle sel_loader (THREAD, instanceKlass::cast(sel_klass())->class_loader()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
577 Symbol* signature_ref = pool->signature_ref_at(index); |
0 | 578 { |
579 ResourceMark rm(THREAD); | |
580 char* failed_type_name = | |
581 SystemDictionary::check_signature_loaders(signature_ref, | |
582 ref_loader, sel_loader, | |
583 false, | |
584 CHECK); | |
585 if (failed_type_name != NULL) { | |
586 const char* msg = "loader constraint violation: when resolving field" | |
587 " \"%s\" the class loader (instance of %s) of the referring class, " | |
588 "%s, and the class loader (instance of %s) for the field's resolved " | |
589 "type, %s, have different Class objects for that type"; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
590 char* field_name = field->as_C_string(); |
0 | 591 const char* loader1 = SystemDictionary::loader_name(ref_loader()); |
592 char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string(); | |
593 const char* loader2 = SystemDictionary::loader_name(sel_loader()); | |
594 size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) + | |
595 strlen(sel) + strlen(loader2) + strlen(failed_type_name); | |
596 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); | |
597 jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2, | |
598 failed_type_name); | |
599 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); | |
600 } | |
601 } | |
602 } | |
603 | |
604 // return information. note that the klass is set to the actual klass containing the | |
605 // field, otherwise access of static fields in superclasses will not work. | |
606 KlassHandle holder (THREAD, fd.field_holder()); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
607 Symbol* name = fd.name(); |
0 | 608 result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags()); |
609 } | |
610 | |
611 | |
612 //------------------------------------------------------------------------------------------------------------------------ | |
613 // Invoke resolution | |
614 // | |
615 // Naming conventions: | |
616 // | |
617 // resolved_method the specified method (i.e., static receiver specified via constant pool index) | |
618 // sel_method the selected method (selected via run-time lookup; e.g., based on dynamic receiver class) | |
619 // resolved_klass the specified klass (i.e., specified via constant pool index) | |
620 // recv_klass the receiver klass | |
621 | |
622 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
623 void LinkResolver::resolve_static_call(CallInfo& result, KlassHandle& resolved_klass, Symbol* method_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
624 Symbol* method_signature, KlassHandle current_klass, |
0 | 625 bool check_access, bool initialize_class, TRAPS) { |
626 methodHandle resolved_method; | |
627 linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | |
628 resolved_klass = KlassHandle(THREAD, Klass::cast(resolved_method->method_holder())); | |
629 | |
630 // Initialize klass (this should only happen if everything is ok) | |
631 if (initialize_class && resolved_klass->should_be_initialized()) { | |
632 resolved_klass->initialize(CHECK); | |
633 linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | |
634 } | |
635 | |
636 // setup result | |
637 result.set_static(resolved_klass, resolved_method, CHECK); | |
638 } | |
639 | |
640 // throws linktime exceptions | |
641 void LinkResolver::linktime_resolve_static_method(methodHandle& resolved_method, KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
642 Symbol* method_name, Symbol* method_signature, |
0 | 643 KlassHandle current_klass, bool check_access, TRAPS) { |
644 | |
645 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | |
646 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier"); | |
647 | |
648 // check if static | |
649 if (!resolved_method->is_static()) { | |
3324
acf5e660c71a
6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents:
2460
diff
changeset
|
650 ResourceMark rm(THREAD); |
0 | 651 char buf[200]; |
652 jio_snprintf(buf, sizeof(buf), "Expected static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
653 resolved_method->name(), | |
654 resolved_method->signature())); | |
655 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
656 } | |
657 } | |
658 | |
659 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
660 void LinkResolver::resolve_special_call(CallInfo& result, KlassHandle resolved_klass, Symbol* method_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
661 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { |
0 | 662 methodHandle resolved_method; |
663 linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | |
664 runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK); | |
665 } | |
666 | |
667 // throws linktime exceptions | |
668 void LinkResolver::linktime_resolve_special_method(methodHandle& resolved_method, KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
669 Symbol* method_name, Symbol* method_signature, |
0 | 670 KlassHandle current_klass, bool check_access, TRAPS) { |
671 | |
672 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | |
673 | |
674 // check if method name is <init>, that it is found in same klass as static type | |
675 if (resolved_method->name() == vmSymbols::object_initializer_name() && | |
676 resolved_method->method_holder() != resolved_klass()) { | |
677 ResourceMark rm(THREAD); | |
678 Exceptions::fthrow( | |
679 THREAD_AND_LOCATION, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
680 vmSymbols::java_lang_NoSuchMethodError(), |
0 | 681 "%s: method %s%s not found", |
682 resolved_klass->external_name(), | |
683 resolved_method->name()->as_C_string(), | |
684 resolved_method->signature()->as_C_string() | |
685 ); | |
686 return; | |
687 } | |
688 | |
689 // check if not static | |
690 if (resolved_method->is_static()) { | |
3324
acf5e660c71a
6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents:
2460
diff
changeset
|
691 ResourceMark rm(THREAD); |
0 | 692 char buf[200]; |
693 jio_snprintf(buf, sizeof(buf), | |
694 "Expecting non-static method %s", | |
695 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
696 resolved_method->name(), | |
697 resolved_method->signature())); | |
698 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
699 } | |
700 } | |
701 | |
702 // throws runtime exceptions | |
703 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, | |
704 KlassHandle current_klass, bool check_access, TRAPS) { | |
705 | |
706 // resolved method is selected method unless we have an old-style lookup | |
707 methodHandle sel_method(THREAD, resolved_method()); | |
708 | |
709 // check if this is an old-style super call and do a new lookup if so | |
710 { KlassHandle method_klass = KlassHandle(THREAD, | |
711 resolved_method->method_holder()); | |
712 | |
713 if (check_access && | |
714 // a) check if ACC_SUPER flag is set for the current class | |
715 current_klass->is_super() && | |
716 // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!) | |
717 current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() && | |
718 // c) check if the method is not <init> | |
719 resolved_method->name() != vmSymbols::object_initializer_name()) { | |
720 // Lookup super method | |
721 KlassHandle super_klass(THREAD, current_klass->super()); | |
722 lookup_instance_method_in_klasses(sel_method, super_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
723 resolved_method->name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
724 resolved_method->signature(), CHECK); |
0 | 725 // check if found |
726 if (sel_method.is_null()) { | |
727 ResourceMark rm(THREAD); | |
728 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
729 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
730 resolved_method->name(), | |
731 resolved_method->signature())); | |
732 } | |
733 } | |
734 } | |
735 | |
736 // check if not static | |
737 if (sel_method->is_static()) { | |
3324
acf5e660c71a
6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents:
2460
diff
changeset
|
738 ResourceMark rm(THREAD); |
0 | 739 char buf[200]; |
740 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
741 resolved_method->name(), | |
742 resolved_method->signature())); | |
743 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
744 } | |
745 | |
746 // check if abstract | |
747 if (sel_method->is_abstract()) { | |
748 ResourceMark rm(THREAD); | |
749 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
750 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
751 sel_method->name(), | |
752 sel_method->signature())); | |
753 } | |
754 | |
755 // setup result | |
756 result.set_static(resolved_klass, sel_method, CHECK); | |
757 } | |
758 | |
759 void LinkResolver::resolve_virtual_call(CallInfo& result, Handle recv, KlassHandle receiver_klass, KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
760 Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, |
0 | 761 bool check_access, bool check_null_and_abstract, TRAPS) { |
762 methodHandle resolved_method; | |
763 linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | |
764 runtime_resolve_virtual_method(result, resolved_method, resolved_klass, recv, receiver_klass, check_null_and_abstract, CHECK); | |
765 } | |
766 | |
767 // throws linktime exceptions | |
768 void LinkResolver::linktime_resolve_virtual_method(methodHandle &resolved_method, KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
769 Symbol* method_name, Symbol* method_signature, |
0 | 770 KlassHandle current_klass, bool check_access, TRAPS) { |
771 // normal method resolution | |
772 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | |
773 | |
774 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); | |
775 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); | |
776 | |
777 // check if not static | |
778 if (resolved_method->is_static()) { | |
3324
acf5e660c71a
6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents:
2460
diff
changeset
|
779 ResourceMark rm(THREAD); |
0 | 780 char buf[200]; |
781 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
782 resolved_method->name(), | |
783 resolved_method->signature())); | |
784 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
785 } | |
786 } | |
787 | |
788 // throws runtime exceptions | |
789 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result, | |
790 methodHandle resolved_method, | |
791 KlassHandle resolved_klass, | |
792 Handle recv, | |
793 KlassHandle recv_klass, | |
794 bool check_null_and_abstract, | |
795 TRAPS) { | |
796 | |
797 // setup default return values | |
798 int vtable_index = methodOopDesc::invalid_vtable_index; | |
799 methodHandle selected_method; | |
800 | |
801 assert(recv.is_null() || recv->is_oop(), "receiver is not an oop"); | |
802 | |
803 // runtime method resolution | |
804 if (check_null_and_abstract && recv.is_null()) { // check if receiver exists | |
805 THROW(vmSymbols::java_lang_NullPointerException()); | |
806 } | |
807 | |
808 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's | |
809 // has not been rewritten, and the vtable initialized. | |
810 assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked"); | |
811 | |
812 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's | |
813 // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since | |
814 // a missing receiver might result in a bogus lookup. | |
815 assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked"); | |
816 | |
817 // do lookup based on receiver klass using the vtable index | |
818 if (resolved_method->method_holder()->klass_part()->is_interface()) { // miranda method | |
819 vtable_index = vtable_index_of_miranda_method(resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
820 resolved_method->name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
821 resolved_method->signature(), CHECK); |
0 | 822 assert(vtable_index >= 0 , "we should have valid vtable index at this point"); |
823 | |
824 instanceKlass* inst = instanceKlass::cast(recv_klass()); | |
825 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); | |
826 } else { | |
827 // at this point we are sure that resolved_method is virtual and not | |
828 // a miranda method; therefore, it must have a valid vtable index. | |
829 vtable_index = resolved_method->vtable_index(); | |
830 // We could get a negative vtable_index for final methods, | |
831 // because as an optimization they are they are never put in the vtable, | |
832 // unless they override an existing method. | |
833 // If we do get a negative, it means the resolved method is the the selected | |
834 // method, and it can never be changed by an override. | |
835 if (vtable_index == methodOopDesc::nonvirtual_vtable_index) { | |
836 assert(resolved_method->can_be_statically_bound(), "cannot override this method"); | |
837 selected_method = resolved_method; | |
838 } else { | |
839 // recv_klass might be an arrayKlassOop but all vtables start at | |
840 // the same place. The cast is to avoid virtual call and assertion. | |
841 instanceKlass* inst = (instanceKlass*)recv_klass()->klass_part(); | |
842 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index)); | |
843 } | |
844 } | |
845 | |
846 // check if method exists | |
847 if (selected_method.is_null()) { | |
848 ResourceMark rm(THREAD); | |
849 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
850 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
851 resolved_method->name(), | |
852 resolved_method->signature())); | |
853 } | |
854 | |
855 // check if abstract | |
856 if (check_null_and_abstract && selected_method->is_abstract()) { | |
857 ResourceMark rm(THREAD); | |
858 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
859 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()), | |
860 selected_method->name(), | |
861 selected_method->signature())); | |
862 } | |
863 | |
864 // setup result | |
865 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK); | |
866 } | |
867 | |
868 void LinkResolver::resolve_interface_call(CallInfo& result, Handle recv, KlassHandle recv_klass, KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
869 Symbol* method_name, Symbol* method_signature, KlassHandle current_klass, |
0 | 870 bool check_access, bool check_null_and_abstract, TRAPS) { |
871 methodHandle resolved_method; | |
872 linktime_resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | |
873 runtime_resolve_interface_method(result, resolved_method, resolved_klass, recv, recv_klass, check_null_and_abstract, CHECK); | |
874 } | |
875 | |
876 // throws linktime exceptions | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
877 void LinkResolver::linktime_resolve_interface_method(methodHandle& resolved_method, KlassHandle resolved_klass, Symbol* method_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
878 Symbol* method_signature, KlassHandle current_klass, bool check_access, TRAPS) { |
0 | 879 // normal interface method resolution |
880 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK); | |
881 | |
882 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier"); | |
883 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier"); | |
884 } | |
885 | |
886 // throws runtime exceptions | |
887 void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass, | |
888 Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) { | |
889 // check if receiver exists | |
890 if (check_null_and_abstract && recv.is_null()) { | |
891 THROW(vmSymbols::java_lang_NullPointerException()); | |
892 } | |
893 | |
894 // check if receiver klass implements the resolved interface | |
895 if (!recv_klass->is_subtype_of(resolved_klass())) { | |
3324
acf5e660c71a
6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents:
2460
diff
changeset
|
896 ResourceMark rm(THREAD); |
0 | 897 char buf[200]; |
898 jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s", | |
899 (Klass::cast(recv_klass()))->external_name(), | |
900 (Klass::cast(resolved_klass()))->external_name()); | |
901 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf); | |
902 } | |
903 // do lookup based on receiver klass | |
904 methodHandle sel_method; | |
905 lookup_instance_method_in_klasses(sel_method, recv_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
906 resolved_method->name(), |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
907 resolved_method->signature(), CHECK); |
0 | 908 // check if method exists |
909 if (sel_method.is_null()) { | |
910 ResourceMark rm(THREAD); | |
911 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
912 methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()), | |
913 resolved_method->name(), | |
914 resolved_method->signature())); | |
915 } | |
916 // check if public | |
917 if (!sel_method->is_public()) { | |
918 ResourceMark rm(THREAD); | |
919 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(), | |
920 methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()), | |
921 sel_method->name(), | |
922 sel_method->signature())); | |
923 } | |
924 // check if abstract | |
925 if (check_null_and_abstract && sel_method->is_abstract()) { | |
926 ResourceMark rm(THREAD); | |
927 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(), | |
928 methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()), | |
929 sel_method->name(), | |
930 sel_method->signature())); | |
931 } | |
932 // setup result | |
933 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK); | |
934 } | |
935 | |
936 | |
937 methodHandle LinkResolver::linktime_resolve_interface_method_or_null( | |
938 KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
939 Symbol* method_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
940 Symbol* method_signature, |
0 | 941 KlassHandle current_klass, |
942 bool check_access) { | |
943 EXCEPTION_MARK; | |
944 methodHandle method_result; | |
945 linktime_resolve_interface_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD); | |
946 if (HAS_PENDING_EXCEPTION) { | |
947 CLEAR_PENDING_EXCEPTION; | |
948 return methodHandle(); | |
949 } else { | |
950 return method_result; | |
951 } | |
952 } | |
953 | |
954 methodHandle LinkResolver::linktime_resolve_virtual_method_or_null( | |
955 KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
956 Symbol* method_name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
957 Symbol* method_signature, |
0 | 958 KlassHandle current_klass, |
959 bool check_access) { | |
960 EXCEPTION_MARK; | |
961 methodHandle method_result; | |
962 linktime_resolve_virtual_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD); | |
963 if (HAS_PENDING_EXCEPTION) { | |
964 CLEAR_PENDING_EXCEPTION; | |
965 return methodHandle(); | |
966 } else { | |
967 return method_result; | |
968 } | |
969 } | |
970 | |
971 methodHandle LinkResolver::resolve_virtual_call_or_null( | |
972 KlassHandle receiver_klass, | |
973 KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
974 Symbol* name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
975 Symbol* signature, |
0 | 976 KlassHandle current_klass) { |
977 EXCEPTION_MARK; | |
978 CallInfo info; | |
979 resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD); | |
980 if (HAS_PENDING_EXCEPTION) { | |
981 CLEAR_PENDING_EXCEPTION; | |
982 return methodHandle(); | |
983 } | |
984 return info.selected_method(); | |
985 } | |
986 | |
987 methodHandle LinkResolver::resolve_interface_call_or_null( | |
988 KlassHandle receiver_klass, | |
989 KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
990 Symbol* name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
991 Symbol* signature, |
0 | 992 KlassHandle current_klass) { |
993 EXCEPTION_MARK; | |
994 CallInfo info; | |
995 resolve_interface_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD); | |
996 if (HAS_PENDING_EXCEPTION) { | |
997 CLEAR_PENDING_EXCEPTION; | |
998 return methodHandle(); | |
999 } | |
1000 return info.selected_method(); | |
1001 } | |
1002 | |
1003 int LinkResolver::resolve_virtual_vtable_index( | |
1004 KlassHandle receiver_klass, | |
1005 KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1006 Symbol* name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1007 Symbol* signature, |
0 | 1008 KlassHandle current_klass) { |
1009 EXCEPTION_MARK; | |
1010 CallInfo info; | |
1011 resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD); | |
1012 if (HAS_PENDING_EXCEPTION) { | |
1013 CLEAR_PENDING_EXCEPTION; | |
1014 return methodOopDesc::invalid_vtable_index; | |
1015 } | |
1016 return info.vtable_index(); | |
1017 } | |
1018 | |
1019 methodHandle LinkResolver::resolve_static_call_or_null( | |
1020 KlassHandle resolved_klass, | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1021 Symbol* name, |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1022 Symbol* signature, |
0 | 1023 KlassHandle current_klass) { |
1024 EXCEPTION_MARK; | |
1025 CallInfo info; | |
1026 resolve_static_call(info, resolved_klass, name, signature, current_klass, true, false, THREAD); | |
1027 if (HAS_PENDING_EXCEPTION) { | |
1028 CLEAR_PENDING_EXCEPTION; | |
1029 return methodHandle(); | |
1030 } | |
1031 return info.selected_method(); | |
1032 } | |
1033 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1034 methodHandle LinkResolver::resolve_special_call_or_null(KlassHandle resolved_klass, Symbol* name, Symbol* signature, |
0 | 1035 KlassHandle current_klass) { |
1036 EXCEPTION_MARK; | |
1037 CallInfo info; | |
1038 resolve_special_call(info, resolved_klass, name, signature, current_klass, true, THREAD); | |
1039 if (HAS_PENDING_EXCEPTION) { | |
1040 CLEAR_PENDING_EXCEPTION; | |
1041 return methodHandle(); | |
1042 } | |
1043 return info.selected_method(); | |
1044 } | |
1045 | |
1046 | |
1047 | |
1048 //------------------------------------------------------------------------------------------------------------------------ | |
1049 // ConstantPool entries | |
1050 | |
1051 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) { | |
1052 switch (byte) { | |
1053 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break; | |
1054 case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break; | |
1055 case Bytecodes::_invokevirtual : resolve_invokevirtual (result, recv, pool, index, CHECK); break; | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1056 case Bytecodes::_invokedynamic : resolve_invokedynamic (result, pool, index, CHECK); break; |
0 | 1057 case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break; |
1058 } | |
1059 return; | |
1060 } | |
1061 | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1062 void LinkResolver::resolve_pool(KlassHandle& resolved_klass, Symbol*& method_name, Symbol*& method_signature, |
0 | 1063 KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS) { |
1064 // resolve klass | |
1065 resolve_klass(resolved_klass, pool, index, CHECK); | |
1066 | |
1067 // Get name, signature, and static klass | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1068 method_name = pool->name_ref_at(index); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1069 method_signature = pool->signature_ref_at(index); |
0 | 1070 current_klass = KlassHandle(THREAD, pool->pool_holder()); |
1071 } | |
1072 | |
1073 | |
1074 void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { | |
1075 KlassHandle resolved_klass; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1076 Symbol* method_name = NULL; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1077 Symbol* method_signature = NULL; |
0 | 1078 KlassHandle current_klass; |
1079 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); | |
1080 resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); | |
1081 } | |
1082 | |
1083 | |
1084 void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) { | |
1085 KlassHandle resolved_klass; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1086 Symbol* method_name = NULL; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1087 Symbol* method_signature = NULL; |
0 | 1088 KlassHandle current_klass; |
1089 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); | |
1090 resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK); | |
1091 } | |
1092 | |
1093 | |
1094 void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv, | |
1095 constantPoolHandle pool, int index, | |
1096 TRAPS) { | |
1097 | |
1098 KlassHandle resolved_klass; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1099 Symbol* method_name = NULL; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1100 Symbol* method_signature = NULL; |
0 | 1101 KlassHandle current_klass; |
1102 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); | |
1103 KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass()); | |
1104 resolve_virtual_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); | |
1105 } | |
1106 | |
1107 | |
1108 void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) { | |
1109 KlassHandle resolved_klass; | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1110 Symbol* method_name = NULL; |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1111 Symbol* method_signature = NULL; |
0 | 1112 KlassHandle current_klass; |
1113 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK); | |
1114 KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass()); | |
1115 resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK); | |
1116 } | |
1117 | |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1118 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1119 void LinkResolver::resolve_invokedynamic(CallInfo& result, constantPoolHandle pool, int raw_index, TRAPS) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1120 assert(EnableInvokeDynamic, ""); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1121 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1122 // This guy is reached from InterpreterRuntime::resolve_invokedynamic. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1123 |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1124 // At this point, we only need the signature, and can ignore the name. |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1125 Symbol* method_signature = pool->signature_ref_at(raw_index); // raw_index works directly |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
1126 Symbol* method_name = vmSymbols::invokeExact_name(); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1127 KlassHandle resolved_klass = SystemDictionaryHandles::MethodHandle_klass(); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1128 |
1507
cd5dbf694d45
6939134: JSR 292 adjustments to method handle invocation
jrose
parents:
1142
diff
changeset
|
1129 // JSR 292: this must be an implicitly generated method MethodHandle.invokeExact(*...) |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1130 // The extra MH receiver will be inserted into the stack on every call. |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1131 methodHandle resolved_method; |
1508
2ffde6cfe049
6939196: method handle signatures off the boot class path get linkage errors
jrose
parents:
1507
diff
changeset
|
1132 KlassHandle current_klass(THREAD, pool->pool_holder()); |
3744
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1133 lookup_implicit_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, THREAD); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1134 if (HAS_PENDING_EXCEPTION) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1135 if (PENDING_EXCEPTION->is_a(SystemDictionary::BootstrapMethodError_klass())) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1136 // throw these guys, since they are already wrapped |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1137 return; |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1138 } |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1139 if (!PENDING_EXCEPTION->is_a(SystemDictionary::LinkageError_klass())) { |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1140 // intercept only LinkageErrors which might have failed to wrap |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1141 return; |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1142 } |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1143 // See the "Linking Exceptions" section for the invokedynamic instruction in the JVMS. |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1144 Handle ex(THREAD, PENDING_EXCEPTION); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1145 CLEAR_PENDING_EXCEPTION; |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1146 oop bsme = Klass::cast(SystemDictionary::BootstrapMethodError_klass())->java_mirror(); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1147 MethodHandles::raise_exception(Bytecodes::_athrow, ex(), bsme, CHECK); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1148 // java code should not return, but if it does throw out anyway |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1149 THROW(vmSymbols::java_lang_InternalError()); |
60b8287df30e
7049415: Failure of resolution of sym.reference to the c.s.s. should be wrapped in BootstrapMethodError
jrose
parents:
3324
diff
changeset
|
1150 } |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1151 if (resolved_method.is_null()) { |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1152 THROW(vmSymbols::java_lang_InternalError()); |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1153 } |
1660
083fde3b838e
6964498: JSR 292 invokedynamic sites need local bootstrap methods
jrose
parents:
1552
diff
changeset
|
1154 result.set_dynamic(resolved_method, CHECK); |
726
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1155 } |
be93aad57795
6655646: dynamic languages need dynamically linked call sites
jrose
parents:
710
diff
changeset
|
1156 |
0 | 1157 //------------------------------------------------------------------------------------------------------------------------ |
1158 #ifndef PRODUCT | |
1159 | |
1160 void FieldAccessInfo::print() { | |
1161 ResourceMark rm; | |
1162 tty->print_cr("Field %s@%d", name()->as_C_string(), field_offset()); | |
1163 } | |
1164 | |
1165 #endif |