comparison src/share/vm/oops/klassVtable.hpp @ 6948:e522a00b91aa

Merge with http://hg.openjdk.java.net/hsx/hsx25/hotspot/ after NPG - C++ build works
author Doug Simon <doug.simon@oracle.com>
date Mon, 12 Nov 2012 23:14:12 +0100
parents 4735d2c84362
children 8d9fc28831cc
comparison
equal deleted inserted replaced
6711:ae13cc658b80 6948:e522a00b91aa
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
39 // Currently a klassVtable contains a direct reference to the vtable data, and is therefore 39 // Currently a klassVtable contains a direct reference to the vtable data, and is therefore
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
82 // is necessary. 82 // is necessary.
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(
88 klassOop super, objArrayOop methods, 88 int* vtable_length, int* num_new_mirandas,
89 AccessFlags class_flags, Handle classloader, 89 GrowableArray<Method*>* all_mirandas, Klass* super,
90 Symbol* classname, objArrayOop local_interfaces, 90 Array<Method*>* methods, AccessFlags class_flags, Handle classloader,
91 TRAPS); 91 Symbol* classname, Array<Klass*>* local_interfaces, 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_lists(
145 static void get_mirandas(GrowableArray<methodOop>* mirandas, klassOop super, objArrayOop class_methods, objArrayOop local_interfaces); 131 GrowableArray<Method*>* new_mirandas,
146 static int get_num_mirandas(klassOop super, objArrayOop class_methods, objArrayOop local_interfaces); 132 GrowableArray<Method*>* all_mirandas,
147 133 Array<Method*>* current_interface_methods, Array<Method*>* class_methods,
134 Klass* super);
135 static void get_mirandas(
136 GrowableArray<Method*>* new_mirandas,
137 GrowableArray<Method*>* all_mirandas, Klass* super,
138 Array<Method*>* class_methods, Array<Klass*>* local_interfaces);
148 139
149 void verify_against(outputStream* st, klassVtable* vt, int index); 140 void verify_against(outputStream* st, klassVtable* vt, int index);
150 inline instanceKlass* ik() const; 141 inline InstanceKlass* ik() const;
151 }; 142 };
152 143
153 144
154 // private helper class for klassVtable 145 // private helper class for klassVtable
155 // description of entry points: 146 // description of entry points:
164 // size in words 155 // size in words
165 static int size() { 156 static int size() {
166 return sizeof(vtableEntry) / sizeof(HeapWord); 157 return sizeof(vtableEntry) / sizeof(HeapWord);
167 } 158 }
168 static int method_offset_in_bytes() { return offset_of(vtableEntry, _method); } 159 static int method_offset_in_bytes() { return offset_of(vtableEntry, _method); }
169 methodOop method() const { return _method; } 160 Method* method() const { return _method; }
170 161
171 private: 162 private:
172 methodOop _method; 163 Method* _method;
173 void set(methodOop method) { assert(method != NULL, "use clear"); _method = method; } 164 void set(Method* method) { assert(method != NULL, "use clear"); _method = method; }
174 void clear() { _method = NULL; } 165 void clear() { _method = NULL; }
175 void print() PRODUCT_RETURN; 166 void print() PRODUCT_RETURN;
176 void verify(klassVtable* vt, outputStream* st); 167 void verify(klassVtable* vt, outputStream* st);
177 168
178 friend class klassVtable; 169 friend class klassVtable;
179 }; 170 };
180 171
181 172
182 inline methodOop klassVtable::method_at(int i) const { 173 inline Method* klassVtable::method_at(int i) const {
183 assert(i >= 0 && i < _length, "index out of bounds"); 174 assert(i >= 0 && i < _length, "index out of bounds");
184 assert(table()[i].method() != NULL, "should not be null"); 175 assert(table()[i].method() != NULL, "should not be null");
185 assert(oop(table()[i].method())->is_method(), "should be method"); 176 assert(((Metadata*)table()[i].method())->is_method(), "should be method");
186 return table()[i].method(); 177 return table()[i].method();
187 } 178 }
188 179
189 inline methodOop klassVtable::unchecked_method_at(int i) const { 180 inline Method* klassVtable::unchecked_method_at(int i) const {
190 assert(i >= 0 && i < _length, "index out of bounds"); 181 assert(i >= 0 && i < _length, "index out of bounds");
191 return table()[i].method(); 182 return table()[i].method();
192 } 183 }
193 184
194 inline oop* klassVtable::adr_method_at(int i) const { 185 inline Method** klassVtable::adr_method_at(int i) const {
195 // Allow one past the last entry to be referenced; useful for loop bounds. 186 // Allow one past the last entry to be referenced; useful for loop bounds.
196 assert(i >= 0 && i <= _length, "index out of bounds"); 187 assert(i >= 0 && i <= _length, "index out of bounds");
197 return (oop*)(address(table() + i) + vtableEntry::method_offset_in_bytes()); 188 return (Method**)(address(table() + i) + vtableEntry::method_offset_in_bytes());
198 } 189 }
199 190
200 // -------------------------------------------------------------------------------- 191 // --------------------------------------------------------------------------------
201 class klassItable; 192 class klassItable;
202 class itableMethodEntry; 193 class itableMethodEntry;
203 194
204 class itableOffsetEntry VALUE_OBJ_CLASS_SPEC { 195 class itableOffsetEntry VALUE_OBJ_CLASS_SPEC {
205 private: 196 private:
206 klassOop _interface; 197 Klass* _interface;
207 int _offset; 198 int _offset;
208 public: 199 public:
209 klassOop interface_klass() const { return _interface; } 200 Klass* interface_klass() const { return _interface; }
210 int offset() const { return _offset; } 201 int offset() const { return _offset; }
211 202
212 static itableMethodEntry* method_entry(klassOop k, int offset) { return (itableMethodEntry*)(((address)k) + offset); } 203 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); } 204 itableMethodEntry* first_method_entry(Klass* k) { return method_entry(k, _offset); }
214 205
215 void initialize(klassOop interf, int offset) { _interface = interf; _offset = offset; } 206 void initialize(Klass* interf, int offset) { _interface = interf; _offset = offset; }
216 207
217 // Static size and offset accessors 208 // Static size and offset accessors
218 static int size() { return sizeof(itableOffsetEntry) / HeapWordSize; } // size in words 209 static int size() { return sizeof(itableOffsetEntry) / HeapWordSize; } // size in words
219 static int interface_offset_in_bytes() { return offset_of(itableOffsetEntry, _interface); } 210 static int interface_offset_in_bytes() { return offset_of(itableOffsetEntry, _interface); }
220 static int offset_offset_in_bytes() { return offset_of(itableOffsetEntry, _offset); } 211 static int offset_offset_in_bytes() { return offset_of(itableOffsetEntry, _offset); }
223 }; 214 };
224 215
225 216
226 class itableMethodEntry VALUE_OBJ_CLASS_SPEC { 217 class itableMethodEntry VALUE_OBJ_CLASS_SPEC {
227 private: 218 private:
228 methodOop _method; 219 Method* _method;
229 220
230 public: 221 public:
231 methodOop method() const { return _method; } 222 Method* method() const { return _method; }
232 223
233 void clear() { _method = NULL; } 224 void clear() { _method = NULL; }
234 225
235 void initialize(methodOop method); 226 void initialize(Method* method);
236 227
237 // Static size and offset accessors 228 // Static size and offset accessors
238 static int size() { return sizeof(itableMethodEntry) / HeapWordSize; } // size in words 229 static int size() { return sizeof(itableMethodEntry) / HeapWordSize; } // size in words
239 static int method_offset_in_bytes() { return offset_of(itableMethodEntry, _method); } 230 static int method_offset_in_bytes() { return offset_of(itableMethodEntry, _method); }
240 231
243 234
244 // 235 //
245 // Format of an itable 236 // Format of an itable
246 // 237 //
247 // ---- offset table --- 238 // ---- offset table ---
248 // klassOop of interface 1 \ 239 // Klass* of interface 1 \
249 // offset to vtable from start of oop / offset table entry 240 // offset to vtable from start of oop / offset table entry
250 // ... 241 // ...
251 // klassOop of interface n \ 242 // Klass* of interface n \
252 // offset to vtable from start of oop / offset table entry 243 // offset to vtable from start of oop / offset table entry
253 // --- vtable for interface 1 --- 244 // --- vtable for interface 1 ---
254 // methodOop \ 245 // Method* \
255 // compiler entry point / method table entry 246 // compiler entry point / method table entry
256 // ... 247 // ...
257 // methodOop \ 248 // Method* \
258 // compiler entry point / method table entry 249 // compiler entry point / method table entry
259 // -- vtable for interface 2 --- 250 // -- vtable for interface 2 ---
260 // ... 251 // ...
261 // 252 //
262 class klassItable : public ResourceObj { 253 class klassItable : public ResourceObj {
280 271
281 // Initialization 272 // Initialization
282 void initialize_itable(bool checkconstraints, TRAPS); 273 void initialize_itable(bool checkconstraints, TRAPS);
283 274
284 // Updates 275 // Updates
285 void initialize_with_method(methodOop m); 276 void initialize_with_method(Method* m);
286 277
287 // RedefineClasses() API support: 278 // RedefineClasses() API support:
288 // if any entry of this itable points to any of old_methods, 279 // if any entry of this itable points to any of old_methods,
289 // replace it with the corresponding new_method. 280 // replace it with the corresponding new_method.
290 // trace_name_printed is set to true if the current call has 281 // trace_name_printed is set to true if the current call has
291 // printed the klass name so that other routines in the adjust_* 282 // printed the klass name so that other routines in the adjust_*
292 // group don't print the klass name. 283 // group don't print the klass name.
293 void adjust_method_entries(methodOop* old_methods, methodOop* new_methods, 284 void adjust_method_entries(Method** old_methods, Method** new_methods,
294 int methods_length, bool * trace_name_printed); 285 int methods_length, bool * trace_name_printed);
295 286
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 287 // Setup of itable
311 static int compute_itable_size(objArrayHandle transitive_interfaces); 288 static int compute_itable_size(Array<Klass*>* transitive_interfaces);
312 static void setup_itable_offset_table(instanceKlassHandle klass); 289 static void setup_itable_offset_table(instanceKlassHandle klass);
313 290
314 // Resolving of method to index 291 // Resolving of method to index
315 static int compute_itable_index(methodOop m); 292 static int compute_itable_index(Method* m);
316 // ...and back again: 293 // ...and back again:
317 static methodOop method_for_itable_index(klassOop klass, int itable_index); 294 static Method* method_for_itable_index(Klass* klass, int itable_index);
318 295
319 // Debugging/Statistics 296 // Debugging/Statistics
320 static void print_statistics() PRODUCT_RETURN; 297 static void print_statistics() PRODUCT_RETURN;
321 private: 298 private:
322 intptr_t* vtable_start() const { return ((intptr_t*)_klass()) + _table_offset; } 299 intptr_t* vtable_start() const { return ((intptr_t*)_klass()) + _table_offset; }
328 // Statistics 305 // Statistics
329 NOT_PRODUCT(static int _total_classes;) // Total no. of classes with itables 306 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 307 NOT_PRODUCT(static long _total_size;) // Total no. of bytes used for itables
331 308
332 static void update_stats(int size) PRODUCT_RETURN NOT_PRODUCT({ _total_classes++; _total_size += size; }) 309 static void update_stats(int size) PRODUCT_RETURN NOT_PRODUCT({ _total_classes++; _total_size += size; })
310
311 public:
312 #ifndef PRODUCT
313 bool check_no_old_entries();
314 #endif
333 }; 315 };
334 316
335 #endif // SHARE_VM_OOPS_KLASSVTABLE_HPP 317 #endif // SHARE_VM_OOPS_KLASSVTABLE_HPP