179 180 // private helper class for klassVtable 181 // description of entry points: 182 // destination is interpreted: 183 // from_compiled_code_entry_point -> c2iadapter 184 // from_interpreter_entry_point -> interpreter entry point 185 // destination is compiled: 186 // from_compiled_code_entry_point -> nmethod entry point 187 // from_interpreter_entry_point -> i2cadapter 188 class vtableEntry VALUE_OBJ_CLASS_SPEC { 189 friend class VMStructs; 190 friend class JVMCIVMStructs; 191 192 public: 193 // size in words 194 static int size() { return sizeof(vtableEntry) / wordSize; } 195 static int size_in_bytes() { return sizeof(vtableEntry); } 196 197 static int method_offset_in_bytes() { return offset_of(vtableEntry, _method); } 198 Method* method() const { return _method; } 199 200 private: 201 Method* _method; 202 void set(Method* method) { assert(method != NULL, "use clear"); _method = method; } 203 void clear() { _method = NULL; } 204 void print() PRODUCT_RETURN; 205 void verify(klassVtable* vt, outputStream* st); 206 207 friend class klassVtable; 208 }; 209 210 211 inline Method* klassVtable::method_at(int i) const { 212 assert(i >= 0 && i < _length, "index out of bounds"); 213 assert(table()[i].method() != NULL, "should not be null"); 214 assert(((Metadata*)table()[i].method())->is_method(), "should be method"); 215 return table()[i].method(); 216 } 217 218 inline Method* klassVtable::unchecked_method_at(int i) const { 219 assert(i >= 0 && i < _length, "index out of bounds"); 220 return table()[i].method(); 221 } 222 223 inline Method** klassVtable::adr_method_at(int i) const { 224 // Allow one past the last entry to be referenced; useful for loop bounds. 225 assert(i >= 0 && i <= _length, "index out of bounds"); 226 return (Method**)(address(table() + i) + vtableEntry::method_offset_in_bytes()); 227 } 228 229 // -------------------------------------------------------------------------------- 230 class klassItable; 231 class itableMethodEntry; 232 233 class itableOffsetEntry VALUE_OBJ_CLASS_SPEC { 234 private: 235 Klass* _interface; 236 int _offset; 237 public: 238 Klass* interface_klass() const { return _interface; } 239 int offset() const { return _offset; } 240 241 static itableMethodEntry* method_entry(Klass* k, int offset) { return (itableMethodEntry*)(((address)k) + offset); } 242 itableMethodEntry* first_method_entry(Klass* k) { return method_entry(k, _offset); } 243 244 void initialize(Klass* interf, int offset) { _interface = interf; _offset = offset; } 245 246 // Static size and offset accessors 247 static int size() { return sizeof(itableOffsetEntry) / wordSize; } // size in words 248 static int interface_offset_in_bytes() { return offset_of(itableOffsetEntry, _interface); } 249 static int offset_offset_in_bytes() { return offset_of(itableOffsetEntry, _offset); } 250 251 friend class klassItable; 252 }; 253 254 255 class itableMethodEntry VALUE_OBJ_CLASS_SPEC { 256 private: 257 Method* _method; 258 259 public: 260 Method* method() const { return _method; } 261 262 void clear() { _method = NULL; } 263 264 void initialize(Method* method); 265 266 // Static size and offset accessors 267 static int size() { return sizeof(itableMethodEntry) / wordSize; } // size in words 268 static int method_offset_in_bytes() { return offset_of(itableMethodEntry, _method); } 269 270 friend class klassItable; 271 }; 272 273 // 274 // Format of an itable 275 // 276 // ---- offset table --- 277 // Klass* of interface 1 \ 278 // offset to vtable from start of oop / offset table entry 279 // ... 280 // Klass* of interface n \ | 179 180 // private helper class for klassVtable 181 // description of entry points: 182 // destination is interpreted: 183 // from_compiled_code_entry_point -> c2iadapter 184 // from_interpreter_entry_point -> interpreter entry point 185 // destination is compiled: 186 // from_compiled_code_entry_point -> nmethod entry point 187 // from_interpreter_entry_point -> i2cadapter 188 class vtableEntry VALUE_OBJ_CLASS_SPEC { 189 friend class VMStructs; 190 friend class JVMCIVMStructs; 191 192 public: 193 // size in words 194 static int size() { return sizeof(vtableEntry) / wordSize; } 195 static int size_in_bytes() { return sizeof(vtableEntry); } 196 197 static int method_offset_in_bytes() { return offset_of(vtableEntry, _method); } 198 Method* method() const { return _method; } 199 Method** method_addr() { return &_method; } 200 201 private: 202 Method* _method; 203 void set(Method* method) { assert(method != NULL, "use clear"); _method = method; } 204 void clear() { _method = NULL; } 205 void print() PRODUCT_RETURN; 206 void verify(klassVtable* vt, outputStream* st); 207 208 friend class klassVtable; 209 }; 210 211 212 inline Method* klassVtable::method_at(int i) const { 213 assert(i >= 0 && i < _length, "index out of bounds"); 214 assert(table()[i].method() != NULL, "should not be null"); 215 assert(((Metadata*)table()[i].method())->is_method(), "should be method"); 216 return table()[i].method(); 217 } 218 219 inline Method* klassVtable::unchecked_method_at(int i) const { 220 assert(i >= 0 && i < _length, "index out of bounds"); 221 return table()[i].method(); 222 } 223 224 inline Method** klassVtable::adr_method_at(int i) const { 225 // Allow one past the last entry to be referenced; useful for loop bounds. 226 assert(i >= 0 && i <= _length, "index out of bounds"); 227 return (Method**)(address(table() + i) + vtableEntry::method_offset_in_bytes()); 228 } 229 230 // -------------------------------------------------------------------------------- 231 class klassItable; 232 class itableMethodEntry; 233 234 class itableOffsetEntry VALUE_OBJ_CLASS_SPEC { 235 private: 236 Klass* _interface; 237 int _offset; 238 public: 239 Klass* interface_klass() const { return _interface; } 240 Klass**interface_klass_addr() { return &_interface; } 241 int offset() const { return _offset; } 242 243 static itableMethodEntry* method_entry(Klass* k, int offset) { return (itableMethodEntry*)(((address)k) + offset); } 244 itableMethodEntry* first_method_entry(Klass* k) { return method_entry(k, _offset); } 245 246 void initialize(Klass* interf, int offset) { _interface = interf; _offset = offset; } 247 248 // Static size and offset accessors 249 static int size() { return sizeof(itableOffsetEntry) / wordSize; } // size in words 250 static int interface_offset_in_bytes() { return offset_of(itableOffsetEntry, _interface); } 251 static int offset_offset_in_bytes() { return offset_of(itableOffsetEntry, _offset); } 252 253 friend class klassItable; 254 }; 255 256 257 class itableMethodEntry VALUE_OBJ_CLASS_SPEC { 258 private: 259 Method* _method; 260 261 public: 262 Method* method() const { return _method; } 263 Method**method_addr() { return &_method; } 264 265 void clear() { _method = NULL; } 266 267 void initialize(Method* method); 268 269 // Static size and offset accessors 270 static int size() { return sizeof(itableMethodEntry) / wordSize; } // size in words 271 static int method_offset_in_bytes() { return offset_of(itableMethodEntry, _method); } 272 273 friend class klassItable; 274 }; 275 276 // 277 // Format of an itable 278 // 279 // ---- offset table --- 280 // Klass* of interface 1 \ 281 // offset to vtable from start of oop / offset table entry 282 // ... 283 // Klass* of interface n \ |