annotate src/share/vm/oops/klassVtable.cpp @ 4155:394404b2d9bd

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