annotate src/share/vm/oops/klassVtable.cpp @ 10185:d50cc62e94ff

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