Mercurial > hg > truffle
annotate src/share/vm/oops/klassVtable.cpp @ 9126:bc26f978b0ce
HotSpotResolvedObjectType: implement hasFinalizeSubclass() correctly
don't use the (wrong) cached value, but ask the runtime on each request.
Fixes regression on xml.* benchmarks @ specjvm2008. The problem was:
After the constructor of Object was deoptimized due to an assumption violation,
it was recompiled again after some time. However, on recompilation, the value
of hasFinalizeSubclass for the class was not updated and it was compiled again
with a, now wrong, assumption, which then triggers deoptimization again.
This was repeated until it hit the recompilation limit (defined by
PerMethodRecompilationCutoff), and therefore only executed by the interpreter
from now on, causing the performance regression.
author | Bernhard Urban <bernhard.urban@jku.at> |
---|---|
date | Mon, 15 Apr 2013 19:54:58 +0200 |
parents | cd3089a56438 |
children | 08236d966eea |
rev | line source |
---|---|
0 | 1 /* |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
1490
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:
1490
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #include "precompiled.hpp" |
26 #include "classfile/systemDictionary.hpp" | |
27 #include "classfile/vmSymbols.hpp" | |
28 #include "gc_implementation/shared/markSweep.inline.hpp" | |
29 #include "memory/gcLocker.hpp" | |
30 #include "memory/resourceArea.hpp" | |
31 #include "memory/universe.inline.hpp" | |
32 #include "oops/instanceKlass.hpp" | |
33 #include "oops/klassVtable.hpp" | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
34 #include "oops/method.hpp" |
1972 | 35 #include "oops/objArrayOop.hpp" |
36 #include "oops/oop.inline.hpp" | |
37 #include "prims/jvmtiRedefineClassesTrace.hpp" | |
38 #include "runtime/arguments.hpp" | |
39 #include "runtime/handles.inline.hpp" | |
40 #include "utilities/copy.hpp" | |
0 | 41 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
42 inline InstanceKlass* klassVtable::ik() const { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
43 Klass* k = _klass(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
44 assert(k->oop_is_instance(), "not an InstanceKlass"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
45 return (InstanceKlass*)k; |
0 | 46 } |
47 | |
48 | |
49 // this function computes the vtable size (including the size needed for miranda | |
50 // methods) and the number of miranda methods in this class | |
51 // Note on Miranda methods: Let's say there is a class C that implements | |
52 // interface I. Let's say there is a method m in I that neither C nor any | |
53 // of its super classes implement (i.e there is no method of any access, with | |
54 // the same name and signature as m), then m is a Miranda method which is | |
55 // entered as a public abstract method in C's vtable. From then on it should | |
56 // treated as any other public method in C for method over-ride purposes. | |
6934 | 57 void klassVtable::compute_vtable_size_and_num_mirandas( |
58 int* vtable_length_ret, int* num_new_mirandas, | |
59 GrowableArray<Method*>* all_mirandas, Klass* super, | |
60 Array<Method*>* methods, AccessFlags class_flags, | |
61 Handle classloader, Symbol* classname, Array<Klass*>* local_interfaces, | |
62 TRAPS) { | |
0 | 63 No_Safepoint_Verifier nsv; |
64 | |
65 // set up default result values | |
6934 | 66 int vtable_length = 0; |
0 | 67 |
68 // start off with super's vtable length | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
69 InstanceKlass* sk = (InstanceKlass*)super; |
0 | 70 vtable_length = super == NULL ? 0 : sk->vtable_length(); |
71 | |
72 // go thru each method in the methods table to see if it needs a new entry | |
73 int len = methods->length(); | |
74 for (int i = 0; i < len; i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
75 assert(methods->at(i)->is_method(), "must be a Method*"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
76 methodHandle mh(THREAD, methods->at(i)); |
0 | 77 |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
78 if (needs_new_vtable_entry(mh, super, classloader, classname, class_flags, THREAD)) { |
0 | 79 vtable_length += vtableEntry::size(); // we need a new entry |
80 } | |
81 } | |
82 | |
6934 | 83 GrowableArray<Method*> new_mirandas(20); |
0 | 84 // compute the number of mirandas methods that must be added to the end |
6934 | 85 get_mirandas(&new_mirandas, all_mirandas, super, methods, local_interfaces); |
86 *num_new_mirandas = new_mirandas.length(); | |
87 | |
88 vtable_length += *num_new_mirandas * vtableEntry::size(); | |
0 | 89 |
90 if (Universe::is_bootstrapping() && vtable_length == 0) { | |
91 // array classes don't have their superclass set correctly during | |
92 // bootstrapping | |
93 vtable_length = Universe::base_vtable_size(); | |
94 } | |
95 | |
96 if (super == NULL && !Universe::is_bootstrapping() && | |
97 vtable_length != Universe::base_vtable_size()) { | |
98 // Someone is attempting to redefine java.lang.Object incorrectly. The | |
99 // only way this should happen is from | |
100 // SystemDictionary::resolve_from_stream(), which will detect this later | |
101 // and throw a security exception. So don't assert here to let | |
102 // the exception occur. | |
103 vtable_length = Universe::base_vtable_size(); | |
104 } | |
105 assert(super != NULL || vtable_length == Universe::base_vtable_size(), | |
106 "bad vtable size for class Object"); | |
107 assert(vtable_length % vtableEntry::size() == 0, "bad vtable length"); | |
108 assert(vtable_length >= Universe::base_vtable_size(), "vtable too small"); | |
6934 | 109 |
110 *vtable_length_ret = vtable_length; | |
0 | 111 } |
112 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
113 int klassVtable::index_of(Method* m, int len) const { |
0 | 114 assert(m->vtable_index() >= 0, "do not ask this of non-vtable methods"); |
115 return m->vtable_index(); | |
116 } | |
117 | |
118 int klassVtable::initialize_from_super(KlassHandle super) { | |
119 if (super.is_null()) { | |
120 return 0; | |
121 } else { | |
122 // copy methods from superKlass | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
123 // can't inherit from array class, so must be InstanceKlass |
0 | 124 assert(super->oop_is_instance(), "must be instance klass"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
125 InstanceKlass* sk = (InstanceKlass*)super(); |
0 | 126 klassVtable* superVtable = sk->vtable(); |
127 assert(superVtable->length() <= _length, "vtable too short"); | |
128 #ifdef ASSERT | |
129 superVtable->verify(tty, true); | |
130 #endif | |
131 superVtable->copy_vtable_to(table()); | |
132 #ifndef PRODUCT | |
133 if (PrintVtables && Verbose) { | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
134 ResourceMark rm; |
0 | 135 tty->print_cr("copy vtable from %s to %s size %d", sk->internal_name(), klass()->internal_name(), _length); |
136 } | |
137 #endif | |
138 return superVtable->length(); | |
139 } | |
140 } | |
141 | |
142 // Revised lookup semantics introduced 1.3 (Kestral beta) | |
143 void klassVtable::initialize_vtable(bool checkconstraints, TRAPS) { | |
144 | |
145 // Note: Arrays can have intermediate array supers. Use java_super to skip them. | |
146 KlassHandle super (THREAD, klass()->java_super()); | |
147 int nofNewEntries = 0; | |
148 | |
149 | |
150 if (PrintVtables && !klass()->oop_is_array()) { | |
151 ResourceMark rm(THREAD); | |
152 tty->print_cr("Initializing: %s", _klass->name()->as_C_string()); | |
153 } | |
154 | |
155 #ifdef ASSERT | |
156 oop* end_of_obj = (oop*)_klass() + _klass()->size(); | |
157 oop* end_of_vtable = (oop*)&table()[_length]; | |
158 assert(end_of_vtable <= end_of_obj, "vtable extends beyond end"); | |
159 #endif | |
160 | |
161 if (Universe::is_bootstrapping()) { | |
162 // just clear everything | |
163 for (int i = 0; i < _length; i++) table()[i].clear(); | |
164 return; | |
165 } | |
166 | |
167 int super_vtable_len = initialize_from_super(super); | |
168 if (klass()->oop_is_array()) { | |
169 assert(super_vtable_len == _length, "arrays shouldn't introduce new methods"); | |
170 } else { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
171 assert(_klass->oop_is_instance(), "must be InstanceKlass"); |
0 | 172 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
173 Array<Method*>* methods = ik()->methods(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
174 int len = methods->length(); |
0 | 175 int initialized = super_vtable_len; |
176 | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
177 // update_inherited_vtable can stop for gc - ensure using handles |
0 | 178 for (int i = 0; i < len; i++) { |
179 HandleMark hm(THREAD); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
180 assert(methods->at(i)->is_method(), "must be a Method*"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
181 methodHandle mh(THREAD, methods->at(i)); |
0 | 182 |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
183 bool needs_new_entry = update_inherited_vtable(ik(), mh, super_vtable_len, checkconstraints, CHECK); |
0 | 184 |
185 if (needs_new_entry) { | |
186 put_method_at(mh(), initialized); | |
187 mh()->set_vtable_index(initialized); // set primary vtable index | |
188 initialized++; | |
189 } | |
190 } | |
191 | |
192 // add miranda methods; it will also update the value of initialized | |
6934 | 193 fill_in_mirandas(&initialized); |
0 | 194 |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
195 // In class hierarchies where the accessibility is not increasing (i.e., going from private -> |
0 | 196 // package_private -> publicprotected), the vtable might actually be smaller than our initial |
197 // calculation. | |
198 assert(initialized <= _length, "vtable initialization failed"); | |
199 for(;initialized < _length; initialized++) { | |
200 put_method_at(NULL, initialized); | |
201 } | |
202 NOT_PRODUCT(verify(tty, true)); | |
203 } | |
204 } | |
205 | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
206 // Called for cases where a method does not override its superclass' vtable entry |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
207 // For bytecodes not produced by javac together it is possible that a method does not override |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
208 // the superclass's method, but might indirectly override a super-super class's vtable entry |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
209 // If none found, return a null superk, else return the superk of the method this does override |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
210 InstanceKlass* klassVtable::find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
211 int vtable_index, Handle target_loader, Symbol* target_classname, Thread * THREAD) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
212 InstanceKlass* superk = initialsuper; |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
213 while (superk != NULL && superk->super() != NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
214 InstanceKlass* supersuperklass = InstanceKlass::cast(superk->super()); |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
215 klassVtable* ssVtable = supersuperklass->vtable(); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
216 if (vtable_index < ssVtable->length()) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
217 Method* super_method = ssVtable->method_at(vtable_index); |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
218 #ifndef PRODUCT |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
219 Symbol* name= target_method()->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
220 Symbol* signature = target_method()->signature(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
221 assert(super_method->name() == name && super_method->signature() == signature, "vtable entry name/sig mismatch"); |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
222 #endif |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
223 if (supersuperklass->is_override(super_method, target_loader, target_classname, THREAD)) { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
224 #ifndef PRODUCT |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
225 if (PrintVtables && Verbose) { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
226 ResourceMark rm(THREAD); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
227 tty->print("transitive overriding superclass %s with %s::%s index %d, original flags: ", |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
228 supersuperklass->internal_name(), |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
229 _klass->internal_name(), (target_method() != NULL) ? |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
230 target_method()->name()->as_C_string() : "<NULL>", vtable_index); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
231 super_method->access_flags().print_on(tty); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
232 tty->print("overriders flags: "); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
233 target_method->access_flags().print_on(tty); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
234 tty->cr(); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
235 } |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
236 #endif /*PRODUCT*/ |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
237 break; // return found superk |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
238 } |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
239 } else { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
240 // super class has no vtable entry here, stop transitive search |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
241 superk = (InstanceKlass*)NULL; |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
242 break; |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
243 } |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
244 // if no override found yet, continue to search up |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
245 superk = InstanceKlass::cast(superk->super()); |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
246 } |
0 | 247 |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
248 return superk; |
0 | 249 } |
250 | |
6934 | 251 // Methods that are "effectively" final don't need vtable entries. |
252 bool method_is_effectively_final( | |
253 AccessFlags klass_flags, methodHandle target) { | |
254 return target->is_final() || klass_flags.is_final() && !target->is_overpass(); | |
255 } | |
0 | 256 |
257 // Update child's copy of super vtable for overrides | |
258 // OR return true if a new vtable entry is required | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
259 // Only called for InstanceKlass's, i.e. not for arrays |
0 | 260 // If that changed, could not use _klass as handle for klass |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
261 bool klassVtable::update_inherited_vtable(InstanceKlass* klass, methodHandle target_method, int super_vtable_len, |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
262 bool checkconstraints, TRAPS) { |
0 | 263 ResourceMark rm; |
264 bool allocate_new = true; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
265 assert(klass->oop_is_instance(), "must be InstanceKlass"); |
0 | 266 |
267 // Initialize the method's vtable index to "nonvirtual". | |
268 // If we allocate a vtable entry, we will update it to a non-negative number. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
269 target_method()->set_vtable_index(Method::nonvirtual_vtable_index); |
0 | 270 |
271 // Static and <init> methods are never in | |
272 if (target_method()->is_static() || target_method()->name() == vmSymbols::object_initializer_name()) { | |
273 return false; | |
274 } | |
275 | |
6934 | 276 if (method_is_effectively_final(klass->access_flags(), target_method)) { |
0 | 277 // a final method never needs a new entry; final methods can be statically |
278 // resolved and they have to be present in the vtable only if they override | |
279 // a super's method, in which case they re-use its entry | |
280 allocate_new = false; | |
281 } | |
282 | |
283 // we need a new entry if there is no superclass | |
284 if (klass->super() == NULL) { | |
285 return allocate_new; | |
286 } | |
287 | |
288 // private methods always have a new entry in the vtable | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
289 // specification interpretation since classic has |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
290 // private methods not overriding |
0 | 291 if (target_method()->is_private()) { |
292 return allocate_new; | |
293 } | |
294 | |
295 // search through the vtable and update overridden entries | |
296 // Since check_signature_loaders acquires SystemDictionary_lock | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
297 // which can block for gc, once we are in this loop, use handles |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
298 // For classfiles built with >= jdk7, we now look for transitive overrides |
0 | 299 |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
300 Symbol* name = target_method()->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
301 Symbol* signature = target_method()->signature(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
302 Handle target_loader(THREAD, _klass()->class_loader()); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
303 Symbol* target_classname = _klass->name(); |
0 | 304 for(int i = 0; i < super_vtable_len; i++) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
305 Method* super_method = method_at(i); |
0 | 306 // Check if method name matches |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
307 if (super_method->name() == name && super_method->signature() == signature) { |
0 | 308 |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
309 // get super_klass for method_holder for the found method |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
310 InstanceKlass* super_klass = super_method->method_holder(); |
0 | 311 |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
312 if ((super_klass->is_override(super_method, target_loader, target_classname, THREAD)) || |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
313 ((klass->major_version() >= VTABLE_TRANSITIVE_OVERRIDE_VERSION) |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
314 && ((super_klass = find_transitive_override(super_klass, target_method, i, target_loader, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
315 target_classname, THREAD)) != (InstanceKlass*)NULL))) { |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
316 // overriding, so no new entry |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
317 allocate_new = false; |
0 | 318 |
319 if (checkconstraints) { | |
320 // Override vtable entry if passes loader constraint check | |
321 // if loader constraint checking requested | |
322 // No need to visit his super, since he and his super | |
323 // have already made any needed loader constraints. | |
324 // Since loader constraints are transitive, it is enough | |
325 // to link to the first super, and we get all the others. | |
326 Handle super_loader(THREAD, super_klass->class_loader()); | |
327 | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
328 if (target_loader() != super_loader()) { |
0 | 329 ResourceMark rm(THREAD); |
8840
cd3089a56438
8009731: Confusing error message for loader constraint violation
acorn
parents:
8021
diff
changeset
|
330 Symbol* failed_type_symbol = |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
331 SystemDictionary::check_signature_loaders(signature, target_loader, |
0 | 332 super_loader, true, |
333 CHECK_(false)); | |
8840
cd3089a56438
8009731: Confusing error message for loader constraint violation
acorn
parents:
8021
diff
changeset
|
334 if (failed_type_symbol != NULL) { |
0 | 335 const char* msg = "loader constraint violation: when resolving " |
336 "overridden method \"%s\" the class loader (instance" | |
337 " of %s) of the current class, %s, and its superclass loader " | |
338 "(instance of %s), have different Class objects for the type " | |
339 "%s used in the signature"; | |
340 char* sig = target_method()->name_and_sig_as_C_string(); | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
341 const char* loader1 = SystemDictionary::loader_name(target_loader()); |
0 | 342 char* current = _klass->name()->as_C_string(); |
343 const char* loader2 = SystemDictionary::loader_name(super_loader()); | |
8840
cd3089a56438
8009731: Confusing error message for loader constraint violation
acorn
parents:
8021
diff
changeset
|
344 char* failed_type_name = failed_type_symbol->as_C_string(); |
0 | 345 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
346 strlen(current) + strlen(loader2) + strlen(failed_type_name); | |
347 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); | |
348 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, | |
349 failed_type_name); | |
350 THROW_MSG_(vmSymbols::java_lang_LinkageError(), buf, false); | |
351 } | |
352 } | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
353 } |
0 | 354 |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
355 put_method_at(target_method(), i); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
356 target_method()->set_vtable_index(i); |
0 | 357 #ifndef PRODUCT |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
358 if (PrintVtables && Verbose) { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
359 tty->print("overriding with %s::%s index %d, original flags: ", |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
360 _klass->internal_name(), (target_method() != NULL) ? |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
361 target_method()->name()->as_C_string() : "<NULL>", i); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
362 super_method->access_flags().print_on(tty); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
363 tty->print("overriders flags: "); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
364 target_method->access_flags().print_on(tty); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
365 tty->cr(); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
366 } |
0 | 367 #endif /*PRODUCT*/ |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
368 } else { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
369 // allocate_new = true; default. We might override one entry, |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
370 // but not override another. Once we override one, not need new |
0 | 371 #ifndef PRODUCT |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
372 if (PrintVtables && Verbose) { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
373 tty->print("NOT overriding with %s::%s index %d, original flags: ", |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
374 _klass->internal_name(), (target_method() != NULL) ? |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
375 target_method()->name()->as_C_string() : "<NULL>", i); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
376 super_method->access_flags().print_on(tty); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
377 tty->print("overriders flags: "); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
378 target_method->access_flags().print_on(tty); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
379 tty->cr(); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
380 } |
0 | 381 #endif /*PRODUCT*/ |
382 } | |
383 } | |
384 } | |
385 return allocate_new; | |
386 } | |
387 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
388 void klassVtable::put_method_at(Method* m, int index) { |
0 | 389 #ifndef PRODUCT |
390 if (PrintVtables && Verbose) { | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
391 ResourceMark rm; |
0 | 392 tty->print_cr("adding %s::%s at index %d", _klass->internal_name(), |
393 (m != NULL) ? m->name()->as_C_string() : "<NULL>", index); | |
394 } | |
395 #endif | |
396 table()[index].set(m); | |
397 } | |
398 | |
399 // Find out if a method "m" with superclass "super", loader "classloader" and | |
400 // name "classname" needs a new vtable entry. Let P be a class package defined | |
401 // by "classloader" and "classname". | |
402 // NOTE: The logic used here is very similar to the one used for computing | |
403 // the vtables indices for a method. We cannot directly use that function because, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
404 // we allocate the InstanceKlass at load time, and that requires that the |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
405 // superclass has been loaded. |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
406 // However, the vtable entries are filled in at link time, and therefore |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
407 // the superclass' vtable may not yet have been filled in. |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
408 bool klassVtable::needs_new_vtable_entry(methodHandle target_method, |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
409 Klass* super, |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
410 Handle classloader, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
411 Symbol* classname, |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
412 AccessFlags class_flags, |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
413 TRAPS) { |
6934 | 414 |
415 if (method_is_effectively_final(class_flags, target_method) || | |
0 | 416 // a final method never needs a new entry; final methods can be statically |
417 // resolved and they have to be present in the vtable only if they override | |
418 // a super's method, in which case they re-use its entry | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
419 (target_method()->is_static()) || |
0 | 420 // static methods don't need to be in vtable |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
421 (target_method()->name() == vmSymbols::object_initializer_name()) |
0 | 422 // <init> is never called dynamically-bound |
423 ) { | |
424 return false; | |
425 } | |
426 | |
427 // we need a new entry if there is no superclass | |
428 if (super == NULL) { | |
429 return true; | |
430 } | |
431 | |
432 // private methods always have a new entry in the vtable | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
433 // specification interpretation since classic has |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
434 // private methods not overriding |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
435 if (target_method()->is_private()) { |
0 | 436 return true; |
437 } | |
438 | |
439 // search through the super class hierarchy to see if we need | |
440 // a new entry | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
441 ResourceMark rm; |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
442 Symbol* name = target_method()->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
443 Symbol* signature = target_method()->signature(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
444 Klass* k = super; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
445 Method* super_method = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
446 InstanceKlass *holder = NULL; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
447 Method* recheck_method = NULL; |
0 | 448 while (k != NULL) { |
449 // lookup through the hierarchy for a method with matching name and sign. | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
450 super_method = InstanceKlass::cast(k)->lookup_method(name, signature); |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
451 if (super_method == NULL) { |
0 | 452 break; // we still have to search for a matching miranda method |
453 } | |
454 // get the class holding the matching method | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
455 // make sure you use that class for is_override |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
456 InstanceKlass* superk = super_method->method_holder(); |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
457 // we want only instance method matches |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
458 // pretend private methods are not in the super vtable |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
459 // since we do override around them: e.g. a.m pub/b.m private/c.m pub, |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
460 // ignore private, c.m pub does override a.m pub |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
461 // For classes that were not javac'd together, we also do transitive overriding around |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
462 // methods that have less accessibility |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
463 if ((!super_method->is_static()) && |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
464 (!super_method->is_private())) { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
465 if (superk->is_override(super_method, classloader, classname, THREAD)) { |
0 | 466 return false; |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
467 // else keep looking for transitive overrides |
0 | 468 } |
469 } | |
470 | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
471 // Start with lookup result and continue to search up |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
472 k = superk->super(); // haven't found an override match yet; continue to look |
0 | 473 } |
474 | |
475 // if the target method is public or protected it may have a matching | |
476 // miranda method in the super, whose entry it should re-use. | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
477 // Actually, to handle cases that javac would not generate, we need |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
478 // this check for all access permissions. |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
479 InstanceKlass *sk = InstanceKlass::cast(super); |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
480 if (sk->has_miranda_methods()) { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
481 if (sk->lookup_method_in_all_interfaces(name, signature) != NULL) { |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
482 return false; // found a matching miranda; we do not need a new entry |
0 | 483 } |
484 } | |
485 return true; // found no match; we need a new entry | |
486 } | |
487 | |
488 // Support for miranda methods | |
489 | |
490 // get the vtable index of a miranda method with matching "name" and "signature" | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
491 int klassVtable::index_of_miranda(Symbol* name, Symbol* signature) { |
0 | 492 // search from the bottom, might be faster |
493 for (int i = (length() - 1); i >= 0; i--) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
494 Method* m = table()[i].method(); |
0 | 495 if (is_miranda_entry_at(i) && |
496 m->name() == name && m->signature() == signature) { | |
497 return i; | |
498 } | |
499 } | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
500 return Method::invalid_vtable_index; |
0 | 501 } |
502 | |
503 // check if an entry is miranda | |
504 bool klassVtable::is_miranda_entry_at(int i) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
505 Method* m = method_at(i); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
506 Klass* method_holder = m->method_holder(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
507 InstanceKlass *mhk = InstanceKlass::cast(method_holder); |
0 | 508 |
509 // miranda methods are interface methods in a class's vtable | |
510 if (mhk->is_interface()) { | |
6934 | 511 assert(m->is_public(), "should be public"); |
0 | 512 assert(ik()->implements_interface(method_holder) , "this class should implement the interface"); |
513 assert(is_miranda(m, ik()->methods(), ik()->super()), "should be a miranda_method"); | |
514 return true; | |
515 } | |
516 return false; | |
517 } | |
518 | |
519 // check if a method is a miranda method, given a class's methods table and it's super | |
520 // the caller must make sure that the method belongs to an interface implemented by the class | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
521 bool klassVtable::is_miranda(Method* m, Array<Method*>* class_methods, Klass* super) { |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
522 Symbol* name = m->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
523 Symbol* signature = m->signature(); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
524 if (InstanceKlass::find_method(class_methods, name, signature) == NULL) { |
2018
642e54d1850a
6989076: JVM crashes in klassItable::initialize_itable_for_interface
dsamersoff
parents:
1972
diff
changeset
|
525 // did not find it in the method table of the current class |
0 | 526 if (super == NULL) { |
527 // super doesn't exist | |
528 return true; | |
2018
642e54d1850a
6989076: JVM crashes in klassItable::initialize_itable_for_interface
dsamersoff
parents:
1972
diff
changeset
|
529 } |
642e54d1850a
6989076: JVM crashes in klassItable::initialize_itable_for_interface
dsamersoff
parents:
1972
diff
changeset
|
530 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
531 Method* mo = InstanceKlass::cast(super)->lookup_method(name, signature); |
2018
642e54d1850a
6989076: JVM crashes in klassItable::initialize_itable_for_interface
dsamersoff
parents:
1972
diff
changeset
|
532 if (mo == NULL || mo->access_flags().is_private() ) { |
642e54d1850a
6989076: JVM crashes in klassItable::initialize_itable_for_interface
dsamersoff
parents:
1972
diff
changeset
|
533 // super class hierarchy does not implement it or protection is different |
642e54d1850a
6989076: JVM crashes in klassItable::initialize_itable_for_interface
dsamersoff
parents:
1972
diff
changeset
|
534 return true; |
0 | 535 } |
536 } | |
2018
642e54d1850a
6989076: JVM crashes in klassItable::initialize_itable_for_interface
dsamersoff
parents:
1972
diff
changeset
|
537 |
0 | 538 return false; |
539 } | |
540 | |
6934 | 541 void klassVtable::add_new_mirandas_to_lists( |
542 GrowableArray<Method*>* new_mirandas, GrowableArray<Method*>* all_mirandas, | |
543 Array<Method*>* current_interface_methods, Array<Method*>* class_methods, | |
544 Klass* super) { | |
0 | 545 // iterate thru the current interface's method to see if it a miranda |
546 int num_methods = current_interface_methods->length(); | |
547 for (int i = 0; i < num_methods; i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
548 Method* im = current_interface_methods->at(i); |
0 | 549 bool is_duplicate = false; |
6934 | 550 int num_of_current_mirandas = new_mirandas->length(); |
0 | 551 // check for duplicate mirandas in different interfaces we implement |
552 for (int j = 0; j < num_of_current_mirandas; j++) { | |
6934 | 553 Method* miranda = new_mirandas->at(j); |
0 | 554 if ((im->name() == miranda->name()) && |
555 (im->signature() == miranda->signature())) { | |
556 is_duplicate = true; | |
557 break; | |
558 } | |
559 } | |
560 | |
561 if (!is_duplicate) { // we don't want duplicate miranda entries in the vtable | |
562 if (is_miranda(im, class_methods, super)) { // is it a miranda at all? | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
563 InstanceKlass *sk = InstanceKlass::cast(super); |
0 | 564 // check if it is a duplicate of a super's miranda |
565 if (sk->lookup_method_in_all_interfaces(im->name(), im->signature()) == NULL) { | |
6934 | 566 new_mirandas->append(im); |
567 } | |
568 if (all_mirandas != NULL) { | |
569 all_mirandas->append(im); | |
0 | 570 } |
571 } | |
572 } | |
573 } | |
574 } | |
575 | |
6934 | 576 void klassVtable::get_mirandas(GrowableArray<Method*>* new_mirandas, |
577 GrowableArray<Method*>* all_mirandas, | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
578 Klass* super, Array<Method*>* class_methods, |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
579 Array<Klass*>* local_interfaces) { |
6934 | 580 assert((new_mirandas->length() == 0) , "current mirandas must be 0"); |
0 | 581 |
582 // iterate thru the local interfaces looking for a miranda | |
583 int num_local_ifs = local_interfaces->length(); | |
584 for (int i = 0; i < num_local_ifs; i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
585 InstanceKlass *ik = InstanceKlass::cast(local_interfaces->at(i)); |
6934 | 586 add_new_mirandas_to_lists(new_mirandas, all_mirandas, |
587 ik->methods(), class_methods, super); | |
0 | 588 // iterate thru each local's super interfaces |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
589 Array<Klass*>* super_ifs = ik->transitive_interfaces(); |
0 | 590 int num_super_ifs = super_ifs->length(); |
591 for (int j = 0; j < num_super_ifs; j++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
592 InstanceKlass *sik = InstanceKlass::cast(super_ifs->at(j)); |
6934 | 593 add_new_mirandas_to_lists(new_mirandas, all_mirandas, |
594 sik->methods(), class_methods, super); | |
0 | 595 } |
596 } | |
597 } | |
598 | |
599 // fill in mirandas | |
6934 | 600 void klassVtable::fill_in_mirandas(int* initialized) { |
601 GrowableArray<Method*> mirandas(20); | |
602 get_mirandas(&mirandas, NULL, ik()->super(), ik()->methods(), | |
603 ik()->local_interfaces()); | |
604 for (int i = 0; i < mirandas.length(); i++) { | |
605 put_method_at(mirandas.at(i), *initialized); | |
606 ++(*initialized); | |
0 | 607 } |
608 } | |
609 | |
610 void klassVtable::copy_vtable_to(vtableEntry* start) { | |
611 Copy::disjoint_words((HeapWord*)table(), (HeapWord*)start, _length * vtableEntry::size()); | |
612 } | |
613 | |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
614 #if INCLUDE_JVMTI |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
615 void klassVtable::adjust_method_entries(Method** old_methods, Method** new_methods, |
0 | 616 int methods_length, bool * trace_name_printed) { |
617 // search the vtable for uses of either obsolete or EMCP methods | |
618 for (int j = 0; j < methods_length; j++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
619 Method* old_method = old_methods[j]; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
620 Method* new_method = new_methods[j]; |
0 | 621 |
622 // In the vast majority of cases we could get the vtable index | |
623 // by using: old_method->vtable_index() | |
624 // However, there are rare cases, eg. sun.awt.X11.XDecoratedPeer.getX() | |
625 // in sun.awt.X11.XFramePeer where methods occur more than once in the | |
626 // vtable, so, alas, we must do an exhaustive search. | |
627 for (int index = 0; index < length(); index++) { | |
628 if (unchecked_method_at(index) == old_method) { | |
629 put_method_at(new_method, index); | |
630 | |
631 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { | |
632 if (!(*trace_name_printed)) { | |
633 // RC_TRACE_MESG macro has an embedded ResourceMark | |
634 RC_TRACE_MESG(("adjust: name=%s", | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
635 old_method->method_holder()->external_name())); |
0 | 636 *trace_name_printed = true; |
637 } | |
638 // RC_TRACE macro has an embedded ResourceMark | |
639 RC_TRACE(0x00100000, ("vtable method update: %s(%s)", | |
640 new_method->name()->as_C_string(), | |
641 new_method->signature()->as_C_string())); | |
642 } | |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
643 // cannot 'break' here; see for-loop comment above. |
0 | 644 } |
645 } | |
646 } | |
647 } | |
648 | |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
649 // a vtable should never contain old or obsolete methods |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
650 bool klassVtable::check_no_old_or_obsolete_entries() { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
651 for (int i = 0; i < length(); i++) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
652 Method* m = unchecked_method_at(i); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
653 if (m != NULL && |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
654 (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
655 return false; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
656 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
657 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
658 return true; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
659 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
660 |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
661 void klassVtable::dump_vtable() { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
662 tty->print_cr("vtable dump --"); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
663 for (int i = 0; i < length(); i++) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
664 Method* m = unchecked_method_at(i); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
665 if (m != NULL) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
666 tty->print(" (%5d) ", i); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
667 m->access_flags().print_on(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
668 tty->print(" -- "); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
669 m->print_name(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
670 tty->cr(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
671 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
672 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
673 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
674 #endif // INCLUDE_JVMTI |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
675 |
3245
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2376
diff
changeset
|
676 // CDS/RedefineClasses support - clear vtables so they can be reinitialized |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2376
diff
changeset
|
677 void klassVtable::clear_vtable() { |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2376
diff
changeset
|
678 for (int i = 0; i < _length; i++) table()[i].clear(); |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2376
diff
changeset
|
679 } |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2376
diff
changeset
|
680 |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2376
diff
changeset
|
681 bool klassVtable::is_initialized() { |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2376
diff
changeset
|
682 return _length == 0 || table()[0].method() != NULL; |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2376
diff
changeset
|
683 } |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2376
diff
changeset
|
684 |
0 | 685 //----------------------------------------------------------------------------------------- |
686 // Itable code | |
687 | |
688 // Initialize a itableMethodEntry | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
689 void itableMethodEntry::initialize(Method* m) { |
0 | 690 if (m == NULL) return; |
691 | |
692 _method = m; | |
693 } | |
694 | |
695 klassItable::klassItable(instanceKlassHandle klass) { | |
696 _klass = klass; | |
697 | |
698 if (klass->itable_length() > 0) { | |
699 itableOffsetEntry* offset_entry = (itableOffsetEntry*)klass->start_of_itable(); | |
700 if (offset_entry != NULL && offset_entry->interface_klass() != NULL) { // Check that itable is initialized | |
701 // First offset entry points to the first method_entry | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
702 intptr_t* method_entry = (intptr_t *)(((address)klass()) + offset_entry->offset()); |
0 | 703 intptr_t* end = klass->end_of_itable(); |
704 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
705 _table_offset = (intptr_t*)offset_entry - (intptr_t*)klass(); |
0 | 706 _size_offset_table = (method_entry - ((intptr_t*)offset_entry)) / itableOffsetEntry::size(); |
707 _size_method_table = (end - method_entry) / itableMethodEntry::size(); | |
708 assert(_table_offset >= 0 && _size_offset_table >= 0 && _size_method_table >= 0, "wrong computation"); | |
709 return; | |
710 } | |
711 } | |
712 | |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
713 // The length of the itable was either zero, or it has not yet been initialized. |
0 | 714 _table_offset = 0; |
715 _size_offset_table = 0; | |
716 _size_method_table = 0; | |
717 } | |
718 | |
719 static int initialize_count = 0; | |
720 | |
721 // Initialization | |
722 void klassItable::initialize_itable(bool checkconstraints, TRAPS) { | |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
723 // Cannot be setup doing bootstrapping, interfaces don't have |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
724 // itables, and klass with only ones entry have empty itables |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
725 if (Universe::is_bootstrapping() || |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
726 _klass->is_interface() || |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
727 _klass->itable_length() == itableOffsetEntry::size()) return; |
0 | 728 |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
729 // There's alway an extra itable entry so we can null-terminate it. |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
730 guarantee(size_offset_table() >= 1, "too small"); |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
731 int num_interfaces = size_offset_table() - 1; |
0 | 732 if (num_interfaces > 0) { |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
733 if (TraceItables) tty->print_cr("%3d: Initializing itables for %s", ++initialize_count, |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
734 _klass->name()->as_C_string()); |
0 | 735 |
736 | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
610
diff
changeset
|
737 // Iterate through all interfaces |
0 | 738 int i; |
739 for(i = 0; i < num_interfaces; i++) { | |
740 itableOffsetEntry* ioe = offset_entry(i); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
741 HandleMark hm(THREAD); |
0 | 742 KlassHandle interf_h (THREAD, ioe->interface_klass()); |
743 assert(interf_h() != NULL && ioe->offset() != 0, "bad offset entry in itable"); | |
744 initialize_itable_for_interface(ioe->offset(), interf_h, checkconstraints, CHECK); | |
745 } | |
746 | |
747 } | |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
748 // Check that the last entry is empty |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
749 itableOffsetEntry* ioe = offset_entry(size_offset_table() - 1); |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
750 guarantee(ioe->interface_klass() == NULL && ioe->offset() == 0, "terminator entry missing"); |
0 | 751 } |
752 | |
753 | |
754 void klassItable::initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
755 Array<Method*>* methods = InstanceKlass::cast(interf_h())->methods(); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
756 int nof_methods = methods->length(); |
0 | 757 HandleMark hm; |
758 KlassHandle klass = _klass; | |
1489
cff162798819
6888953: some calls to function-like macros are missing semicolons
jcoomes
parents:
676
diff
changeset
|
759 assert(nof_methods > 0, "at least one method must exist for interface to be in vtable"); |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
760 Handle interface_loader (THREAD, InstanceKlass::cast(interf_h())->class_loader()); |
0 | 761 int ime_num = 0; |
762 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
763 // Skip first Method* if it is a class initializer |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
764 int i = methods->at(0)->is_static_initializer() ? 1 : 0; |
0 | 765 |
766 // m, method_name, method_signature, klass reset each loop so they | |
767 // don't need preserving across check_signature_loaders call | |
768 // methods needs a handle in case of gc from check_signature_loaders | |
769 for(; i < nof_methods; i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
770 Method* m = methods->at(i); |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
771 Symbol* method_name = m->name(); |
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
2018
diff
changeset
|
772 Symbol* method_signature = m->signature(); |
0 | 773 |
774 // This is same code as in Linkresolver::lookup_instance_method_in_klasses | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
775 Method* target = klass->uncached_lookup_method(method_name, method_signature); |
0 | 776 while (target != NULL && target->is_static()) { |
777 // continue with recursive lookup through the superclass | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
778 Klass* super = target->method_holder()->super(); |
6983 | 779 target = (super == NULL) ? (Method*)NULL : super->uncached_lookup_method(method_name, method_signature); |
0 | 780 } |
781 if (target == NULL || !target->is_public() || target->is_abstract()) { | |
782 // Entry do not resolve. Leave it empty | |
783 } else { | |
784 // Entry did resolve, check loader constraints before initializing | |
785 // if checkconstraints requested | |
786 methodHandle target_h (THREAD, target); // preserve across gc | |
787 if (checkconstraints) { | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
788 Handle method_holder_loader (THREAD, target->method_holder()->class_loader()); |
0 | 789 if (method_holder_loader() != interface_loader()) { |
790 ResourceMark rm(THREAD); | |
8840
cd3089a56438
8009731: Confusing error message for loader constraint violation
acorn
parents:
8021
diff
changeset
|
791 Symbol* failed_type_symbol = |
0 | 792 SystemDictionary::check_signature_loaders(method_signature, |
793 method_holder_loader, | |
794 interface_loader, | |
795 true, CHECK); | |
8840
cd3089a56438
8009731: Confusing error message for loader constraint violation
acorn
parents:
8021
diff
changeset
|
796 if (failed_type_symbol != NULL) { |
0 | 797 const char* msg = "loader constraint violation in interface " |
798 "itable initialization: when resolving method \"%s\" the class" | |
799 " loader (instance of %s) of the current class, %s, " | |
800 "and the class loader (instance of %s) for interface " | |
801 "%s have different Class objects for the type %s " | |
802 "used in the signature"; | |
803 char* sig = target_h()->name_and_sig_as_C_string(); | |
804 const char* loader1 = SystemDictionary::loader_name(method_holder_loader()); | |
805 char* current = klass->name()->as_C_string(); | |
806 const char* loader2 = SystemDictionary::loader_name(interface_loader()); | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
807 char* iface = InstanceKlass::cast(interf_h())->name()->as_C_string(); |
8840
cd3089a56438
8009731: Confusing error message for loader constraint violation
acorn
parents:
8021
diff
changeset
|
808 char* failed_type_name = failed_type_symbol->as_C_string(); |
0 | 809 size_t buflen = strlen(msg) + strlen(sig) + strlen(loader1) + |
810 strlen(current) + strlen(loader2) + strlen(iface) + | |
811 strlen(failed_type_name); | |
812 char* buf = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, buflen); | |
813 jio_snprintf(buf, buflen, msg, sig, loader1, current, loader2, | |
814 iface, failed_type_name); | |
815 THROW_MSG(vmSymbols::java_lang_LinkageError(), buf); | |
816 } | |
817 } | |
818 } | |
819 | |
820 // ime may have moved during GC so recalculate address | |
821 itableOffsetEntry::method_entry(_klass(), method_table_offset)[ime_num].initialize(target_h()); | |
822 } | |
823 // Progress to next entry | |
824 ime_num++; | |
825 } | |
826 } | |
827 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
828 // Update entry for specific Method* |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
829 void klassItable::initialize_with_method(Method* m) { |
0 | 830 itableMethodEntry* ime = method_entry(0); |
831 for(int i = 0; i < _size_method_table; i++) { | |
832 if (ime->method() == m) { | |
833 ime->initialize(m); | |
834 } | |
835 ime++; | |
836 } | |
837 } | |
838 | |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
839 #if INCLUDE_JVMTI |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
840 void klassItable::adjust_method_entries(Method** old_methods, Method** new_methods, |
0 | 841 int methods_length, bool * trace_name_printed) { |
842 // search the itable for uses of either obsolete or EMCP methods | |
843 for (int j = 0; j < methods_length; j++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
844 Method* old_method = old_methods[j]; |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
845 Method* new_method = new_methods[j]; |
0 | 846 itableMethodEntry* ime = method_entry(0); |
847 | |
610
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
196
diff
changeset
|
848 // The itable can describe more than one interface and the same |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
196
diff
changeset
|
849 // method signature can be specified by more than one interface. |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
196
diff
changeset
|
850 // This means we have to do an exhaustive search to find all the |
70998f2e05ef
6805864: 4/3 Problem with jvmti->redefineClasses: some methods don't get redefined
dcubed
parents:
196
diff
changeset
|
851 // old_method references. |
0 | 852 for (int i = 0; i < _size_method_table; i++) { |
853 if (ime->method() == old_method) { | |
854 ime->initialize(new_method); | |
855 | |
856 if (RC_TRACE_IN_RANGE(0x00100000, 0x00400000)) { | |
857 if (!(*trace_name_printed)) { | |
858 // RC_TRACE_MESG macro has an embedded ResourceMark | |
859 RC_TRACE_MESG(("adjust: name=%s", | |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
860 old_method->method_holder()->external_name())); |
0 | 861 *trace_name_printed = true; |
862 } | |
863 // RC_TRACE macro has an embedded ResourceMark | |
864 RC_TRACE(0x00200000, ("itable method update: %s(%s)", | |
865 new_method->name()->as_C_string(), | |
866 new_method->signature()->as_C_string())); | |
867 } | |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
868 // cannot 'break' here; see for-loop comment above. |
0 | 869 } |
870 ime++; | |
871 } | |
872 } | |
873 } | |
874 | |
8021
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
875 // an itable should never contain old or obsolete methods |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
876 bool klassItable::check_no_old_or_obsolete_entries() { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
877 itableMethodEntry* ime = method_entry(0); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
878 for (int i = 0; i < _size_method_table; i++) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
879 Method* m = ime->method(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
880 if (m != NULL && |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
881 (NOT_PRODUCT(!m->is_valid() ||) m->is_old() || m->is_obsolete())) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
882 return false; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
883 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
884 ime++; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
885 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
886 return true; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
887 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
888 |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
889 void klassItable::dump_itable() { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
890 itableMethodEntry* ime = method_entry(0); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
891 tty->print_cr("itable dump --"); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
892 for (int i = 0; i < _size_method_table; i++) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
893 Method* m = ime->method(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
894 if (m != NULL) { |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
895 tty->print(" (%5d) ", i); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
896 m->access_flags().print_on(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
897 tty->print(" -- "); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
898 m->print_name(tty); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
899 tty->cr(); |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
900 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
901 ime++; |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
902 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
903 } |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
904 #endif // INCLUDE_JVMTI |
8d9fc28831cc
7182152: Instrumentation hot swap test incorrect monitor count
dcubed
parents:
6983
diff
changeset
|
905 |
0 | 906 |
907 // Setup | |
908 class InterfaceVisiterClosure : public StackObj { | |
909 public: | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
910 virtual void doit(Klass* intf, int method_count) = 0; |
0 | 911 }; |
912 | |
913 // Visit all interfaces with at-least one method (excluding <clinit>) | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
914 void visit_all_interfaces(Array<Klass*>* transitive_intf, InterfaceVisiterClosure *blk) { |
0 | 915 // Handle array argument |
916 for(int i = 0; i < transitive_intf->length(); i++) { | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
917 Klass* intf = transitive_intf->at(i); |
6983 | 918 assert(intf->is_interface(), "sanity check"); |
0 | 919 |
920 // Find no. of methods excluding a <clinit> | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
921 int method_count = InstanceKlass::cast(intf)->methods()->length(); |
0 | 922 if (method_count > 0) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
923 Method* m = InstanceKlass::cast(intf)->methods()->at(0); |
0 | 924 assert(m != NULL && m->is_method(), "sanity check"); |
925 if (m->name() == vmSymbols::object_initializer_name()) { | |
926 method_count--; | |
927 } | |
928 } | |
929 | |
930 // Only count interfaces with at least one method | |
931 if (method_count > 0) { | |
932 blk->doit(intf, method_count); | |
933 } | |
934 } | |
935 } | |
936 | |
937 class CountInterfacesClosure : public InterfaceVisiterClosure { | |
938 private: | |
939 int _nof_methods; | |
940 int _nof_interfaces; | |
941 public: | |
942 CountInterfacesClosure() { _nof_methods = 0; _nof_interfaces = 0; } | |
943 | |
944 int nof_methods() const { return _nof_methods; } | |
945 int nof_interfaces() const { return _nof_interfaces; } | |
946 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
947 void doit(Klass* intf, int method_count) { _nof_methods += method_count; _nof_interfaces++; } |
0 | 948 }; |
949 | |
950 class SetupItableClosure : public InterfaceVisiterClosure { | |
951 private: | |
952 itableOffsetEntry* _offset_entry; | |
953 itableMethodEntry* _method_entry; | |
954 address _klass_begin; | |
955 public: | |
956 SetupItableClosure(address klass_begin, itableOffsetEntry* offset_entry, itableMethodEntry* method_entry) { | |
957 _klass_begin = klass_begin; | |
958 _offset_entry = offset_entry; | |
959 _method_entry = method_entry; | |
960 } | |
961 | |
962 itableMethodEntry* method_entry() const { return _method_entry; } | |
963 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
964 void doit(Klass* intf, int method_count) { |
0 | 965 int offset = ((address)_method_entry) - _klass_begin; |
966 _offset_entry->initialize(intf, offset); | |
967 _offset_entry++; | |
968 _method_entry += method_count; | |
969 } | |
970 }; | |
971 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
972 int klassItable::compute_itable_size(Array<Klass*>* transitive_interfaces) { |
0 | 973 // Count no of interfaces and total number of interface methods |
974 CountInterfacesClosure cic; | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
975 visit_all_interfaces(transitive_interfaces, &cic); |
0 | 976 |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
977 // There's alway an extra itable entry so we can null-terminate it. |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
978 int itable_size = calc_itable_size(cic.nof_interfaces() + 1, cic.nof_methods()); |
0 | 979 |
980 // Statistics | |
981 update_stats(itable_size * HeapWordSize); | |
982 | |
983 return itable_size; | |
984 } | |
985 | |
986 | |
987 // Fill out offset table and interface klasses into the itable space | |
988 void klassItable::setup_itable_offset_table(instanceKlassHandle klass) { | |
989 if (klass->itable_length() == 0) return; | |
990 assert(!klass->is_interface(), "Should have zero length itable"); | |
991 | |
992 // Count no of interfaces and total number of interface methods | |
993 CountInterfacesClosure cic; | |
994 visit_all_interfaces(klass->transitive_interfaces(), &cic); | |
995 int nof_methods = cic.nof_methods(); | |
996 int nof_interfaces = cic.nof_interfaces(); | |
997 | |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
998 // Add one extra entry so we can null-terminate the table |
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
999 nof_interfaces++; |
0 | 1000 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1001 assert(compute_itable_size(klass->transitive_interfaces()) == |
0 | 1002 calc_itable_size(nof_interfaces, nof_methods), |
1003 "mismatch calculation of itable size"); | |
1004 | |
1005 // Fill-out offset table | |
1006 itableOffsetEntry* ioe = (itableOffsetEntry*)klass->start_of_itable(); | |
1007 itableMethodEntry* ime = (itableMethodEntry*)(ioe + nof_interfaces); | |
1008 intptr_t* end = klass->end_of_itable(); | |
2376
c7f3d0b4570f
7017732: move static fields into Class to prepare for perm gen removal
never
parents:
2334
diff
changeset
|
1009 assert((oop*)(ime + nof_methods) <= (oop*)klass->start_of_nonstatic_oop_maps(), "wrong offset calculation (1)"); |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
16
diff
changeset
|
1010 assert((oop*)(end) == (oop*)(ime + nof_methods), "wrong offset calculation (2)"); |
0 | 1011 |
1012 // Visit all interfaces and initialize itable offset table | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1013 SetupItableClosure sic((address)klass(), ioe, ime); |
0 | 1014 visit_all_interfaces(klass->transitive_interfaces(), &sic); |
1015 | |
1016 #ifdef ASSERT | |
1017 ime = sic.method_entry(); | |
1018 oop* v = (oop*) klass->end_of_itable(); | |
1019 assert( (oop*)(ime) == v, "wrong offset calculation (2)"); | |
1020 #endif | |
1021 } | |
1022 | |
1023 | |
1024 // m must be a method in an interface | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1025 int klassItable::compute_itable_index(Method* m) { |
6940
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
1026 InstanceKlass* intf = m->method_holder(); |
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
1027 assert(intf->is_interface(), "sanity check"); |
18fb7da42534
8000725: NPG: method_holder() and pool_holder() and pool_holder field should be InstanceKlass
coleenp
parents:
6934
diff
changeset
|
1028 Array<Method*>* methods = intf->methods(); |
0 | 1029 int index = 0; |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1030 while(methods->at(index) != m) { |
0 | 1031 index++; |
1032 assert(index < methods->length(), "should find index for resolve_invoke"); | |
1033 } | |
1034 // Adjust for <clinit>, which is left out of table if first method | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1035 if (methods->length() > 0 && methods->at(0)->is_static_initializer()) { |
0 | 1036 index--; |
1037 } | |
1038 return index; | |
1039 } | |
1040 | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1041 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1042 // inverse to compute_itable_index |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1043 Method* klassItable::method_for_itable_index(Klass* intf, int itable_index) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1044 assert(InstanceKlass::cast(intf)->is_interface(), "sanity check"); |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1045 Array<Method*>* methods = InstanceKlass::cast(intf)->methods(); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1046 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1047 int index = itable_index; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1048 // Adjust for <clinit>, which is left out of table if first method |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1049 if (methods->length() > 0 && methods->at(0)->is_static_initializer()) { |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1050 index++; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1051 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1052 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1053 if (itable_index < 0 || index >= methods->length()) |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1054 return NULL; // help caller defend against bad indexes |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1055 |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1056 Method* m = methods->at(index); |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1057 assert(compute_itable_index(m) == itable_index, "correct inverse"); |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1058 |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1059 return m; |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1060 } |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
610
diff
changeset
|
1061 |
0 | 1062 void klassVtable::verify(outputStream* st, bool forced) { |
1063 // make sure table is initialized | |
1064 if (!Universe::is_fully_initialized()) return; | |
1065 #ifndef PRODUCT | |
1066 // avoid redundant verifies | |
1067 if (!forced && _verify_count == Universe::verify_count()) return; | |
1068 _verify_count = Universe::verify_count(); | |
1069 #endif | |
1070 oop* end_of_obj = (oop*)_klass() + _klass()->size(); | |
1071 oop* end_of_vtable = (oop *)&table()[_length]; | |
1072 if (end_of_vtable > end_of_obj) { | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1489
diff
changeset
|
1073 fatal(err_msg("klass %s: klass object too short (vtable extends beyond " |
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1489
diff
changeset
|
1074 "end)", _klass->internal_name())); |
0 | 1075 } |
1076 | |
1077 for (int i = 0; i < _length; i++) table()[i].verify(this, st); | |
1078 // verify consistency with superKlass vtable | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1079 Klass* super = _klass->super(); |
0 | 1080 if (super != NULL) { |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1081 InstanceKlass* sk = InstanceKlass::cast(super); |
0 | 1082 klassVtable* vt = sk->vtable(); |
1083 for (int i = 0; i < vt->length(); i++) { | |
1084 verify_against(st, vt, i); | |
1085 } | |
1086 } | |
1087 } | |
1088 | |
1089 void klassVtable::verify_against(outputStream* st, klassVtable* vt, int index) { | |
1090 vtableEntry* vte = &vt->table()[index]; | |
1091 if (vte->method()->name() != table()[index].method()->name() || | |
1092 vte->method()->signature() != table()[index].method()->signature()) { | |
1093 fatal("mismatched name/signature of vtable entries"); | |
1094 } | |
1095 } | |
1096 | |
1097 #ifndef PRODUCT | |
1098 void klassVtable::print() { | |
1099 ResourceMark rm; | |
1100 tty->print("klassVtable for klass %s (length %d):\n", _klass->internal_name(), length()); | |
1101 for (int i = 0; i < length(); i++) { | |
1102 table()[i].print(); | |
1103 tty->cr(); | |
1104 } | |
1105 } | |
1106 #endif | |
1107 | |
1108 void vtableEntry::verify(klassVtable* vt, outputStream* st) { | |
1109 NOT_PRODUCT(FlagSetting fs(IgnoreLockingAssertions, true)); | |
1110 assert(method() != NULL, "must have set method"); | |
1111 method()->verify(); | |
1112 // we sub_type, because it could be a miranda method | |
1113 if (!vt->klass()->is_subtype_of(method()->method_holder())) { | |
1114 #ifndef PRODUCT | |
1115 print(); | |
1116 #endif | |
1490
f03d0a26bf83
6888954: argument formatting for assert() and friends
jcoomes
parents:
1489
diff
changeset
|
1117 fatal(err_msg("vtableEntry " PTR_FORMAT ": method is from subclass", this)); |
0 | 1118 } |
1119 } | |
1120 | |
1121 #ifndef PRODUCT | |
1122 | |
1123 void vtableEntry::print() { | |
1124 ResourceMark rm; | |
1125 tty->print("vtableEntry %s: ", method()->name()->as_C_string()); | |
1126 if (Verbose) { | |
1127 tty->print("m %#lx ", (address)method()); | |
1128 } | |
1129 } | |
1130 | |
1131 class VtableStats : AllStatic { | |
1132 public: | |
1133 static int no_klasses; // # classes with vtables | |
1134 static int no_array_klasses; // # array classes | |
1135 static int no_instance_klasses; // # instanceKlasses | |
1136 static int sum_of_vtable_len; // total # of vtable entries | |
1137 static int sum_of_array_vtable_len; // total # of vtable entries in array klasses only | |
1138 static int fixed; // total fixed overhead in bytes | |
1139 static int filler; // overhead caused by filler bytes | |
1140 static int entries; // total bytes consumed by vtable entries | |
1141 static int array_entries; // total bytes consumed by array vtable entries | |
1142 | |
6725
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1143 static void do_class(Klass* k) { |
da91efe96a93
6964458: Reimplement class meta-data storage to use native memory
coleenp
parents:
3245
diff
changeset
|
1144 Klass* kl = k; |
0 | 1145 klassVtable* vt = kl->vtable(); |
1146 if (vt == NULL) return; | |
1147 no_klasses++; | |
1148 if (kl->oop_is_instance()) { | |
1149 no_instance_klasses++; | |
1150 kl->array_klasses_do(do_class); | |
1151 } | |
1152 if (kl->oop_is_array()) { | |
1153 no_array_klasses++; | |
1154 sum_of_array_vtable_len += vt->length(); | |
1155 } | |
1156 sum_of_vtable_len += vt->length(); | |
1157 } | |
1158 | |
1159 static void compute() { | |
1160 SystemDictionary::classes_do(do_class); | |
1161 fixed = no_klasses * oopSize; // vtable length | |
1162 // filler size is a conservative approximation | |
6831
d8ce2825b193
8000213: NPG: Should have renamed arrayKlass and typeArrayKlass
coleenp
parents:
6725
diff
changeset
|
1163 filler = oopSize * (no_klasses - no_instance_klasses) * (sizeof(InstanceKlass) - sizeof(ArrayKlass) - 1); |
0 | 1164 entries = sizeof(vtableEntry) * sum_of_vtable_len; |
1165 array_entries = sizeof(vtableEntry) * sum_of_array_vtable_len; | |
1166 } | |
1167 }; | |
1168 | |
1169 int VtableStats::no_klasses = 0; | |
1170 int VtableStats::no_array_klasses = 0; | |
1171 int VtableStats::no_instance_klasses = 0; | |
1172 int VtableStats::sum_of_vtable_len = 0; | |
1173 int VtableStats::sum_of_array_vtable_len = 0; | |
1174 int VtableStats::fixed = 0; | |
1175 int VtableStats::filler = 0; | |
1176 int VtableStats::entries = 0; | |
1177 int VtableStats::array_entries = 0; | |
1178 | |
1179 void klassVtable::print_statistics() { | |
1180 ResourceMark rm; | |
1181 HandleMark hm; | |
1182 VtableStats::compute(); | |
1183 tty->print_cr("vtable statistics:"); | |
1184 tty->print_cr("%6d classes (%d instance, %d array)", VtableStats::no_klasses, VtableStats::no_instance_klasses, VtableStats::no_array_klasses); | |
1185 int total = VtableStats::fixed + VtableStats::filler + VtableStats::entries; | |
1186 tty->print_cr("%6d bytes fixed overhead (refs + vtable object header)", VtableStats::fixed); | |
1187 tty->print_cr("%6d bytes filler overhead", VtableStats::filler); | |
1188 tty->print_cr("%6d bytes for vtable entries (%d for arrays)", VtableStats::entries, VtableStats::array_entries); | |
1189 tty->print_cr("%6d bytes total", total); | |
1190 } | |
1191 | |
1192 int klassItable::_total_classes; // Total no. of classes with itables | |
1193 long klassItable::_total_size; // Total no. of bytes used for itables | |
1194 | |
1195 void klassItable::print_statistics() { | |
1196 tty->print_cr("itable statistics:"); | |
1197 tty->print_cr("%6d classes with itables", _total_classes); | |
1198 tty->print_cr("%6d K uses for itables (average by class: %d bytes)", _total_size / K, _total_size / _total_classes); | |
1199 } | |
1200 | |
1201 #endif // PRODUCT |