46 int _length; // length of vtable (number of entries) |
46 int _length; // length of vtable (number of entries) |
47 #ifndef PRODUCT |
47 #ifndef PRODUCT |
48 int _verify_count; // to make verify faster |
48 int _verify_count; // to make verify faster |
49 #endif |
49 #endif |
50 |
50 |
51 // Ordering important, so greater_than (>) can be used as an merge operator. |
|
52 enum AccessType { |
|
53 acc_private = 0, |
|
54 acc_package_private = 1, |
|
55 acc_publicprotected = 2 |
|
56 }; |
|
57 |
|
58 public: |
51 public: |
59 klassVtable(Klass* klass, void* base, int length) : _klass(klass) { |
52 klassVtable(Klass* klass, void* base, int length) : _klass(klass) { |
60 _tableOffset = (address)base - (address)klass; _length = length; |
53 _tableOffset = (address)base - (address)klass; _length = length; |
61 } |
54 } |
62 |
55 |
64 vtableEntry* table() const { return (vtableEntry*)(address(_klass) + _tableOffset); } |
57 vtableEntry* table() const { return (vtableEntry*)(address(_klass) + _tableOffset); } |
65 Klass* klass() const { return _klass; } |
58 Klass* klass() const { return _klass; } |
66 int length() const { return _length; } |
59 int length() const { return _length; } |
67 inline Method* method_at(int i) const; |
60 inline Method* method_at(int i) const; |
68 inline Method* unchecked_method_at(int i) const; |
61 inline Method* unchecked_method_at(int i) const; |
69 inline Method** adr_method_at(int i) const; |
|
70 |
62 |
71 // searching; all methods return -1 if not found |
63 // searching; all methods return -1 if not found |
72 int index_of(Method* m) const { return index_of(m, _length); } |
|
73 int index_of_miranda(Symbol* name, Symbol* signature); |
64 int index_of_miranda(Symbol* name, Symbol* signature); |
74 |
65 |
75 void initialize_vtable(bool checkconstraints, TRAPS); // initialize vtable of a new klass |
66 void initialize_vtable(bool checkconstraints, TRAPS); // initialize vtable of a new klass |
76 |
|
77 // CDS/RedefineClasses support - clear vtables so they can be reinitialized |
|
78 // at dump time. Clearing gives us an easy way to tell if the vtable has |
|
79 // already been reinitialized at dump time (see dump.cpp). Vtables can |
|
80 // be initialized at run time by RedefineClasses so dumping the right order |
|
81 // is necessary. |
|
82 void clear_vtable(); |
|
83 bool is_initialized(); |
|
84 |
67 |
85 // computes vtable length (in words) and the number of miranda methods |
68 // computes vtable length (in words) and the number of miranda methods |
86 static void compute_vtable_size_and_num_mirandas(int* vtable_length, |
69 static void compute_vtable_size_and_num_mirandas(int* vtable_length, |
87 int* num_new_mirandas, |
70 int* num_new_mirandas, |
88 GrowableArray<Method*>* all_mirandas, |
71 GrowableArray<Method*>* all_mirandas, |
123 enum { VTABLE_TRANSITIVE_OVERRIDE_VERSION = 51 } ; |
106 enum { VTABLE_TRANSITIVE_OVERRIDE_VERSION = 51 } ; |
124 |
107 |
125 private: |
108 private: |
126 void copy_vtable_to(vtableEntry* start); |
109 void copy_vtable_to(vtableEntry* start); |
127 int initialize_from_super(Klass* super); |
110 int initialize_from_super(Klass* super); |
128 int index_of(Method* m, int len) const; // same as index_of, but search only up to len |
|
129 void put_method_at(Method* m, int index); |
111 void put_method_at(Method* m, int index); |
130 static bool needs_new_vtable_entry(const methodHandle& m, |
112 static bool needs_new_vtable_entry(const methodHandle& m, |
131 const Klass* super, |
113 const Klass* super, |
132 Handle classloader, |
114 Handle classloader, |
133 Symbol* classname, |
115 Symbol* classname, |
221 inline Method* klassVtable::unchecked_method_at(int i) const { |
203 inline Method* klassVtable::unchecked_method_at(int i) const { |
222 assert(i >= 0 && i < _length, "index out of bounds"); |
204 assert(i >= 0 && i < _length, "index out of bounds"); |
223 return table()[i].method(); |
205 return table()[i].method(); |
224 } |
206 } |
225 |
207 |
226 inline Method** klassVtable::adr_method_at(int i) const { |
|
227 // Allow one past the last entry to be referenced; useful for loop bounds. |
|
228 assert(i >= 0 && i <= _length, "index out of bounds"); |
|
229 return (Method**)(address(table() + i) + vtableEntry::method_offset_in_bytes()); |
|
230 } |
|
231 |
|
232 // -------------------------------------------------------------------------------- |
208 // -------------------------------------------------------------------------------- |
233 class klassItable; |
209 class klassItable; |
234 class itableMethodEntry; |
210 class itableMethodEntry; |
235 |
211 |
236 class itableOffsetEntry { |
212 class itableOffsetEntry { |
331 static int assign_itable_indices_for_interface(InstanceKlass* klass, TRAPS); |
307 static int assign_itable_indices_for_interface(InstanceKlass* klass, TRAPS); |
332 static int method_count_for_interface(InstanceKlass* klass); |
308 static int method_count_for_interface(InstanceKlass* klass); |
333 static int compute_itable_size(Array<InstanceKlass*>* transitive_interfaces); |
309 static int compute_itable_size(Array<InstanceKlass*>* transitive_interfaces); |
334 static void setup_itable_offset_table(InstanceKlass* klass); |
310 static void setup_itable_offset_table(InstanceKlass* klass); |
335 |
311 |
336 // Resolving of method to index |
|
337 static Method* method_for_itable_index(InstanceKlass* klass, int itable_index); |
|
338 |
|
339 // Debugging/Statistics |
312 // Debugging/Statistics |
340 static void print_statistics() PRODUCT_RETURN; |
313 static void print_statistics() PRODUCT_RETURN; |
341 private: |
314 private: |
342 intptr_t* vtable_start() const { return ((intptr_t*)_klass) + _table_offset; } |
315 intptr_t* vtable_start() const { return ((intptr_t*)_klass) + _table_offset; } |
343 intptr_t* method_start() const { return vtable_start() + _size_offset_table * itableOffsetEntry::size(); } |
316 intptr_t* method_start() const { return vtable_start() + _size_offset_table * itableOffsetEntry::size(); } |