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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
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
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
25 #include "precompiled.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
26 #include "classfile/systemDictionary.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
27 #include "classfile/vmSymbols.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
28 #include "compiler/compileBroker.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
29 #include "gc_interface/collectedHeap.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
30 #include "interpreter/bytecode.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
31 #include "interpreter/interpreterRuntime.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
32 #include "interpreter/linkResolver.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
33 #include "memory/resourceArea.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
34 #include "memory/universe.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
35 #include "oops/instanceKlass.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
36 #include "oops/objArrayOop.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
37 #include "prims/methodHandles.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
38 #include "prims/nativeLookup.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
39 #include "runtime/compilationPolicy.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
40 #include "runtime/fieldDescriptor.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
41 #include "runtime/frame.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
42 #include "runtime/handles.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
43 #include "runtime/reflection.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
44 #include "runtime/signature.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
45 #include "runtime/vmThread.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
46 #ifdef TARGET_OS_FAMILY_linux
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
47 # include "thread_linux.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
48 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
49 #ifdef TARGET_OS_FAMILY_solaris
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
50 # include "thread_solaris.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
51 #endif
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
52 #ifdef TARGET_OS_FAMILY_windows
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
53 # include "thread_windows.inline.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1783
diff changeset
54 #endif
3960
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 3837
diff changeset
55 #ifdef TARGET_OS_FAMILY_bsd
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 3837
diff changeset
56 # include "thread_bsd.inline.hpp"
f08d439fab8c 7089790: integrate bsd-port changes
never
parents: 3837
diff changeset
57 #endif
0
a61af66fc99e Initial load
duke
parents:
diff changeset
58
a61af66fc99e Initial load
duke
parents:
diff changeset
59 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
60 // Implementation of FieldAccessInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
63 BasicType field_type, AccessFlags access_flags) {
a61af66fc99e Initial load
duke
parents:
diff changeset
64 _klass = klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
65 _name = name;
a61af66fc99e Initial load
duke
parents:
diff changeset
66 _field_index = field_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
67 _field_offset = field_offset;
a61af66fc99e Initial load
duke
parents:
diff changeset
68 _field_type = field_type;
a61af66fc99e Initial load
duke
parents:
diff changeset
69 _access_flags = access_flags;
a61af66fc99e Initial load
duke
parents:
diff changeset
70 }
a61af66fc99e Initial load
duke
parents:
diff changeset
71
a61af66fc99e Initial load
duke
parents:
diff changeset
72
a61af66fc99e Initial load
duke
parents:
diff changeset
73 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
74 // Implementation of CallInfo
a61af66fc99e Initial load
duke
parents:
diff changeset
75
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 void CallInfo::set_static(KlassHandle resolved_klass, methodHandle resolved_method, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
78 int vtable_index = methodOopDesc::nonvirtual_vtable_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
79 set_common(resolved_klass, resolved_klass, resolved_method, resolved_method, vtable_index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
80 }
a61af66fc99e Initial load
duke
parents:
diff changeset
81
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83 void CallInfo::set_interface(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
84 // This is only called for interface methods. If the resolved_method
a61af66fc99e Initial load
duke
parents:
diff changeset
85 // comes from java/lang/Object, it can be the subject of a virtual call, so
a61af66fc99e Initial load
duke
parents:
diff changeset
86 // we should pick the vtable index from the resolved method.
a61af66fc99e Initial load
duke
parents:
diff changeset
87 // Other than that case, there is no valid vtable index to specify.
a61af66fc99e Initial load
duke
parents:
diff changeset
88 int vtable_index = methodOopDesc::invalid_vtable_index;
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1135
diff changeset
89 if (resolved_method->method_holder() == SystemDictionary::Object_klass()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
90 assert(resolved_method->vtable_index() == selected_method->vtable_index(), "sanity check");
a61af66fc99e Initial load
duke
parents:
diff changeset
91 vtable_index = resolved_method->vtable_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
92 }
a61af66fc99e Initial load
duke
parents:
diff changeset
93 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
94 }
a61af66fc99e Initial load
duke
parents:
diff changeset
95
a61af66fc99e Initial load
duke
parents:
diff changeset
96 void CallInfo::set_virtual(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
97 assert(vtable_index >= 0 || vtable_index == methodOopDesc::nonvirtual_vtable_index, "valid index");
a61af66fc99e Initial load
duke
parents:
diff changeset
98 set_common(resolved_klass, selected_klass, resolved_method, selected_method, vtable_index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
110 void CallInfo::set_common(KlassHandle resolved_klass, KlassHandle selected_klass, methodHandle resolved_method, methodHandle selected_method, int vtable_index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
111 assert(resolved_method->signature() == selected_method->signature(), "signatures must correspond");
a61af66fc99e Initial load
duke
parents:
diff changeset
112 _resolved_klass = resolved_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
113 _selected_klass = selected_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
114 _resolved_method = resolved_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
115 _selected_method = selected_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
116 _vtable_index = vtable_index;
1783
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1660
diff changeset
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
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1660
diff changeset
120 // Note: with several active threads, the must_be_compiled may be true
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1660
diff changeset
121 // while can_be_compiled is false; remove assert
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1660
diff changeset
122 // assert(CompilationPolicy::can_be_compiled(selected_method), "cannot compile");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
123 if (THREAD->is_Compiler_thread()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
124 // don't force compilation, resolve was on behalf of compiler
a61af66fc99e Initial load
duke
parents:
diff changeset
125 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
d5d065957597 6953144: Tiered compilation
iveresov
parents: 1660
diff changeset
139 methodHandle(), 0, "must_be_compiled", CHECK);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
140 }
a61af66fc99e Initial load
duke
parents:
diff changeset
141 }
a61af66fc99e Initial load
duke
parents:
diff changeset
142
a61af66fc99e Initial load
duke
parents:
diff changeset
143
a61af66fc99e Initial load
duke
parents:
diff changeset
144 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Klass resolution
a61af66fc99e Initial load
duke
parents:
diff changeset
146
a61af66fc99e Initial load
duke
parents:
diff changeset
147 void LinkResolver::check_klass_accessability(KlassHandle ref_klass, KlassHandle sel_klass, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
148 if (!Reflection::verify_class_access(ref_klass->as_klassOop(),
a61af66fc99e Initial load
duke
parents:
diff changeset
149 sel_klass->as_klassOop(),
a61af66fc99e Initial load
duke
parents:
diff changeset
150 true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
151 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
152 Exceptions::fthrow(
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
155 "tried to access class %s from class %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
156 sel_klass->external_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
157 ref_klass->external_name()
a61af66fc99e Initial load
duke
parents:
diff changeset
158 );
a61af66fc99e Initial load
duke
parents:
diff changeset
159 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161 }
a61af66fc99e Initial load
duke
parents:
diff changeset
162
a61af66fc99e Initial load
duke
parents:
diff changeset
163 void LinkResolver::resolve_klass(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
164 klassOop result_oop = pool->klass_ref_at(index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
165 result = KlassHandle(THREAD, result_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 }
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 void LinkResolver::resolve_klass_no_update(KlassHandle& result, constantPoolHandle pool, int index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 klassOop result_oop =
a61af66fc99e Initial load
duke
parents:
diff changeset
170 constantPoolOopDesc::klass_ref_at_if_loaded_check(pool, index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
171 result = KlassHandle(THREAD, result_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
172 }
a61af66fc99e Initial load
duke
parents:
diff changeset
173
a61af66fc99e Initial load
duke
parents:
diff changeset
174
a61af66fc99e Initial load
duke
parents:
diff changeset
175 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
176 // Method resolution
a61af66fc99e Initial load
duke
parents:
diff changeset
177 //
a61af66fc99e Initial load
duke
parents:
diff changeset
178 // According to JVM spec. $5.4.3c & $5.4.3d
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
191 result = methodHandle(THREAD, result_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
192 }
a61af66fc99e Initial load
duke
parents:
diff changeset
193
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
197 result = methodHandle(THREAD, result_oop);
a61af66fc99e Initial load
duke
parents:
diff changeset
198 while (!result.is_null() && result->is_static()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
201 }
a61af66fc99e Initial load
duke
parents:
diff changeset
202 }
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
206 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
209 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
214 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
ed69575596ac 6981791: remove experimental code for JSR 292
jrose
parents: 2416
diff changeset
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
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
237 CHECK);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
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
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
240 result = methodHandle(THREAD, result_oop);
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
241 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
242 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
243 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
244
0
a61af66fc99e Initial load
duke
parents:
diff changeset
245 void LinkResolver::check_method_accessability(KlassHandle ref_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
246 KlassHandle resolved_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
247 KlassHandle sel_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
248 methodHandle sel_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
249 TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
250
a61af66fc99e Initial load
duke
parents:
diff changeset
251 AccessFlags flags = sel_method->access_flags();
a61af66fc99e Initial load
duke
parents:
diff changeset
252
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // Special case: arrays always override "clone". JVMS 2.15.
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // If the resolved klass is an array class, and the declaring class
a61af66fc99e Initial load
duke
parents:
diff changeset
255 // is java.lang.Object and the method is "clone", set the flags
a61af66fc99e Initial load
duke
parents:
diff changeset
256 // to public.
a61af66fc99e Initial load
duke
parents:
diff changeset
257 //
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // We'll check for the method name first, as that's most likely
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // to be false (so we'll short-circuit out of these tests).
a61af66fc99e Initial load
duke
parents:
diff changeset
260 if (sel_method->name() == vmSymbols::clone_name() &&
1142
4ce7240d622c 6914300: ciEnv should export all well known classes
never
parents: 1135
diff changeset
261 sel_klass() == SystemDictionary::Object_klass() &&
0
a61af66fc99e Initial load
duke
parents:
diff changeset
262 resolved_klass->oop_is_array()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
263 // We need to change "protected" to "public".
a61af66fc99e Initial load
duke
parents:
diff changeset
264 assert(flags.is_protected(), "clone not protected?");
a61af66fc99e Initial load
duke
parents:
diff changeset
265 jint new_flags = flags.as_int();
a61af66fc99e Initial load
duke
parents:
diff changeset
266 new_flags = new_flags & (~JVM_ACC_PROTECTED);
a61af66fc99e Initial load
duke
parents:
diff changeset
267 new_flags = new_flags | JVM_ACC_PUBLIC;
a61af66fc99e Initial load
duke
parents:
diff changeset
268 flags.set_flags(new_flags);
a61af66fc99e Initial load
duke
parents:
diff changeset
269 }
a61af66fc99e Initial load
duke
parents:
diff changeset
270
a61af66fc99e Initial load
duke
parents:
diff changeset
271 if (!Reflection::verify_field_access(ref_klass->as_klassOop(),
a61af66fc99e Initial load
duke
parents:
diff changeset
272 resolved_klass->as_klassOop(),
a61af66fc99e Initial load
duke
parents:
diff changeset
273 sel_klass->as_klassOop(),
a61af66fc99e Initial load
duke
parents:
diff changeset
274 flags,
a61af66fc99e Initial load
duke
parents:
diff changeset
275 true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
276 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
277 Exceptions::fthrow(
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
280 "tried to access method %s.%s%s from class %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
281 sel_klass->external_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
282 sel_method->name()->as_C_string(),
a61af66fc99e Initial load
duke
parents:
diff changeset
283 sel_method->signature()->as_C_string(),
a61af66fc99e Initial load
duke
parents:
diff changeset
284 ref_klass->external_name()
a61af66fc99e Initial load
duke
parents:
diff changeset
285 );
a61af66fc99e Initial load
duke
parents:
diff changeset
286 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
287 }
a61af66fc99e Initial load
duke
parents:
diff changeset
288 }
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 void LinkResolver::resolve_method(methodHandle& resolved_method, KlassHandle& resolved_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
291 constantPoolHandle pool, int index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
292
a61af66fc99e Initial load
duke
parents:
diff changeset
293 // resolve klass
a61af66fc99e Initial load
duke
parents:
diff changeset
294 resolve_klass(resolved_klass, pool, index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
298 KlassHandle current_klass(THREAD, pool->pool_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
310 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
311 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
325 void LinkResolver::resolve_interface_method(methodHandle& resolved_method, KlassHandle& resolved_klass, constantPoolHandle pool, int index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 // resolve klass
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
331 KlassHandle current_klass(THREAD, pool->pool_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
332
a61af66fc99e Initial load
duke
parents:
diff changeset
333 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
334 }
a61af66fc99e Initial load
duke
parents:
diff changeset
335
a61af66fc99e Initial load
duke
parents:
diff changeset
336
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
339 KlassHandle current_klass, bool check_access, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
340
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // 1. check if klass is not interface
a61af66fc99e Initial load
duke
parents:
diff changeset
342 if (resolved_klass->is_interface()) {
3324
acf5e660c71a 6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents: 2460
diff changeset
343 ResourceMark rm(THREAD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
344 char buf[200];
a61af66fc99e Initial load
duke
parents:
diff changeset
345 jio_snprintf(buf, sizeof(buf), "Found interface %s, but class was expected", Klass::cast(resolved_klass())->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
346 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
347 }
a61af66fc99e Initial load
duke
parents:
diff changeset
348
a61af66fc99e Initial load
duke
parents:
diff changeset
349 // 2. lookup method in resolved klass and its super klasses
a61af66fc99e Initial load
duke
parents:
diff changeset
350 lookup_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
351
a61af66fc99e Initial load
duke
parents:
diff changeset
352 if (resolved_method.is_null()) { // not found in the class hierarchy
a61af66fc99e Initial load
duke
parents:
diff changeset
353 // 3. lookup method in all the interfaces implemented by the resolved klass
a61af66fc99e Initial load
duke
parents:
diff changeset
354 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
355
a61af66fc99e Initial load
duke
parents:
diff changeset
356 if (resolved_method.is_null()) {
710
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
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
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
359 }
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
360
e5b0439ef4ae 6655638: dynamic languages need method handles
jrose
parents: 0
diff changeset
361 if (resolved_method.is_null()) {
0
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // 4. method lookup failed
a61af66fc99e Initial load
duke
parents:
diff changeset
363 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
364 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
368 }
a61af66fc99e Initial load
duke
parents:
diff changeset
369 }
a61af66fc99e Initial load
duke
parents:
diff changeset
370
a61af66fc99e Initial load
duke
parents:
diff changeset
371 // 5. check if method is concrete
a61af66fc99e Initial load
duke
parents:
diff changeset
372 if (resolved_method->is_abstract() && !resolved_klass->is_abstract()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
373 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
374 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
378 }
a61af66fc99e Initial load
duke
parents:
diff changeset
379
a61af66fc99e Initial load
duke
parents:
diff changeset
380 // 6. access checks, access checking may be turned off when calling from within the VM.
a61af66fc99e Initial load
duke
parents:
diff changeset
381 if (check_access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
382 assert(current_klass.not_null() , "current_klass should not be null");
a61af66fc99e Initial load
duke
parents:
diff changeset
383
a61af66fc99e Initial load
duke
parents:
diff changeset
384 // check if method can be accessed by the referring class
a61af66fc99e Initial load
duke
parents:
diff changeset
385 check_method_accessability(current_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
386 resolved_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
387 KlassHandle(THREAD, resolved_method->method_holder()),
a61af66fc99e Initial load
duke
parents:
diff changeset
388 resolved_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
389 CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
390
a61af66fc99e Initial load
duke
parents:
diff changeset
391 // check loader constraints
a61af66fc99e Initial load
duke
parents:
diff changeset
392 Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
393 Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
394 {
a61af66fc99e Initial load
duke
parents:
diff changeset
395 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
396 char* failed_type_name =
a61af66fc99e Initial load
duke
parents:
diff changeset
397 SystemDictionary::check_signature_loaders(method_signature, loader,
a61af66fc99e Initial load
duke
parents:
diff changeset
398 class_loader, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
399 if (failed_type_name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
400 const char* msg = "loader constraint violation: when resolving method"
a61af66fc99e Initial load
duke
parents:
diff changeset
401 " \"%s\" the class loader (instance of %s) of the current class, %s,"
a61af66fc99e Initial load
duke
parents:
diff changeset
402 " and the class loader (instance of %s) for resolved class, %s, have"
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
405 const char* loader1 = SystemDictionary::loader_name(loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
406 char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
407 const char* loader2 = SystemDictionary::loader_name(class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
408 char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
409 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
a61af66fc99e Initial load
duke
parents:
diff changeset
410 strlen(current) + strlen(loader2) + strlen(resolved) +
a61af66fc99e Initial load
duke
parents:
diff changeset
411 strlen(failed_type_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
412 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
413 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
a61af66fc99e Initial load
duke
parents:
diff changeset
414 resolved, failed_type_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
415 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
416 }
a61af66fc99e Initial load
duke
parents:
diff changeset
417 }
a61af66fc99e Initial load
duke
parents:
diff changeset
418 }
a61af66fc99e Initial load
duke
parents:
diff changeset
419 }
a61af66fc99e Initial load
duke
parents:
diff changeset
420
a61af66fc99e Initial load
duke
parents:
diff changeset
421 void LinkResolver::resolve_interface_method(methodHandle& resolved_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
425 KlassHandle current_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
426 bool check_access, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
427
a61af66fc99e Initial load
duke
parents:
diff changeset
428 // check if klass is interface
a61af66fc99e Initial load
duke
parents:
diff changeset
429 if (!resolved_klass->is_interface()) {
3324
acf5e660c71a 6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents: 2460
diff changeset
430 ResourceMark rm(THREAD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
431 char buf[200];
a61af66fc99e Initial load
duke
parents:
diff changeset
432 jio_snprintf(buf, sizeof(buf), "Found class %s, but interface was expected", Klass::cast(resolved_klass())->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
433 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
434 }
a61af66fc99e Initial load
duke
parents:
diff changeset
435
a61af66fc99e Initial load
duke
parents:
diff changeset
436 // lookup method in this interface or its super, java.lang.Object
a61af66fc99e Initial load
duke
parents:
diff changeset
437 lookup_instance_method_in_klasses(resolved_method, resolved_klass, method_name, method_signature, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
438
a61af66fc99e Initial load
duke
parents:
diff changeset
439 if (resolved_method.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // lookup method in all the super-interfaces
a61af66fc99e Initial load
duke
parents:
diff changeset
441 lookup_method_in_interfaces(resolved_method, resolved_klass, method_name, method_signature, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
442 if (resolved_method.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // no method found
a61af66fc99e Initial load
duke
parents:
diff changeset
444 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
445 THROW_MSG(vmSymbols::java_lang_NoSuchMethodError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
449 }
a61af66fc99e Initial load
duke
parents:
diff changeset
450 }
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 if (check_access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
453 HandleMark hm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
454 Handle loader (THREAD, instanceKlass::cast(current_klass())->class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
455 Handle class_loader (THREAD, instanceKlass::cast(resolved_method->method_holder())->class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
456 {
a61af66fc99e Initial load
duke
parents:
diff changeset
457 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
458 char* failed_type_name =
a61af66fc99e Initial load
duke
parents:
diff changeset
459 SystemDictionary::check_signature_loaders(method_signature, loader,
a61af66fc99e Initial load
duke
parents:
diff changeset
460 class_loader, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
461 if (failed_type_name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
462 const char* msg = "loader constraint violation: when resolving "
a61af66fc99e Initial load
duke
parents:
diff changeset
463 "interface method \"%s\" the class loader (instance of %s) of the "
a61af66fc99e Initial load
duke
parents:
diff changeset
464 "current class, %s, and the class loader (instance of %s) for "
a61af66fc99e Initial load
duke
parents:
diff changeset
465 "resolved class, %s, have different Class objects for the type %s "
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
468 const char* loader1 = SystemDictionary::loader_name(loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
469 char* current = instanceKlass::cast(current_klass())->name()->as_C_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
470 const char* loader2 = SystemDictionary::loader_name(class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
471 char* resolved = instanceKlass::cast(resolved_klass())->name()->as_C_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
472 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) +
a61af66fc99e Initial load
duke
parents:
diff changeset
473 strlen(current) + strlen(loader2) + strlen(resolved) +
a61af66fc99e Initial load
duke
parents:
diff changeset
474 strlen(failed_type_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
475 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
476 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2,
a61af66fc99e Initial load
duke
parents:
diff changeset
477 resolved, failed_type_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
478 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
479 }
a61af66fc99e Initial load
duke
parents:
diff changeset
480 }
a61af66fc99e Initial load
duke
parents:
diff changeset
481 }
a61af66fc99e Initial load
duke
parents:
diff changeset
482 }
a61af66fc99e Initial load
duke
parents:
diff changeset
483
a61af66fc99e Initial load
duke
parents:
diff changeset
484 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
485 // Field resolution
a61af66fc99e Initial load
duke
parents:
diff changeset
486
a61af66fc99e Initial load
duke
parents:
diff changeset
487 void LinkResolver::check_field_accessability(KlassHandle ref_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
488 KlassHandle resolved_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
489 KlassHandle sel_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
490 fieldDescriptor& fd,
a61af66fc99e Initial load
duke
parents:
diff changeset
491 TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
492 if (!Reflection::verify_field_access(ref_klass->as_klassOop(),
a61af66fc99e Initial load
duke
parents:
diff changeset
493 resolved_klass->as_klassOop(),
a61af66fc99e Initial load
duke
parents:
diff changeset
494 sel_klass->as_klassOop(),
a61af66fc99e Initial load
duke
parents:
diff changeset
495 fd.access_flags(),
a61af66fc99e Initial load
duke
parents:
diff changeset
496 true)) {
a61af66fc99e Initial load
duke
parents:
diff changeset
497 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
498 Exceptions::fthrow(
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
501 "tried to access field %s.%s from class %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
502 sel_klass->external_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
503 fd.name()->as_C_string(),
a61af66fc99e Initial load
duke
parents:
diff changeset
504 ref_klass->external_name()
a61af66fc99e Initial load
duke
parents:
diff changeset
505 );
a61af66fc99e Initial load
duke
parents:
diff changeset
506 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
507 }
a61af66fc99e Initial load
duke
parents:
diff changeset
508 }
a61af66fc99e Initial load
duke
parents:
diff changeset
509
a61af66fc99e Initial load
duke
parents:
diff changeset
510 void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
511 resolve_field(result, pool, index, byte, check_only, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
512 }
a61af66fc99e Initial load
duke
parents:
diff changeset
513
a61af66fc99e Initial load
duke
parents:
diff changeset
514 void LinkResolver::resolve_field(FieldAccessInfo& result, constantPoolHandle pool, int index, Bytecodes::Code byte, bool check_only, bool update_pool, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
515 assert(byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic ||
a61af66fc99e Initial load
duke
parents:
diff changeset
516 byte == Bytecodes::_getfield || byte == Bytecodes::_putfield, "bad bytecode");
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 bool is_static = (byte == Bytecodes::_getstatic || byte == Bytecodes::_putstatic);
a61af66fc99e Initial load
duke
parents:
diff changeset
519 bool is_put = (byte == Bytecodes::_putfield || byte == Bytecodes::_putstatic);
a61af66fc99e Initial load
duke
parents:
diff changeset
520
a61af66fc99e Initial load
duke
parents:
diff changeset
521 // resolve specified klass
a61af66fc99e Initial load
duke
parents:
diff changeset
522 KlassHandle resolved_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
523 if (update_pool) {
a61af66fc99e Initial load
duke
parents:
diff changeset
524 resolve_klass(resolved_klass, pool, index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
525 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
526 resolve_klass_no_update(resolved_klass, pool, index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
527 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
531 // Check if there's a resolved klass containing the field
a61af66fc99e Initial load
duke
parents:
diff changeset
532 if( resolved_klass.is_null() ) {
a61af66fc99e Initial load
duke
parents:
diff changeset
533 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
534 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
a61af66fc99e Initial load
duke
parents:
diff changeset
535 }
a61af66fc99e Initial load
duke
parents:
diff changeset
536
a61af66fc99e Initial load
duke
parents:
diff changeset
537 // Resolve instance field
a61af66fc99e Initial load
duke
parents:
diff changeset
538 fieldDescriptor fd; // find_field initializes fd if found
a61af66fc99e Initial load
duke
parents:
diff changeset
539 KlassHandle sel_klass(THREAD, instanceKlass::cast(resolved_klass())->find_field(field, sig, &fd));
a61af66fc99e Initial load
duke
parents:
diff changeset
540 // check if field exists; i.e., if a klass containing the field def has been selected
a61af66fc99e Initial load
duke
parents:
diff changeset
541 if (sel_klass.is_null()){
a61af66fc99e Initial load
duke
parents:
diff changeset
542 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
543 THROW_MSG(vmSymbols::java_lang_NoSuchFieldError(), field->as_C_string());
a61af66fc99e Initial load
duke
parents:
diff changeset
544 }
a61af66fc99e Initial load
duke
parents:
diff changeset
545
a61af66fc99e Initial load
duke
parents:
diff changeset
546 // check access
a61af66fc99e Initial load
duke
parents:
diff changeset
547 KlassHandle ref_klass(THREAD, pool->pool_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
548 check_field_accessability(ref_klass, resolved_klass, sel_klass, fd, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
549
a61af66fc99e Initial load
duke
parents:
diff changeset
550 // check for errors
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
553 char msg[200];
a61af66fc99e Initial load
duke
parents:
diff changeset
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());
a61af66fc99e Initial load
duke
parents:
diff changeset
555 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), msg);
a61af66fc99e Initial load
duke
parents:
diff changeset
556 }
a61af66fc99e Initial load
duke
parents:
diff changeset
557
a61af66fc99e Initial load
duke
parents:
diff changeset
558 // Final fields can only be accessed from its own class.
a61af66fc99e Initial load
duke
parents:
diff changeset
559 if (is_put && fd.access_flags().is_final() && sel_klass() != pool->pool_holder()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
560 THROW(vmSymbols::java_lang_IllegalAccessError());
a61af66fc99e Initial load
duke
parents:
diff changeset
561 }
a61af66fc99e Initial load
duke
parents:
diff changeset
562
a61af66fc99e Initial load
duke
parents:
diff changeset
563 // initialize resolved_klass if necessary
a61af66fc99e Initial load
duke
parents:
diff changeset
564 // note 1: the klass which declared the field must be initialized (i.e, sel_klass)
a61af66fc99e Initial load
duke
parents:
diff changeset
565 // according to the newest JVM spec (5.5, p.170) - was bug (gri 7/28/99)
a61af66fc99e Initial load
duke
parents:
diff changeset
566 //
a61af66fc99e Initial load
duke
parents:
diff changeset
567 // note 2: we don't want to force initialization if we are just checking
a61af66fc99e Initial load
duke
parents:
diff changeset
568 // if the field access is legal; e.g., during compilation
a61af66fc99e Initial load
duke
parents:
diff changeset
569 if (is_static && !check_only) {
a61af66fc99e Initial load
duke
parents:
diff changeset
570 sel_klass->initialize(CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
571 }
a61af66fc99e Initial load
duke
parents:
diff changeset
572
a61af66fc99e Initial load
duke
parents:
diff changeset
573 {
a61af66fc99e Initial load
duke
parents:
diff changeset
574 HandleMark hm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
575 Handle ref_loader (THREAD, instanceKlass::cast(ref_klass())->class_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
578 {
a61af66fc99e Initial load
duke
parents:
diff changeset
579 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
580 char* failed_type_name =
a61af66fc99e Initial load
duke
parents:
diff changeset
581 SystemDictionary::check_signature_loaders(signature_ref,
a61af66fc99e Initial load
duke
parents:
diff changeset
582 ref_loader, sel_loader,
a61af66fc99e Initial load
duke
parents:
diff changeset
583 false,
a61af66fc99e Initial load
duke
parents:
diff changeset
584 CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
585 if (failed_type_name != NULL) {
a61af66fc99e Initial load
duke
parents:
diff changeset
586 const char* msg = "loader constraint violation: when resolving field"
a61af66fc99e Initial load
duke
parents:
diff changeset
587 " \"%s\" the class loader (instance of %s) of the referring class, "
a61af66fc99e Initial load
duke
parents:
diff changeset
588 "%s, and the class loader (instance of %s) for the field's resolved "
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
591 const char* loader1 = SystemDictionary::loader_name(ref_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
592 char* sel = instanceKlass::cast(sel_klass())->name()->as_C_string();
a61af66fc99e Initial load
duke
parents:
diff changeset
593 const char* loader2 = SystemDictionary::loader_name(sel_loader());
a61af66fc99e Initial load
duke
parents:
diff changeset
594 size_t buflen = strlen(msg) + strlen(field_name) + strlen(loader1) +
a61af66fc99e Initial load
duke
parents:
diff changeset
595 strlen(sel) + strlen(loader2) + strlen(failed_type_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
596 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen);
a61af66fc99e Initial load
duke
parents:
diff changeset
597 jio_snprintf(buf, buflen, msg, field_name, loader1, sel, loader2,
a61af66fc99e Initial load
duke
parents:
diff changeset
598 failed_type_name);
a61af66fc99e Initial load
duke
parents:
diff changeset
599 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
600 }
a61af66fc99e Initial load
duke
parents:
diff changeset
601 }
a61af66fc99e Initial load
duke
parents:
diff changeset
602 }
a61af66fc99e Initial load
duke
parents:
diff changeset
603
a61af66fc99e Initial load
duke
parents:
diff changeset
604 // return information. note that the klass is set to the actual klass containing the
a61af66fc99e Initial load
duke
parents:
diff changeset
605 // field, otherwise access of static fields in superclasses will not work.
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
608 result.set(holder, name, fd.index(), fd.offset(), fd.field_type(), fd.access_flags());
a61af66fc99e Initial load
duke
parents:
diff changeset
609 }
a61af66fc99e Initial load
duke
parents:
diff changeset
610
a61af66fc99e Initial load
duke
parents:
diff changeset
611
a61af66fc99e Initial load
duke
parents:
diff changeset
612 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
613 // Invoke resolution
a61af66fc99e Initial load
duke
parents:
diff changeset
614 //
a61af66fc99e Initial load
duke
parents:
diff changeset
615 // Naming conventions:
a61af66fc99e Initial load
duke
parents:
diff changeset
616 //
a61af66fc99e Initial load
duke
parents:
diff changeset
617 // resolved_method the specified method (i.e., static receiver specified via constant pool index)
a61af66fc99e Initial load
duke
parents:
diff changeset
618 // sel_method the selected method (selected via run-time lookup; e.g., based on dynamic receiver class)
a61af66fc99e Initial load
duke
parents:
diff changeset
619 // resolved_klass the specified klass (i.e., specified via constant pool index)
a61af66fc99e Initial load
duke
parents:
diff changeset
620 // recv_klass the receiver klass
a61af66fc99e Initial load
duke
parents:
diff changeset
621
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
625 bool check_access, bool initialize_class, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
626 methodHandle resolved_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
627 linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
628 resolved_klass = KlassHandle(THREAD, Klass::cast(resolved_method->method_holder()));
a61af66fc99e Initial load
duke
parents:
diff changeset
629
a61af66fc99e Initial load
duke
parents:
diff changeset
630 // Initialize klass (this should only happen if everything is ok)
a61af66fc99e Initial load
duke
parents:
diff changeset
631 if (initialize_class && resolved_klass->should_be_initialized()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
632 resolved_klass->initialize(CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
633 linktime_resolve_static_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
634 }
a61af66fc99e Initial load
duke
parents:
diff changeset
635
a61af66fc99e Initial load
duke
parents:
diff changeset
636 // setup result
a61af66fc99e Initial load
duke
parents:
diff changeset
637 result.set_static(resolved_klass, resolved_method, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
638 }
a61af66fc99e Initial load
duke
parents:
diff changeset
639
a61af66fc99e Initial load
duke
parents:
diff changeset
640 // throws linktime exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
643 KlassHandle current_klass, bool check_access, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
644
a61af66fc99e Initial load
duke
parents:
diff changeset
645 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
646 assert(resolved_method->name() != vmSymbols::class_initializer_name(), "should have been checked in verifier");
a61af66fc99e Initial load
duke
parents:
diff changeset
647
a61af66fc99e Initial load
duke
parents:
diff changeset
648 // check if static
a61af66fc99e Initial load
duke
parents:
diff changeset
649 if (!resolved_method->is_static()) {
3324
acf5e660c71a 6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents: 2460
diff changeset
650 ResourceMark rm(THREAD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
651 char buf[200];
a61af66fc99e Initial load
duke
parents:
diff changeset
652 jio_snprintf(buf, sizeof(buf), "Expected static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
653 resolved_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
654 resolved_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
655 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
656 }
a61af66fc99e Initial load
duke
parents:
diff changeset
657 }
a61af66fc99e Initial load
duke
parents:
diff changeset
658
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
662 methodHandle resolved_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
663 linktime_resolve_special_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
664 runtime_resolve_special_method(result, resolved_method, resolved_klass, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
665 }
a61af66fc99e Initial load
duke
parents:
diff changeset
666
a61af66fc99e Initial load
duke
parents:
diff changeset
667 // throws linktime exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
670 KlassHandle current_klass, bool check_access, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
671
a61af66fc99e Initial load
duke
parents:
diff changeset
672 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
673
a61af66fc99e Initial load
duke
parents:
diff changeset
674 // check if method name is <init>, that it is found in same klass as static type
a61af66fc99e Initial load
duke
parents:
diff changeset
675 if (resolved_method->name() == vmSymbols::object_initializer_name() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
676 resolved_method->method_holder() != resolved_klass()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
677 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
678 Exceptions::fthrow(
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
681 "%s: method %s%s not found",
a61af66fc99e Initial load
duke
parents:
diff changeset
682 resolved_klass->external_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
683 resolved_method->name()->as_C_string(),
a61af66fc99e Initial load
duke
parents:
diff changeset
684 resolved_method->signature()->as_C_string()
a61af66fc99e Initial load
duke
parents:
diff changeset
685 );
a61af66fc99e Initial load
duke
parents:
diff changeset
686 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
687 }
a61af66fc99e Initial load
duke
parents:
diff changeset
688
a61af66fc99e Initial load
duke
parents:
diff changeset
689 // check if not static
a61af66fc99e Initial load
duke
parents:
diff changeset
690 if (resolved_method->is_static()) {
3324
acf5e660c71a 6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents: 2460
diff changeset
691 ResourceMark rm(THREAD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
692 char buf[200];
a61af66fc99e Initial load
duke
parents:
diff changeset
693 jio_snprintf(buf, sizeof(buf),
a61af66fc99e Initial load
duke
parents:
diff changeset
694 "Expecting non-static method %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
695 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
696 resolved_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
697 resolved_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
698 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
699 }
a61af66fc99e Initial load
duke
parents:
diff changeset
700 }
a61af66fc99e Initial load
duke
parents:
diff changeset
701
a61af66fc99e Initial load
duke
parents:
diff changeset
702 // throws runtime exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
703 void LinkResolver::runtime_resolve_special_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
704 KlassHandle current_klass, bool check_access, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
705
a61af66fc99e Initial load
duke
parents:
diff changeset
706 // resolved method is selected method unless we have an old-style lookup
a61af66fc99e Initial load
duke
parents:
diff changeset
707 methodHandle sel_method(THREAD, resolved_method());
a61af66fc99e Initial load
duke
parents:
diff changeset
708
a61af66fc99e Initial load
duke
parents:
diff changeset
709 // check if this is an old-style super call and do a new lookup if so
a61af66fc99e Initial load
duke
parents:
diff changeset
710 { KlassHandle method_klass = KlassHandle(THREAD,
a61af66fc99e Initial load
duke
parents:
diff changeset
711 resolved_method->method_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
712
a61af66fc99e Initial load
duke
parents:
diff changeset
713 if (check_access &&
a61af66fc99e Initial load
duke
parents:
diff changeset
714 // a) check if ACC_SUPER flag is set for the current class
a61af66fc99e Initial load
duke
parents:
diff changeset
715 current_klass->is_super() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
716 // b) check if the method class is a superclass of the current class (superclass relation is not reflexive!)
a61af66fc99e Initial load
duke
parents:
diff changeset
717 current_klass->is_subtype_of(method_klass()) && current_klass() != method_klass() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
718 // c) check if the method is not <init>
a61af66fc99e Initial load
duke
parents:
diff changeset
719 resolved_method->name() != vmSymbols::object_initializer_name()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
720 // Lookup super method
a61af66fc99e Initial load
duke
parents:
diff changeset
721 KlassHandle super_klass(THREAD, current_klass->super());
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
725 // check if found
a61af66fc99e Initial load
duke
parents:
diff changeset
726 if (sel_method.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
727 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
728 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
729 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
730 resolved_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
731 resolved_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
732 }
a61af66fc99e Initial load
duke
parents:
diff changeset
733 }
a61af66fc99e Initial load
duke
parents:
diff changeset
734 }
a61af66fc99e Initial load
duke
parents:
diff changeset
735
a61af66fc99e Initial load
duke
parents:
diff changeset
736 // check if not static
a61af66fc99e Initial load
duke
parents:
diff changeset
737 if (sel_method->is_static()) {
3324
acf5e660c71a 6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents: 2460
diff changeset
738 ResourceMark rm(THREAD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
739 char buf[200];
a61af66fc99e Initial load
duke
parents:
diff changeset
740 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
741 resolved_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
742 resolved_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
743 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
744 }
a61af66fc99e Initial load
duke
parents:
diff changeset
745
a61af66fc99e Initial load
duke
parents:
diff changeset
746 // check if abstract
a61af66fc99e Initial load
duke
parents:
diff changeset
747 if (sel_method->is_abstract()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
748 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
749 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
750 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
751 sel_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
752 sel_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
753 }
a61af66fc99e Initial load
duke
parents:
diff changeset
754
a61af66fc99e Initial load
duke
parents:
diff changeset
755 // setup result
a61af66fc99e Initial load
duke
parents:
diff changeset
756 result.set_static(resolved_klass, sel_method, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
757 }
a61af66fc99e Initial load
duke
parents:
diff changeset
758
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
761 bool check_access, bool check_null_and_abstract, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
762 methodHandle resolved_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
763 linktime_resolve_virtual_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
764 runtime_resolve_virtual_method(result, resolved_method, resolved_klass, recv, receiver_klass, check_null_and_abstract, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
765 }
a61af66fc99e Initial load
duke
parents:
diff changeset
766
a61af66fc99e Initial load
duke
parents:
diff changeset
767 // throws linktime exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
770 KlassHandle current_klass, bool check_access, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
771 // normal method resolution
a61af66fc99e Initial load
duke
parents:
diff changeset
772 resolve_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
773
a61af66fc99e Initial load
duke
parents:
diff changeset
774 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
a61af66fc99e Initial load
duke
parents:
diff changeset
775 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
a61af66fc99e Initial load
duke
parents:
diff changeset
776
a61af66fc99e Initial load
duke
parents:
diff changeset
777 // check if not static
a61af66fc99e Initial load
duke
parents:
diff changeset
778 if (resolved_method->is_static()) {
3324
acf5e660c71a 6728025: LinkResolver is missing some ResourceMarks
jcoomes
parents: 2460
diff changeset
779 ResourceMark rm(THREAD);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
780 char buf[200];
a61af66fc99e Initial load
duke
parents:
diff changeset
781 jio_snprintf(buf, sizeof(buf), "Expecting non-static method %s", methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
782 resolved_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
783 resolved_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
784 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
785 }
a61af66fc99e Initial load
duke
parents:
diff changeset
786 }
a61af66fc99e Initial load
duke
parents:
diff changeset
787
a61af66fc99e Initial load
duke
parents:
diff changeset
788 // throws runtime exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
789 void LinkResolver::runtime_resolve_virtual_method(CallInfo& result,
a61af66fc99e Initial load
duke
parents:
diff changeset
790 methodHandle resolved_method,
a61af66fc99e Initial load
duke
parents:
diff changeset
791 KlassHandle resolved_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
792 Handle recv,
a61af66fc99e Initial load
duke
parents:
diff changeset
793 KlassHandle recv_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
794 bool check_null_and_abstract,
a61af66fc99e Initial load
duke
parents:
diff changeset
795 TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
796
a61af66fc99e Initial load
duke
parents:
diff changeset
797 // setup default return values
a61af66fc99e Initial load
duke
parents:
diff changeset
798 int vtable_index = methodOopDesc::invalid_vtable_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
799 methodHandle selected_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
800
a61af66fc99e Initial load
duke
parents:
diff changeset
801 assert(recv.is_null() || recv->is_oop(), "receiver is not an oop");
a61af66fc99e Initial load
duke
parents:
diff changeset
802
a61af66fc99e Initial load
duke
parents:
diff changeset
803 // runtime method resolution
a61af66fc99e Initial load
duke
parents:
diff changeset
804 if (check_null_and_abstract && recv.is_null()) { // check if receiver exists
a61af66fc99e Initial load
duke
parents:
diff changeset
805 THROW(vmSymbols::java_lang_NullPointerException());
a61af66fc99e Initial load
duke
parents:
diff changeset
806 }
a61af66fc99e Initial load
duke
parents:
diff changeset
807
a61af66fc99e Initial load
duke
parents:
diff changeset
808 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's
a61af66fc99e Initial load
duke
parents:
diff changeset
809 // has not been rewritten, and the vtable initialized.
a61af66fc99e Initial load
duke
parents:
diff changeset
810 assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
a61af66fc99e Initial load
duke
parents:
diff changeset
811
a61af66fc99e Initial load
duke
parents:
diff changeset
812 // Virtual methods cannot be resolved before its klass has been linked, for otherwise the methodOop's
a61af66fc99e Initial load
duke
parents:
diff changeset
813 // has not been rewritten, and the vtable initialized. Make sure to do this after the nullcheck, since
a61af66fc99e Initial load
duke
parents:
diff changeset
814 // a missing receiver might result in a bogus lookup.
a61af66fc99e Initial load
duke
parents:
diff changeset
815 assert(instanceKlass::cast(resolved_method->method_holder())->is_linked(), "must be linked");
a61af66fc99e Initial load
duke
parents:
diff changeset
816
a61af66fc99e Initial load
duke
parents:
diff changeset
817 // do lookup based on receiver klass using the vtable index
a61af66fc99e Initial load
duke
parents:
diff changeset
818 if (resolved_method->method_holder()->klass_part()->is_interface()) { // miranda method
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
822 assert(vtable_index >= 0 , "we should have valid vtable index at this point");
a61af66fc99e Initial load
duke
parents:
diff changeset
823
a61af66fc99e Initial load
duke
parents:
diff changeset
824 instanceKlass* inst = instanceKlass::cast(recv_klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
825 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
a61af66fc99e Initial load
duke
parents:
diff changeset
826 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
827 // at this point we are sure that resolved_method is virtual and not
a61af66fc99e Initial load
duke
parents:
diff changeset
828 // a miranda method; therefore, it must have a valid vtable index.
a61af66fc99e Initial load
duke
parents:
diff changeset
829 vtable_index = resolved_method->vtable_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
830 // We could get a negative vtable_index for final methods,
a61af66fc99e Initial load
duke
parents:
diff changeset
831 // because as an optimization they are they are never put in the vtable,
a61af66fc99e Initial load
duke
parents:
diff changeset
832 // unless they override an existing method.
a61af66fc99e Initial load
duke
parents:
diff changeset
833 // If we do get a negative, it means the resolved method is the the selected
a61af66fc99e Initial load
duke
parents:
diff changeset
834 // method, and it can never be changed by an override.
a61af66fc99e Initial load
duke
parents:
diff changeset
835 if (vtable_index == methodOopDesc::nonvirtual_vtable_index) {
a61af66fc99e Initial load
duke
parents:
diff changeset
836 assert(resolved_method->can_be_statically_bound(), "cannot override this method");
a61af66fc99e Initial load
duke
parents:
diff changeset
837 selected_method = resolved_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
838 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
839 // recv_klass might be an arrayKlassOop but all vtables start at
a61af66fc99e Initial load
duke
parents:
diff changeset
840 // the same place. The cast is to avoid virtual call and assertion.
a61af66fc99e Initial load
duke
parents:
diff changeset
841 instanceKlass* inst = (instanceKlass*)recv_klass()->klass_part();
a61af66fc99e Initial load
duke
parents:
diff changeset
842 selected_method = methodHandle(THREAD, inst->method_at_vtable(vtable_index));
a61af66fc99e Initial load
duke
parents:
diff changeset
843 }
a61af66fc99e Initial load
duke
parents:
diff changeset
844 }
a61af66fc99e Initial load
duke
parents:
diff changeset
845
a61af66fc99e Initial load
duke
parents:
diff changeset
846 // check if method exists
a61af66fc99e Initial load
duke
parents:
diff changeset
847 if (selected_method.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
848 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
849 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
850 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
851 resolved_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
852 resolved_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
853 }
a61af66fc99e Initial load
duke
parents:
diff changeset
854
a61af66fc99e Initial load
duke
parents:
diff changeset
855 // check if abstract
a61af66fc99e Initial load
duke
parents:
diff changeset
856 if (check_null_and_abstract && selected_method->is_abstract()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
857 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
858 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
859 methodOopDesc::name_and_sig_as_C_string(Klass::cast(resolved_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
860 selected_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
861 selected_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
862 }
a61af66fc99e Initial load
duke
parents:
diff changeset
863
a61af66fc99e Initial load
duke
parents:
diff changeset
864 // setup result
a61af66fc99e Initial load
duke
parents:
diff changeset
865 result.set_virtual(resolved_klass, recv_klass, resolved_method, selected_method, vtable_index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
866 }
a61af66fc99e Initial load
duke
parents:
diff changeset
867
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
870 bool check_access, bool check_null_and_abstract, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
871 methodHandle resolved_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
872 linktime_resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
873 runtime_resolve_interface_method(result, resolved_method, resolved_klass, recv, recv_klass, check_null_and_abstract, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
874 }
a61af66fc99e Initial load
duke
parents:
diff changeset
875
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
879 // normal interface method resolution
a61af66fc99e Initial load
duke
parents:
diff changeset
880 resolve_interface_method(resolved_method, resolved_klass, method_name, method_signature, current_klass, check_access, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
881
a61af66fc99e Initial load
duke
parents:
diff changeset
882 assert(resolved_method->name() != vmSymbols::object_initializer_name(), "should have been checked in verifier");
a61af66fc99e Initial load
duke
parents:
diff changeset
883 assert(resolved_method->name() != vmSymbols::class_initializer_name (), "should have been checked in verifier");
a61af66fc99e Initial load
duke
parents:
diff changeset
884 }
a61af66fc99e Initial load
duke
parents:
diff changeset
885
a61af66fc99e Initial load
duke
parents:
diff changeset
886 // throws runtime exceptions
a61af66fc99e Initial load
duke
parents:
diff changeset
887 void LinkResolver::runtime_resolve_interface_method(CallInfo& result, methodHandle resolved_method, KlassHandle resolved_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
888 Handle recv, KlassHandle recv_klass, bool check_null_and_abstract, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
889 // check if receiver exists
a61af66fc99e Initial load
duke
parents:
diff changeset
890 if (check_null_and_abstract && recv.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
891 THROW(vmSymbols::java_lang_NullPointerException());
a61af66fc99e Initial load
duke
parents:
diff changeset
892 }
a61af66fc99e Initial load
duke
parents:
diff changeset
893
a61af66fc99e Initial load
duke
parents:
diff changeset
894 // check if receiver klass implements the resolved interface
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
897 char buf[200];
a61af66fc99e Initial load
duke
parents:
diff changeset
898 jio_snprintf(buf, sizeof(buf), "Class %s does not implement the requested interface %s",
a61af66fc99e Initial load
duke
parents:
diff changeset
899 (Klass::cast(recv_klass()))->external_name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
900 (Klass::cast(resolved_klass()))->external_name());
a61af66fc99e Initial load
duke
parents:
diff changeset
901 THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(), buf);
a61af66fc99e Initial load
duke
parents:
diff changeset
902 }
a61af66fc99e Initial load
duke
parents:
diff changeset
903 // do lookup based on receiver klass
a61af66fc99e Initial load
duke
parents:
diff changeset
904 methodHandle sel_method;
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
908 // check if method exists
a61af66fc99e Initial load
duke
parents:
diff changeset
909 if (sel_method.is_null()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
910 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
911 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
912 methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
913 resolved_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
914 resolved_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
915 }
a61af66fc99e Initial load
duke
parents:
diff changeset
916 // check if public
a61af66fc99e Initial load
duke
parents:
diff changeset
917 if (!sel_method->is_public()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
918 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
919 THROW_MSG(vmSymbols::java_lang_IllegalAccessError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
920 methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
921 sel_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
922 sel_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
923 }
a61af66fc99e Initial load
duke
parents:
diff changeset
924 // check if abstract
a61af66fc99e Initial load
duke
parents:
diff changeset
925 if (check_null_and_abstract && sel_method->is_abstract()) {
a61af66fc99e Initial load
duke
parents:
diff changeset
926 ResourceMark rm(THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
927 THROW_MSG(vmSymbols::java_lang_AbstractMethodError(),
a61af66fc99e Initial load
duke
parents:
diff changeset
928 methodOopDesc::name_and_sig_as_C_string(Klass::cast(recv_klass()),
a61af66fc99e Initial load
duke
parents:
diff changeset
929 sel_method->name(),
a61af66fc99e Initial load
duke
parents:
diff changeset
930 sel_method->signature()));
a61af66fc99e Initial load
duke
parents:
diff changeset
931 }
a61af66fc99e Initial load
duke
parents:
diff changeset
932 // setup result
a61af66fc99e Initial load
duke
parents:
diff changeset
933 result.set_interface(resolved_klass, recv_klass, resolved_method, sel_method, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
934 }
a61af66fc99e Initial load
duke
parents:
diff changeset
935
a61af66fc99e Initial load
duke
parents:
diff changeset
936
a61af66fc99e Initial load
duke
parents:
diff changeset
937 methodHandle LinkResolver::linktime_resolve_interface_method_or_null(
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
941 KlassHandle current_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
942 bool check_access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
943 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
944 methodHandle method_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
945 linktime_resolve_interface_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
946 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
947 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
948 return methodHandle();
a61af66fc99e Initial load
duke
parents:
diff changeset
949 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
950 return method_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
951 }
a61af66fc99e Initial load
duke
parents:
diff changeset
952 }
a61af66fc99e Initial load
duke
parents:
diff changeset
953
a61af66fc99e Initial load
duke
parents:
diff changeset
954 methodHandle LinkResolver::linktime_resolve_virtual_method_or_null(
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
958 KlassHandle current_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
959 bool check_access) {
a61af66fc99e Initial load
duke
parents:
diff changeset
960 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
961 methodHandle method_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
962 linktime_resolve_virtual_method(method_result, resolved_klass, method_name, method_signature, current_klass, check_access, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
963 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
964 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
965 return methodHandle();
a61af66fc99e Initial load
duke
parents:
diff changeset
966 } else {
a61af66fc99e Initial load
duke
parents:
diff changeset
967 return method_result;
a61af66fc99e Initial load
duke
parents:
diff changeset
968 }
a61af66fc99e Initial load
duke
parents:
diff changeset
969 }
a61af66fc99e Initial load
duke
parents:
diff changeset
970
a61af66fc99e Initial load
duke
parents:
diff changeset
971 methodHandle LinkResolver::resolve_virtual_call_or_null(
a61af66fc99e Initial load
duke
parents:
diff changeset
972 KlassHandle receiver_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
976 KlassHandle current_klass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
977 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
978 CallInfo info;
a61af66fc99e Initial load
duke
parents:
diff changeset
979 resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
980 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
981 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
982 return methodHandle();
a61af66fc99e Initial load
duke
parents:
diff changeset
983 }
a61af66fc99e Initial load
duke
parents:
diff changeset
984 return info.selected_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
985 }
a61af66fc99e Initial load
duke
parents:
diff changeset
986
a61af66fc99e Initial load
duke
parents:
diff changeset
987 methodHandle LinkResolver::resolve_interface_call_or_null(
a61af66fc99e Initial load
duke
parents:
diff changeset
988 KlassHandle receiver_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
992 KlassHandle current_klass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
993 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
994 CallInfo info;
a61af66fc99e Initial load
duke
parents:
diff changeset
995 resolve_interface_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
996 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
997 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
998 return methodHandle();
a61af66fc99e Initial load
duke
parents:
diff changeset
999 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1000 return info.selected_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1001 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1002
a61af66fc99e Initial load
duke
parents:
diff changeset
1003 int LinkResolver::resolve_virtual_vtable_index(
a61af66fc99e Initial load
duke
parents:
diff changeset
1004 KlassHandle receiver_klass,
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1008 KlassHandle current_klass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1009 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
1010 CallInfo info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1011 resolve_virtual_call(info, Handle(), receiver_klass, resolved_klass, name, signature, current_klass, true, false, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1012 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1013 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
1014 return methodOopDesc::invalid_vtable_index;
a61af66fc99e Initial load
duke
parents:
diff changeset
1015 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1016 return info.vtable_index();
a61af66fc99e Initial load
duke
parents:
diff changeset
1017 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1018
a61af66fc99e Initial load
duke
parents:
diff changeset
1019 methodHandle LinkResolver::resolve_static_call_or_null(
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1023 KlassHandle current_klass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1024 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
1025 CallInfo info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1026 resolve_static_call(info, resolved_klass, name, signature, current_klass, true, false, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1027 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1028 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
1029 return methodHandle();
a61af66fc99e Initial load
duke
parents:
diff changeset
1030 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1031 return info.selected_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1032 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1035 KlassHandle current_klass) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1036 EXCEPTION_MARK;
a61af66fc99e Initial load
duke
parents:
diff changeset
1037 CallInfo info;
a61af66fc99e Initial load
duke
parents:
diff changeset
1038 resolve_special_call(info, resolved_klass, name, signature, current_klass, true, THREAD);
a61af66fc99e Initial load
duke
parents:
diff changeset
1039 if (HAS_PENDING_EXCEPTION) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1040 CLEAR_PENDING_EXCEPTION;
a61af66fc99e Initial load
duke
parents:
diff changeset
1041 return methodHandle();
a61af66fc99e Initial load
duke
parents:
diff changeset
1042 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1043 return info.selected_method();
a61af66fc99e Initial load
duke
parents:
diff changeset
1044 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1045
a61af66fc99e Initial load
duke
parents:
diff changeset
1046
a61af66fc99e Initial load
duke
parents:
diff changeset
1047
a61af66fc99e Initial load
duke
parents:
diff changeset
1048 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1049 // ConstantPool entries
a61af66fc99e Initial load
duke
parents:
diff changeset
1050
a61af66fc99e Initial load
duke
parents:
diff changeset
1051 void LinkResolver::resolve_invoke(CallInfo& result, Handle recv, constantPoolHandle pool, int index, Bytecodes::Code byte, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1052 switch (byte) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1053 case Bytecodes::_invokestatic : resolve_invokestatic (result, pool, index, CHECK); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1054 case Bytecodes::_invokespecial : resolve_invokespecial (result, pool, index, CHECK); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1057 case Bytecodes::_invokeinterface: resolve_invokeinterface(result, recv, pool, index, CHECK); break;
a61af66fc99e Initial load
duke
parents:
diff changeset
1058 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1059 return;
a61af66fc99e Initial load
duke
parents:
diff changeset
1060 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1063 KlassHandle& current_klass, constantPoolHandle pool, int index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1064 // resolve klass
a61af66fc99e Initial load
duke
parents:
diff changeset
1065 resolve_klass(resolved_klass, pool, index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1066
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1070 current_klass = KlassHandle(THREAD, pool->pool_holder());
a61af66fc99e Initial load
duke
parents:
diff changeset
1071 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1072
a61af66fc99e Initial load
duke
parents:
diff changeset
1073
a61af66fc99e Initial load
duke
parents:
diff changeset
1074 void LinkResolver::resolve_invokestatic(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1078 KlassHandle current_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1079 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1080 resolve_static_call(result, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1081 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1082
a61af66fc99e Initial load
duke
parents:
diff changeset
1083
a61af66fc99e Initial load
duke
parents:
diff changeset
1084 void LinkResolver::resolve_invokespecial(CallInfo& result, constantPoolHandle pool, int index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1088 KlassHandle current_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1089 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1090 resolve_special_call(result, resolved_klass, method_name, method_signature, current_klass, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1091 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1092
a61af66fc99e Initial load
duke
parents:
diff changeset
1093
a61af66fc99e Initial load
duke
parents:
diff changeset
1094 void LinkResolver::resolve_invokevirtual(CallInfo& result, Handle recv,
a61af66fc99e Initial load
duke
parents:
diff changeset
1095 constantPoolHandle pool, int index,
a61af66fc99e Initial load
duke
parents:
diff changeset
1096 TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
1097
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1101 KlassHandle current_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1102 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1103 KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
1104 resolve_virtual_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1105 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1106
a61af66fc99e Initial load
duke
parents:
diff changeset
1107
a61af66fc99e Initial load
duke
parents:
diff changeset
1108 void LinkResolver::resolve_invokeinterface(CallInfo& result, Handle recv, constantPoolHandle pool, int index, TRAPS) {
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1112 KlassHandle current_klass;
a61af66fc99e Initial load
duke
parents:
diff changeset
1113 resolve_pool(resolved_klass, method_name, method_signature, current_klass, pool, index, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1114 KlassHandle recvrKlass (THREAD, recv.is_null() ? (klassOop)NULL : recv->klass());
a61af66fc99e Initial load
duke
parents:
diff changeset
1115 resolve_interface_call(result, recv, recvrKlass, resolved_klass, method_name, method_signature, current_klass, true, true, CHECK);
a61af66fc99e Initial load
duke
parents:
diff changeset
1116 }
a61af66fc99e Initial load
duke
parents:
diff changeset
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
a61af66fc99e Initial load
duke
parents:
diff changeset
1157 //------------------------------------------------------------------------------------------------------------------------
a61af66fc99e Initial load
duke
parents:
diff changeset
1158 #ifndef PRODUCT
a61af66fc99e Initial load
duke
parents:
diff changeset
1159
a61af66fc99e Initial load
duke
parents:
diff changeset
1160 void FieldAccessInfo::print() {
a61af66fc99e Initial load
duke
parents:
diff changeset
1161 ResourceMark rm;
a61af66fc99e Initial load
duke
parents:
diff changeset
1162 tty->print_cr("Field %s@%d", name()->as_C_string(), field_offset());
a61af66fc99e Initial load
duke
parents:
diff changeset
1163 }
a61af66fc99e Initial load
duke
parents:
diff changeset
1164
a61af66fc99e Initial load
duke
parents:
diff changeset
1165 #endif