annotate src/share/vm/oops/klassVtable.cpp @ 6862:8a5ea0a9ccc4

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