Mercurial > hg > truffle
annotate src/share/vm/oops/klassVtable.hpp @ 4710:41406797186b
7113012: G1: rename not-fully-young GCs as "mixed"
Summary: Renamed partially-young GCs as mixed and fully-young GCs as young. Change all external output that includes those terms (GC log and GC ergo log) as well as any comments, fields, methods, etc. The changeset also includes very minor code tidying up (added some curly brackets).
Reviewed-by: johnc, brutisso
author | tonyp |
---|---|
date | Fri, 16 Dec 2011 02:14:27 -0500 |
parents | 8ce625481709 |
children | da91efe96a93 |
rev | line source |
---|---|
0 | 1 /* |
2227 | 2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
676
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
676
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:
676
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
1972 | 25 #ifndef SHARE_VM_OOPS_KLASSVTABLE_HPP |
26 #define SHARE_VM_OOPS_KLASSVTABLE_HPP | |
27 | |
28 #include "memory/allocation.hpp" | |
29 #include "oops/oopsHierarchy.hpp" | |
30 #include "runtime/handles.hpp" | |
31 #include "utilities/growableArray.hpp" | |
32 | |
0 | 33 // A klassVtable abstracts the variable-length vtable that is embedded in instanceKlass |
34 // and arrayKlass. klassVtable objects are used just as convenient transient accessors to the vtable, | |
35 // not to actually hold the vtable data. | |
36 // Note: the klassVtable should not be accessed before the class has been verified | |
37 // (until that point, the vtable is uninitialized). | |
38 | |
39 // Currently a klassVtable contains a direct reference to the vtable data, and is therefore | |
40 // not preserved across GCs. | |
41 | |
42 class vtableEntry; | |
43 | |
44 class klassVtable : public ResourceObj { | |
45 KlassHandle _klass; // my klass | |
46 int _tableOffset; // offset of start of vtable data within klass | |
47 int _length; // length of vtable (number of entries) | |
48 #ifndef PRODUCT | |
49 int _verify_count; // to make verify faster | |
50 #endif | |
51 | |
52 // Ordering important, so greater_than (>) can be used as an merge operator. | |
53 enum AccessType { | |
54 acc_private = 0, | |
55 acc_package_private = 1, | |
56 acc_publicprotected = 2 | |
57 }; | |
58 | |
59 public: | |
60 klassVtable(KlassHandle h_klass, void* base, int length) : _klass(h_klass) { | |
61 _tableOffset = (address)base - (address)h_klass(); _length = length; | |
62 } | |
63 | |
64 // accessors | |
65 vtableEntry* table() const { return (vtableEntry*)(address(_klass()) + _tableOffset); } | |
66 KlassHandle klass() const { return _klass; } | |
67 int length() const { return _length; } | |
68 inline methodOop method_at(int i) const; | |
69 inline methodOop unchecked_method_at(int i) const; | |
70 inline oop* adr_method_at(int i) const; | |
71 | |
72 // searching; all methods return -1 if not found | |
73 int index_of(methodOop m) const { return index_of(m, _length); } | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
74 int index_of_miranda(Symbol* name, Symbol* signature); |
0 | 75 |
76 void initialize_vtable(bool checkconstraints, TRAPS); // initialize vtable of a new klass | |
77 | |
3245
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2227
diff
changeset
|
78 // CDS/RedefineClasses support - clear vtables so they can be reinitialized |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2227
diff
changeset
|
79 // at dump time. Clearing gives us an easy way to tell if the vtable has |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2227
diff
changeset
|
80 // already been reinitialized at dump time (see dump.cpp). Vtables can |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2227
diff
changeset
|
81 // be initialized at run time by RedefineClasses so dumping the right order |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2227
diff
changeset
|
82 // is necessary. |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2227
diff
changeset
|
83 void clear_vtable(); |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2227
diff
changeset
|
84 bool is_initialized(); |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2227
diff
changeset
|
85 |
8ce625481709
7032407: Crash in LinkResolver::runtime_resolve_virtual_method()
coleenp
parents:
2227
diff
changeset
|
86 // computes vtable length (in words) and the number of miranda methods |
0 | 87 static void compute_vtable_size_and_num_mirandas(int &vtable_length, int &num_miranda_methods, |
88 klassOop super, objArrayOop methods, | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
16
diff
changeset
|
89 AccessFlags class_flags, Handle classloader, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
90 Symbol* classname, objArrayOop local_interfaces, |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
16
diff
changeset
|
91 TRAPS); |
0 | 92 |
93 // RedefineClasses() API support: | |
94 // If any entry of this vtable points to any of old_methods, | |
95 // replace it with the corresponding new_method. | |
96 // trace_name_printed is set to true if the current call has | |
97 // printed the klass name so that other routines in the adjust_* | |
98 // group don't print the klass name. | |
99 void adjust_method_entries(methodOop* old_methods, methodOop* new_methods, | |
100 int methods_length, bool * trace_name_printed); | |
101 | |
102 // Garbage collection | |
103 void oop_follow_contents(); | |
104 void oop_adjust_pointers(); | |
105 | |
106 #ifndef SERIALGC | |
107 // Parallel Old | |
108 void oop_follow_contents(ParCompactionManager* cm); | |
109 void oop_update_pointers(ParCompactionManager* cm); | |
110 #endif // SERIALGC | |
111 | |
112 // Iterators | |
113 void oop_oop_iterate(OopClosure* blk); | |
114 void oop_oop_iterate_m(OopClosure* blk, MemRegion mr); | |
115 | |
116 // Debugging code | |
117 void print() PRODUCT_RETURN; | |
118 void verify(outputStream* st, bool force = false); | |
119 static void print_statistics() PRODUCT_RETURN; | |
120 | |
121 #ifndef PRODUCT | |
122 bool check_no_old_entries(); | |
123 void dump_vtable(); | |
124 #endif | |
125 | |
126 protected: | |
127 friend class vtableEntry; | |
128 private: | |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
16
diff
changeset
|
129 enum { VTABLE_TRANSITIVE_OVERRIDE_VERSION = 51 } ; |
0 | 130 void copy_vtable_to(vtableEntry* start); |
131 int initialize_from_super(KlassHandle super); | |
132 int index_of(methodOop m, int len) const; // same as index_of, but search only up to len | |
133 void put_method_at(methodOop m, int index); | |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
134 static bool needs_new_vtable_entry(methodHandle m, klassOop super, Handle classloader, Symbol* classname, AccessFlags access_flags, TRAPS); |
0 | 135 |
652
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
16
diff
changeset
|
136 bool update_inherited_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len, bool checkconstraints, TRAPS); |
4aaa9f5e02a8
4766230: Hotspot vtable inconsistencies cause core dumps. 6579515. 6582242.
acorn
parents:
16
diff
changeset
|
137 instanceKlass* find_transitive_override(instanceKlass* initialsuper, methodHandle target_method, int vtable_index, |
2177
3582bf76420e
6990754: Use native memory and reference counting to implement SymbolTable
coleenp
parents:
1972
diff
changeset
|
138 Handle target_loader, Symbol* target_classname, Thread* THREAD); |
0 | 139 |
140 // support for miranda methods | |
141 bool is_miranda_entry_at(int i); | |
142 void fill_in_mirandas(int& initialized); | |
143 static bool is_miranda(methodOop m, objArrayOop class_methods, klassOop super); | |
144 static void add_new_mirandas_to_list(GrowableArray<methodOop>* list_of_current_mirandas, objArrayOop current_interface_methods, objArrayOop class_methods, klassOop super); | |
145 static void get_mirandas(GrowableArray<methodOop>* mirandas, klassOop super, objArrayOop class_methods, objArrayOop local_interfaces); | |
146 static int get_num_mirandas(klassOop super, objArrayOop class_methods, objArrayOop local_interfaces); | |
147 | |
148 | |
149 void verify_against(outputStream* st, klassVtable* vt, int index); | |
150 inline instanceKlass* ik() const; | |
151 }; | |
152 | |
153 | |
154 // private helper class for klassVtable | |
155 // description of entry points: | |
156 // destination is interpreted: | |
157 // from_compiled_code_entry_point -> c2iadapter | |
158 // from_interpreter_entry_point -> interpreter entry point | |
159 // destination is compiled: | |
160 // from_compiled_code_entry_point -> nmethod entry point | |
161 // from_interpreter_entry_point -> i2cadapter | |
162 class vtableEntry VALUE_OBJ_CLASS_SPEC { | |
163 public: | |
164 // size in words | |
165 static int size() { | |
166 return sizeof(vtableEntry) / sizeof(HeapWord); | |
167 } | |
168 static int method_offset_in_bytes() { return offset_of(vtableEntry, _method); } | |
169 methodOop method() const { return _method; } | |
170 | |
171 private: | |
172 methodOop _method; | |
173 void set(methodOop method) { assert(method != NULL, "use clear"); _method = method; } | |
174 void clear() { _method = NULL; } | |
175 void print() PRODUCT_RETURN; | |
176 void verify(klassVtable* vt, outputStream* st); | |
177 | |
178 friend class klassVtable; | |
179 }; | |
180 | |
181 | |
182 inline methodOop klassVtable::method_at(int i) const { | |
183 assert(i >= 0 && i < _length, "index out of bounds"); | |
184 assert(table()[i].method() != NULL, "should not be null"); | |
185 assert(oop(table()[i].method())->is_method(), "should be method"); | |
186 return table()[i].method(); | |
187 } | |
188 | |
189 inline methodOop klassVtable::unchecked_method_at(int i) const { | |
190 assert(i >= 0 && i < _length, "index out of bounds"); | |
191 return table()[i].method(); | |
192 } | |
193 | |
194 inline oop* klassVtable::adr_method_at(int i) const { | |
195 // Allow one past the last entry to be referenced; useful for loop bounds. | |
196 assert(i >= 0 && i <= _length, "index out of bounds"); | |
197 return (oop*)(address(table() + i) + vtableEntry::method_offset_in_bytes()); | |
198 } | |
199 | |
200 // -------------------------------------------------------------------------------- | |
201 class klassItable; | |
202 class itableMethodEntry; | |
203 | |
204 class itableOffsetEntry VALUE_OBJ_CLASS_SPEC { | |
205 private: | |
206 klassOop _interface; | |
207 int _offset; | |
208 public: | |
209 klassOop interface_klass() const { return _interface; } | |
210 int offset() const { return _offset; } | |
211 | |
212 static itableMethodEntry* method_entry(klassOop k, int offset) { return (itableMethodEntry*)(((address)k) + offset); } | |
213 itableMethodEntry* first_method_entry(klassOop k) { return method_entry(k, _offset); } | |
214 | |
215 void initialize(klassOop interf, int offset) { _interface = interf; _offset = offset; } | |
216 | |
217 // Static size and offset accessors | |
218 static int size() { return sizeof(itableOffsetEntry) / HeapWordSize; } // size in words | |
219 static int interface_offset_in_bytes() { return offset_of(itableOffsetEntry, _interface); } | |
220 static int offset_offset_in_bytes() { return offset_of(itableOffsetEntry, _offset); } | |
221 | |
222 friend class klassItable; | |
223 }; | |
224 | |
225 | |
226 class itableMethodEntry VALUE_OBJ_CLASS_SPEC { | |
227 private: | |
228 methodOop _method; | |
229 | |
230 public: | |
231 methodOop method() const { return _method; } | |
232 | |
233 void clear() { _method = NULL; } | |
234 | |
235 void initialize(methodOop method); | |
236 | |
237 // Static size and offset accessors | |
238 static int size() { return sizeof(itableMethodEntry) / HeapWordSize; } // size in words | |
239 static int method_offset_in_bytes() { return offset_of(itableMethodEntry, _method); } | |
240 | |
241 friend class klassItable; | |
242 }; | |
243 | |
244 // | |
245 // Format of an itable | |
246 // | |
247 // ---- offset table --- | |
248 // klassOop of interface 1 \ | |
249 // offset to vtable from start of oop / offset table entry | |
250 // ... | |
251 // klassOop of interface n \ | |
252 // offset to vtable from start of oop / offset table entry | |
253 // --- vtable for interface 1 --- | |
254 // methodOop \ | |
255 // compiler entry point / method table entry | |
256 // ... | |
257 // methodOop \ | |
258 // compiler entry point / method table entry | |
259 // -- vtable for interface 2 --- | |
260 // ... | |
261 // | |
262 class klassItable : public ResourceObj { | |
263 private: | |
264 instanceKlassHandle _klass; // my klass | |
265 int _table_offset; // offset of start of itable data within klass (in words) | |
266 int _size_offset_table; // size of offset table (in itableOffset entries) | |
267 int _size_method_table; // size of methodtable (in itableMethodEntry entries) | |
268 | |
269 void initialize_itable_for_interface(int method_table_offset, KlassHandle interf_h, bool checkconstraints, TRAPS); | |
270 public: | |
271 klassItable(instanceKlassHandle klass); | |
272 | |
273 itableOffsetEntry* offset_entry(int i) { assert(0 <= i && i <= _size_offset_table, "index out of bounds"); | |
274 return &((itableOffsetEntry*)vtable_start())[i]; } | |
275 | |
276 itableMethodEntry* method_entry(int i) { assert(0 <= i && i <= _size_method_table, "index out of bounds"); | |
277 return &((itableMethodEntry*)method_start())[i]; } | |
278 | |
16
f8236e79048a
6664627: Merge changes made only in hotspot 11 forward to jdk 7
dcubed
parents:
0
diff
changeset
|
279 int size_offset_table() { return _size_offset_table; } |
0 | 280 |
281 // Initialization | |
282 void initialize_itable(bool checkconstraints, TRAPS); | |
283 | |
284 // Updates | |
285 void initialize_with_method(methodOop m); | |
286 | |
287 // RedefineClasses() API support: | |
288 // if any entry of this itable points to any of old_methods, | |
289 // replace it with the corresponding new_method. | |
290 // trace_name_printed is set to true if the current call has | |
291 // printed the klass name so that other routines in the adjust_* | |
292 // group don't print the klass name. | |
293 void adjust_method_entries(methodOop* old_methods, methodOop* new_methods, | |
294 int methods_length, bool * trace_name_printed); | |
295 | |
296 // Garbage collection | |
297 void oop_follow_contents(); | |
298 void oop_adjust_pointers(); | |
299 | |
300 #ifndef SERIALGC | |
301 // Parallel Old | |
302 void oop_follow_contents(ParCompactionManager* cm); | |
303 void oop_update_pointers(ParCompactionManager* cm); | |
304 #endif // SERIALGC | |
305 | |
306 // Iterators | |
307 void oop_oop_iterate(OopClosure* blk); | |
308 void oop_oop_iterate_m(OopClosure* blk, MemRegion mr); | |
309 | |
310 // Setup of itable | |
311 static int compute_itable_size(objArrayHandle transitive_interfaces); | |
312 static void setup_itable_offset_table(instanceKlassHandle klass); | |
313 | |
314 // Resolving of method to index | |
315 static int compute_itable_index(methodOop m); | |
665
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
16
diff
changeset
|
316 // ...and back again: |
c89f86385056
6814659: separable cleanups and subroutines for 6655638
jrose
parents:
16
diff
changeset
|
317 static methodOop method_for_itable_index(klassOop klass, int itable_index); |
0 | 318 |
319 // Debugging/Statistics | |
320 static void print_statistics() PRODUCT_RETURN; | |
321 private: | |
322 intptr_t* vtable_start() const { return ((intptr_t*)_klass()) + _table_offset; } | |
323 intptr_t* method_start() const { return vtable_start() + _size_offset_table * itableOffsetEntry::size(); } | |
324 | |
325 // Helper methods | |
326 static int calc_itable_size(int num_interfaces, int num_methods) { return (num_interfaces * itableOffsetEntry::size()) + (num_methods * itableMethodEntry::size()); } | |
327 | |
328 // Statistics | |
329 NOT_PRODUCT(static int _total_classes;) // Total no. of classes with itables | |
330 NOT_PRODUCT(static long _total_size;) // Total no. of bytes used for itables | |
331 | |
332 static void update_stats(int size) PRODUCT_RETURN NOT_PRODUCT({ _total_classes++; _total_size += size; }) | |
333 }; | |
1972 | 334 |
335 #endif // SHARE_VM_OOPS_KLASSVTABLE_HPP |