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