comparison src/share/vm/oops/klassVtable.hpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 8ce625481709
children d8ce2825b193
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
1 /* 1 /*
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. 2 * Copyright (c) 1997, 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 * 4 *
5 * This code is free software; you can redistribute it and/or modify it 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 6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. 7 * published by the Free Software Foundation.
28 #include "memory/allocation.hpp" 28 #include "memory/allocation.hpp"
29 #include "oops/oopsHierarchy.hpp" 29 #include "oops/oopsHierarchy.hpp"
30 #include "runtime/handles.hpp" 30 #include "runtime/handles.hpp"
31 #include "utilities/growableArray.hpp" 31 #include "utilities/growableArray.hpp"
32 32
33 // A klassVtable abstracts the variable-length vtable that is embedded in instanceKlass 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, 34 // and arrayKlass. klassVtable objects are used just as convenient transient accessors to the vtable,
35 // not to actually hold the vtable data. 35 // not to actually hold the vtable data.
36 // Note: the klassVtable should not be accessed before the class has been verified 36 // Note: the klassVtable should not be accessed before the class has been verified
37 // (until that point, the vtable is uninitialized). 37 // (until that point, the vtable is uninitialized).
38 38
63 63
64 // accessors 64 // accessors
65 vtableEntry* table() const { return (vtableEntry*)(address(_klass()) + _tableOffset); } 65 vtableEntry* table() const { return (vtableEntry*)(address(_klass()) + _tableOffset); }
66 KlassHandle klass() const { return _klass; } 66 KlassHandle klass() const { return _klass; }
67 int length() const { return _length; } 67 int length() const { return _length; }
68 inline methodOop method_at(int i) const; 68 inline Method* method_at(int i) const;
69 inline methodOop unchecked_method_at(int i) const; 69 inline Method* unchecked_method_at(int i) const;
70 inline oop* adr_method_at(int i) const; 70 inline Method** adr_method_at(int i) const;
71 71
72 // searching; all methods return -1 if not found 72 // searching; all methods return -1 if not found
73 int index_of(methodOop m) const { return index_of(m, _length); } 73 int index_of(Method* m) const { return index_of(m, _length); }
74 int index_of_miranda(Symbol* name, Symbol* signature); 74 int index_of_miranda(Symbol* name, Symbol* signature);
75 75
76 void initialize_vtable(bool checkconstraints, TRAPS); // initialize vtable of a new klass 76 void initialize_vtable(bool checkconstraints, TRAPS); // initialize vtable of a new klass
77 77
78 // CDS/RedefineClasses support - clear vtables so they can be reinitialized 78 // CDS/RedefineClasses support - clear vtables so they can be reinitialized
83 void clear_vtable(); 83 void clear_vtable();
84 bool is_initialized(); 84 bool is_initialized();
85 85
86 // computes vtable length (in words) and the number of miranda methods 86 // computes vtable length (in words) and the number of miranda methods
87 static void compute_vtable_size_and_num_mirandas(int &vtable_length, int &num_miranda_methods, 87 static void compute_vtable_size_and_num_mirandas(int &vtable_length, int &num_miranda_methods,
88 klassOop super, objArrayOop methods, 88 Klass* super, Array<Method*>* methods,
89 AccessFlags class_flags, Handle classloader, 89 AccessFlags class_flags, Handle classloader,
90 Symbol* classname, objArrayOop local_interfaces, 90 Symbol* classname, Array<Klass*>* local_interfaces,
91 TRAPS); 91 TRAPS);
92 92
93 // RedefineClasses() API support: 93 // RedefineClasses() API support:
94 // If any entry of this vtable points to any of old_methods, 94 // If any entry of this vtable points to any of old_methods,
95 // replace it with the corresponding new_method. 95 // replace it with the corresponding new_method.
96 // trace_name_printed is set to true if the current call has 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_* 97 // printed the klass name so that other routines in the adjust_*
98 // group don't print the klass name. 98 // group don't print the klass name.
99 void adjust_method_entries(methodOop* old_methods, methodOop* new_methods, 99 void adjust_method_entries(Method** old_methods, Method** new_methods,
100 int methods_length, bool * trace_name_printed); 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 101
116 // Debugging code 102 // Debugging code
117 void print() PRODUCT_RETURN; 103 void print() PRODUCT_RETURN;
118 void verify(outputStream* st, bool force = false); 104 void verify(outputStream* st, bool force = false);
119 static void print_statistics() PRODUCT_RETURN; 105 static void print_statistics() PRODUCT_RETURN;
127 friend class vtableEntry; 113 friend class vtableEntry;
128 private: 114 private:
129 enum { VTABLE_TRANSITIVE_OVERRIDE_VERSION = 51 } ; 115 enum { VTABLE_TRANSITIVE_OVERRIDE_VERSION = 51 } ;
130 void copy_vtable_to(vtableEntry* start); 116 void copy_vtable_to(vtableEntry* start);
131 int initialize_from_super(KlassHandle super); 117 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 118 int index_of(Method* m, int len) const; // same as index_of, but search only up to len
133 void put_method_at(methodOop m, int index); 119 void put_method_at(Method* m, int index);
134 static bool needs_new_vtable_entry(methodHandle m, klassOop super, Handle classloader, Symbol* classname, AccessFlags access_flags, TRAPS); 120 static bool needs_new_vtable_entry(methodHandle m, Klass* super, Handle classloader, Symbol* classname, AccessFlags access_flags, TRAPS);
135 121
136 bool update_inherited_vtable(instanceKlass* klass, methodHandle target_method, int super_vtable_len, bool checkconstraints, TRAPS); 122 bool update_inherited_vtable(InstanceKlass* klass, methodHandle target_method, int super_vtable_len, bool checkconstraints, TRAPS);
137 instanceKlass* find_transitive_override(instanceKlass* initialsuper, methodHandle target_method, int vtable_index, 123 InstanceKlass* find_transitive_override(InstanceKlass* initialsuper, methodHandle target_method, int vtable_index,
138 Handle target_loader, Symbol* target_classname, Thread* THREAD); 124 Handle target_loader, Symbol* target_classname, Thread* THREAD);
139 125
140 // support for miranda methods 126 // support for miranda methods
141 bool is_miranda_entry_at(int i); 127 bool is_miranda_entry_at(int i);
142 void fill_in_mirandas(int& initialized); 128 void fill_in_mirandas(int& initialized);
143 static bool is_miranda(methodOop m, objArrayOop class_methods, klassOop super); 129 static bool is_miranda(Method* m, Array<Method*>* class_methods, Klass* super);
144 static void add_new_mirandas_to_list(GrowableArray<methodOop>* list_of_current_mirandas, objArrayOop current_interface_methods, objArrayOop class_methods, klassOop super); 130 static void add_new_mirandas_to_list(GrowableArray<Method*>* list_of_current_mirandas, Array<Method*>* current_interface_methods, Array<Method*>* class_methods, Klass* super);
145 static void get_mirandas(GrowableArray<methodOop>* mirandas, klassOop super, objArrayOop class_methods, objArrayOop local_interfaces); 131 static void get_mirandas(GrowableArray<Method*>* mirandas, Klass* super, Array<Method*>* class_methods, Array<Klass*>* local_interfaces);
146 static int get_num_mirandas(klassOop super, objArrayOop class_methods, objArrayOop local_interfaces); 132 static int get_num_mirandas(Klass* super, Array<Method*>* class_methods, Array<Klass*>* local_interfaces);
147 133
148 134
149 void verify_against(outputStream* st, klassVtable* vt, int index); 135 void verify_against(outputStream* st, klassVtable* vt, int index);
150 inline instanceKlass* ik() const; 136 inline InstanceKlass* ik() const;
151 }; 137 };
152 138
153 139
154 // private helper class for klassVtable 140 // private helper class for klassVtable
155 // description of entry points: 141 // description of entry points:
164 // size in words 150 // size in words
165 static int size() { 151 static int size() {
166 return sizeof(vtableEntry) / sizeof(HeapWord); 152 return sizeof(vtableEntry) / sizeof(HeapWord);
167 } 153 }
168 static int method_offset_in_bytes() { return offset_of(vtableEntry, _method); } 154 static int method_offset_in_bytes() { return offset_of(vtableEntry, _method); }
169 methodOop method() const { return _method; } 155 Method* method() const { return _method; }
170 156
171 private: 157 private:
172 methodOop _method; 158 Method* _method;
173 void set(methodOop method) { assert(method != NULL, "use clear"); _method = method; } 159 void set(Method* method) { assert(method != NULL, "use clear"); _method = method; }
174 void clear() { _method = NULL; } 160 void clear() { _method = NULL; }
175 void print() PRODUCT_RETURN; 161 void print() PRODUCT_RETURN;
176 void verify(klassVtable* vt, outputStream* st); 162 void verify(klassVtable* vt, outputStream* st);
177 163
178 friend class klassVtable; 164 friend class klassVtable;
179 }; 165 };
180 166
181 167
182 inline methodOop klassVtable::method_at(int i) const { 168 inline Method* klassVtable::method_at(int i) const {
183 assert(i >= 0 && i < _length, "index out of bounds"); 169 assert(i >= 0 && i < _length, "index out of bounds");
184 assert(table()[i].method() != NULL, "should not be null"); 170 assert(table()[i].method() != NULL, "should not be null");
185 assert(oop(table()[i].method())->is_method(), "should be method"); 171 assert(((Metadata*)table()[i].method())->is_method(), "should be method");
186 return table()[i].method(); 172 return table()[i].method();
187 } 173 }
188 174
189 inline methodOop klassVtable::unchecked_method_at(int i) const { 175 inline Method* klassVtable::unchecked_method_at(int i) const {
190 assert(i >= 0 && i < _length, "index out of bounds"); 176 assert(i >= 0 && i < _length, "index out of bounds");
191 return table()[i].method(); 177 return table()[i].method();
192 } 178 }
193 179
194 inline oop* klassVtable::adr_method_at(int i) const { 180 inline Method** klassVtable::adr_method_at(int i) const {
195 // Allow one past the last entry to be referenced; useful for loop bounds. 181 // Allow one past the last entry to be referenced; useful for loop bounds.
196 assert(i >= 0 && i <= _length, "index out of bounds"); 182 assert(i >= 0 && i <= _length, "index out of bounds");
197 return (oop*)(address(table() + i) + vtableEntry::method_offset_in_bytes()); 183 return (Method**)(address(table() + i) + vtableEntry::method_offset_in_bytes());
198 } 184 }
199 185
200 // -------------------------------------------------------------------------------- 186 // --------------------------------------------------------------------------------
201 class klassItable; 187 class klassItable;
202 class itableMethodEntry; 188 class itableMethodEntry;
203 189
204 class itableOffsetEntry VALUE_OBJ_CLASS_SPEC { 190 class itableOffsetEntry VALUE_OBJ_CLASS_SPEC {
205 private: 191 private:
206 klassOop _interface; 192 Klass* _interface;
207 int _offset; 193 int _offset;
208 public: 194 public:
209 klassOop interface_klass() const { return _interface; } 195 Klass* interface_klass() const { return _interface; }
210 int offset() const { return _offset; } 196 int offset() const { return _offset; }
211 197
212 static itableMethodEntry* method_entry(klassOop k, int offset) { return (itableMethodEntry*)(((address)k) + offset); } 198 static itableMethodEntry* method_entry(Klass* k, int offset) { return (itableMethodEntry*)(((address)k) + offset); }
213 itableMethodEntry* first_method_entry(klassOop k) { return method_entry(k, _offset); } 199 itableMethodEntry* first_method_entry(Klass* k) { return method_entry(k, _offset); }
214 200
215 void initialize(klassOop interf, int offset) { _interface = interf; _offset = offset; } 201 void initialize(Klass* interf, int offset) { _interface = interf; _offset = offset; }
216 202
217 // Static size and offset accessors 203 // Static size and offset accessors
218 static int size() { return sizeof(itableOffsetEntry) / HeapWordSize; } // size in words 204 static int size() { return sizeof(itableOffsetEntry) / HeapWordSize; } // size in words
219 static int interface_offset_in_bytes() { return offset_of(itableOffsetEntry, _interface); } 205 static int interface_offset_in_bytes() { return offset_of(itableOffsetEntry, _interface); }
220 static int offset_offset_in_bytes() { return offset_of(itableOffsetEntry, _offset); } 206 static int offset_offset_in_bytes() { return offset_of(itableOffsetEntry, _offset); }
223 }; 209 };
224 210
225 211
226 class itableMethodEntry VALUE_OBJ_CLASS_SPEC { 212 class itableMethodEntry VALUE_OBJ_CLASS_SPEC {
227 private: 213 private:
228 methodOop _method; 214 Method* _method;
229 215
230 public: 216 public:
231 methodOop method() const { return _method; } 217 Method* method() const { return _method; }
232 218
233 void clear() { _method = NULL; } 219 void clear() { _method = NULL; }
234 220
235 void initialize(methodOop method); 221 void initialize(Method* method);
236 222
237 // Static size and offset accessors 223 // Static size and offset accessors
238 static int size() { return sizeof(itableMethodEntry) / HeapWordSize; } // size in words 224 static int size() { return sizeof(itableMethodEntry) / HeapWordSize; } // size in words
239 static int method_offset_in_bytes() { return offset_of(itableMethodEntry, _method); } 225 static int method_offset_in_bytes() { return offset_of(itableMethodEntry, _method); }
240 226
243 229
244 // 230 //
245 // Format of an itable 231 // Format of an itable
246 // 232 //
247 // ---- offset table --- 233 // ---- offset table ---
248 // klassOop of interface 1 \ 234 // Klass* of interface 1 \
249 // offset to vtable from start of oop / offset table entry 235 // offset to vtable from start of oop / offset table entry
250 // ... 236 // ...
251 // klassOop of interface n \ 237 // Klass* of interface n \
252 // offset to vtable from start of oop / offset table entry 238 // offset to vtable from start of oop / offset table entry
253 // --- vtable for interface 1 --- 239 // --- vtable for interface 1 ---
254 // methodOop \ 240 // Method* \
255 // compiler entry point / method table entry 241 // compiler entry point / method table entry
256 // ... 242 // ...
257 // methodOop \ 243 // Method* \
258 // compiler entry point / method table entry 244 // compiler entry point / method table entry
259 // -- vtable for interface 2 --- 245 // -- vtable for interface 2 ---
260 // ... 246 // ...
261 // 247 //
262 class klassItable : public ResourceObj { 248 class klassItable : public ResourceObj {
280 266
281 // Initialization 267 // Initialization
282 void initialize_itable(bool checkconstraints, TRAPS); 268 void initialize_itable(bool checkconstraints, TRAPS);
283 269
284 // Updates 270 // Updates
285 void initialize_with_method(methodOop m); 271 void initialize_with_method(Method* m);
286 272
287 // RedefineClasses() API support: 273 // RedefineClasses() API support:
288 // if any entry of this itable points to any of old_methods, 274 // if any entry of this itable points to any of old_methods,
289 // replace it with the corresponding new_method. 275 // replace it with the corresponding new_method.
290 // trace_name_printed is set to true if the current call has 276 // trace_name_printed is set to true if the current call has
291 // printed the klass name so that other routines in the adjust_* 277 // printed the klass name so that other routines in the adjust_*
292 // group don't print the klass name. 278 // group don't print the klass name.
293 void adjust_method_entries(methodOop* old_methods, methodOop* new_methods, 279 void adjust_method_entries(Method** old_methods, Method** new_methods,
294 int methods_length, bool * trace_name_printed); 280 int methods_length, bool * trace_name_printed);
295 281
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 282 // Setup of itable
311 static int compute_itable_size(objArrayHandle transitive_interfaces); 283 static int compute_itable_size(Array<Klass*>* transitive_interfaces);
312 static void setup_itable_offset_table(instanceKlassHandle klass); 284 static void setup_itable_offset_table(instanceKlassHandle klass);
313 285
314 // Resolving of method to index 286 // Resolving of method to index
315 static int compute_itable_index(methodOop m); 287 static int compute_itable_index(Method* m);
316 // ...and back again: 288 // ...and back again:
317 static methodOop method_for_itable_index(klassOop klass, int itable_index); 289 static Method* method_for_itable_index(Klass* klass, int itable_index);
318 290
319 // Debugging/Statistics 291 // Debugging/Statistics
320 static void print_statistics() PRODUCT_RETURN; 292 static void print_statistics() PRODUCT_RETURN;
321 private: 293 private:
322 intptr_t* vtable_start() const { return ((intptr_t*)_klass()) + _table_offset; } 294 intptr_t* vtable_start() const { return ((intptr_t*)_klass()) + _table_offset; }
328 // Statistics 300 // Statistics
329 NOT_PRODUCT(static int _total_classes;) // Total no. of classes with itables 301 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 302 NOT_PRODUCT(static long _total_size;) // Total no. of bytes used for itables
331 303
332 static void update_stats(int size) PRODUCT_RETURN NOT_PRODUCT({ _total_classes++; _total_size += size; }) 304 static void update_stats(int size) PRODUCT_RETURN NOT_PRODUCT({ _total_classes++; _total_size += size; })
305
306 public:
307 #ifndef PRODUCT
308 bool check_no_old_entries();
309 #endif
333 }; 310 };
334 311
335 #endif // SHARE_VM_OOPS_KLASSVTABLE_HPP 312 #endif // SHARE_VM_OOPS_KLASSVTABLE_HPP