int arrayKlass::object_size(int header_size) const { // size of an array klass object assert(header_size <= instanceKlass::header_size(), "bad header size"); // If this assert fails, see comments in base_create_array_klass. header_size = instanceKlass::header_size(); #ifdef _LP64 int size = header_size + align_object_offset(vtable_length()); #else int size = header_size + vtable_length(); #endif return align_object_size(size); }
void ClassInfo::iterate_tables(OopROMVisitor* visitor) { int index = 0; if (vtable_length() > 0) { visitor->do_comment("Virtual dispatch table"); for (index = 0; index < vtable_length(); index++) { IndexableField field(index, true); visitor->do_oop(&field, vtable_offset_from_index(index), true); } } if (itable_length() > 0){ visitor->do_comment("Interface dispatch table"); for (index = 0; index < itable_length(); index++) { { InstanceClass ic = itable_interface_at(index); Symbol name = ic.name(); char buffer[1024]; jvm_sprintf(buffer, "interface klass_index "); name.string_copy(buffer + jvm_strlen(buffer), sizeof(buffer) - jvm_strlen(buffer)); NamedField field(buffer, true); visitor->do_int(&field, itable_offset_from_index(index), true); } { NamedField field("offset", true); visitor->do_int(&field, itable_offset_from_index(index) + sizeof(jint), true); } } for (index = 0; index < itable_length(); index++) { int offset = itable_offset_at(index); // Some ROM's interfaces that implement other interfaces set // offset=0, since this information is actually needed by // anyone. if (offset > 0) { InstanceClass ic = itable_interface_at(index); Symbol name = ic.name(); ObjArray methods = ic.methods(); const int buffer_size = 256; char buffer[256]; jvm_sprintf(buffer, "Table for interface #%d: ", index); name.string_copy(buffer + jvm_strlen(buffer), buffer_size- jvm_strlen(buffer)); visitor->do_comment(buffer); for (int i = 0; i < methods.length(); i ++) { IndexableField field(i, true); visitor->do_oop(&field, offset + i * sizeof(jobject), true); } } } } }
// Initialize a class on behalf of a task. // When entering here, the class may either be not initialized at all, or it // may be being initialized. // // If not initialized, a task mirror is created. // setup_java_mirror set the task mirror pointer in the task mirror table // of the class in "initializing" state. // set_initialized sets the task mirror pointer in "initialized" state. ReturnOop InstanceClass::initialize_for_task(JVM_SINGLE_ARG_TRAPS){ UsingFastOops fast_oops; TaskMirror::Fast tm; tm = task_mirror_desc(); if (TaskMirrorDesc::is_being_initialized_mirror((TaskMirrorDesc*)tm.obj())) { tm = TaskMirror::clinit_list_lookup(this); if (tm.is_null()) { // allocate Task mirror tm = setup_task_mirror(static_field_size(), vtable_length(), true JVM_CHECK_0); initialize_static_fields(&tm); } } else { return tm.obj(); } GUARANTEE(!tm.is_null(), "null task mirror"); JavaClassObj::Fast m = tm().real_java_mirror(); initialize_internal(Thread::current(), &m JVM_CHECK_0); return tm.obj(); }
klassVtable* arrayKlass::vtable() const { KlassHandle kh(Thread::current(), as_klassOop()); return new klassVtable(kh, start_of_vtable(), vtable_length() / vtableEntry::size()); }
// generate a map of all the field types in this object int ClassInfo::generate_fieldmap(TypeArray* field_map) { int map_index = 0; // (1) map the generic header // Obj Near map_index = Near::generate_fieldmap(field_map); //_object_size field_map->byte_at_put(map_index++, T_SHORT); //_vtable_length field_map->byte_at_put(map_index++, T_SHORT); //_itable_length field_map->byte_at_put(map_index++, T_SHORT); //_klass_index field_map->byte_at_put(map_index++, T_SHORT); //_name field_map->byte_at_put(map_index++, T_OBJECT); //_access_flags field_map->byte_at_put(map_index++, T_INT); // (2) Map the fields specific to array or instance int offset = generic_header_size(); if (is_array()) { //_type field_map->byte_at_put(map_index++, T_INT); offset += sizeof(int); //_scale; field_map->byte_at_put(map_index++, T_INT); offset += sizeof(int); // 2 dummies field_map->byte_at_put(map_index++, T_INT); field_map->byte_at_put(map_index++, T_INT); offset += 2 * sizeof(int); #if ENABLE_ISOLATES // 1 more dummy field_map->byte_at_put(map_index++, T_INT); offset += sizeof(int); #endif } else { // _methods field_map->byte_at_put(map_index++, T_OBJECT); offset += sizeof(jobject); // _fields field_map->byte_at_put(map_index++, T_OBJECT); offset += sizeof(jobject); #if ENABLE_ISOLATES // static_field size field_map->byte_at_put(map_index++, T_INT); offset += sizeof(int); #endif // _local_interfaces field_map->byte_at_put(map_index++, T_OBJECT); offset += sizeof(jobject); #if ENABLE_REFLECTION // _inner_classes field_map->byte_at_put(map_index++, T_OBJECT); offset += sizeof(jobject); #endif // _constants field_map->byte_at_put(map_index++, T_OBJECT); offset += sizeof(jobject); } while (offset < header_size()) { // C++ compiler may have added struct padding field_map->byte_at_put(map_index++, T_INT); offset += sizeof(jint); } // (3) Map the itable and vtable int i; // vtable for (i = 0; i < vtable_length(); i++) { field_map->byte_at_put(map_index++, T_OBJECT); offset += sizeof(jobject); } // itable for (i = 0; i < itable_length(); i++) { field_map->byte_at_put(map_index++, T_INT); // interface klass_index offset += sizeof(jint); field_map->byte_at_put(map_index++, T_INT); // method index offset += sizeof(int); } while (offset < itable_end_offset()) { field_map->byte_at_put(map_index++, T_OBJECT); // interface method offset += sizeof(jobject); } return map_index; }
int itable_offset_from_index(int index) { int itable_start = vtable_offset_from_index(vtable_length()); return itable_start + (index * (sizeof(int) + sizeof(int))); }