hotspot source code - class file parse

Java 的版本号定义如下:

80818283848586878889909192939495
// Used for two backward compatibility reasons:// - to check for new additions to the class file format in JDK1.5// - to check for bug fixes in the format checker in JDK1.5#define JAVA_1_5_VERSION                  49// Used for backward compatibility reasons:// - to check for javac bug fixes that happened after 1.5// - also used as the max version when running in jdk6#define JAVA_6_VERSION                    50// Used for backward compatibility reasons:// - to check NameAndType_info signatures more aggressively#define JAVA_7_VERSION                    51// Extension method support.#define JAVA_8_VERSION                    52

Java7 常量池中新增加了3个常量类型,如InvokeDynamicMethodHandleMethodType,Java7 发布时 JVM 中新增加了一个指令invokedynamic,在常量池解析时就会碰到与这个指令直接相关的新增加的3个常量类型和新增加的属性BootstrapMethods

979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314
void ClassFileParser::parse_constant_pool_entries(int length, TRAPS) {  // Use a local copy of ClassFileStream. It helps the C++ compiler to optimize  // this function (_current can be allocated in a register, with scalar  // replacement of aggregates). The _current pointer is copied back to  // stream() when this function returns. DON'T call another method within  // this method that uses stream().  ClassFileStream* cfs0 = stream();  ClassFileStream cfs1 = *cfs0;  ClassFileStream* cfs = &cfs1;#ifdef ASSERT  assert(cfs->allocated_on_stack(),"should be local");  u1* old_current = cfs0->current();#endif  Handle class_loader(THREAD, _loader_data->class_loader());  // Used for batching symbol allocations.  const char* names[SymbolTable::symbol_alloc_batch_size];  int lengths[SymbolTable::symbol_alloc_batch_size];  int indices[SymbolTable::symbol_alloc_batch_size];  unsigned int hashValues[SymbolTable::symbol_alloc_batch_size];  int names_count = 0;  // parsing  Index 0 is unused  for (int index = 1; index < length; index++) {    // Each of the following case guarantees one more byte in the stream    // for the following tag or the access_flags following constant pool,    // so we don't need bounds-check for reading tag.    u1 tag = cfs->get_u1_fast();    switch (tag) {      case JVM_CONSTANT_Class :        {          cfs->guarantee_more(3, CHECK);  // name_index, tag/access_flags          u2 name_index = cfs->get_u2_fast();          _cp->klass_index_at_put(index, name_index);        }        break;      case JVM_CONSTANT_Fieldref :        {          cfs->guarantee_more(5, CHECK);  // class_index, name_and_type_index, tag/access_flags          u2 class_index = cfs->get_u2_fast();          u2 name_and_type_index = cfs->get_u2_fast();          _cp->field_at_put(index, class_index, name_and_type_index);        }        break;      case JVM_CONSTANT_Methodref :        {          cfs->guarantee_more(5, CHECK);  // class_index, name_and_type_index, tag/access_flags          u2 class_index = cfs->get_u2_fast();          u2 name_and_type_index = cfs->get_u2_fast();          _cp->method_at_put(index, class_index, name_and_type_index);        }        break;      case JVM_CONSTANT_InterfaceMethodref :        {          cfs->guarantee_more(5, CHECK);  // class_index, name_and_type_index, tag/access_flags          u2 class_index = cfs->get_u2_fast();          u2 name_and_type_index = cfs->get_u2_fast();          _cp->interface_method_at_put(index, class_index, name_and_type_index);        }        break;      case JVM_CONSTANT_String :        {          cfs->guarantee_more(3, CHECK);  // string_index, tag/access_flags          u2 string_index = cfs->get_u2_fast();          _cp->string_index_at_put(index, string_index);        }        break;      case JVM_CONSTANT_MethodHandle :      case JVM_CONSTANT_MethodType :        if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {          classfile_parse_error(            "Class file version does not support constant tag %u in class file %s",            tag, CHECK);        }        if (!EnableInvokeDynamic) {          classfile_parse_error(            "This JVM does not support constant tag %u in class file %s",            tag, CHECK);        }        if (tag == JVM_CONSTANT_MethodHandle) {          cfs->guarantee_more(4, CHECK);  // ref_kind, method_index, tag/access_flags          u1 ref_kind = cfs->get_u1_fast();          u2 method_index = cfs->get_u2_fast();          _cp->method_handle_index_at_put(index, ref_kind, method_index);        } else if (tag == JVM_CONSTANT_MethodType) {          cfs->guarantee_more(3, CHECK);  // signature_index, tag/access_flags          u2 signature_index = cfs->get_u2_fast();          _cp->method_type_index_at_put(index, signature_index);        } else {          ShouldNotReachHere();        }        break;      case JVM_CONSTANT_InvokeDynamic :        {          if (_major_version < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {            classfile_parse_error(              "Class file version does not support constant tag %u in class file %s",              tag, CHECK);          }          if (!EnableInvokeDynamic) {            classfile_parse_error(              "This JVM does not support constant tag %u in class file %s",              tag, CHECK);          }          cfs->guarantee_more(5, CHECK);  // bsm_index, nt, tag/access_flags          u2 bootstrap_specifier_index = cfs->get_u2_fast();          u2 name_and_type_index = cfs->get_u2_fast();          if (_max_bootstrap_specifier_index < (int) bootstrap_specifier_index)            _max_bootstrap_specifier_index = (int) bootstrap_specifier_index;  // collect for later          _cp->invoke_dynamic_at_put(index, bootstrap_specifier_index, name_and_type_index);        }        break;      case JVM_CONSTANT_Integer :        {          cfs->guarantee_more(5, CHECK);  // bytes, tag/access_flags          u4 bytes = cfs->get_u4_fast();          _cp->int_at_put(index, (jint) bytes);        }        break;      case JVM_CONSTANT_Float :        {          cfs->guarantee_more(5, CHECK);  // bytes, tag/access_flags          u4 bytes = cfs->get_u4_fast();          _cp->float_at_put(index, *(jfloat*)&bytes);        }        break;      case JVM_CONSTANT_Long :        // A mangled type might cause you to overrun allocated memory        guarantee_property(index+1 < length,                           "Invalid constant pool entry %u in class file %s",                           index, CHECK);        {          cfs->guarantee_more(9, CHECK);  // bytes, tag/access_flags          u8 bytes = cfs->get_u8_fast();          _cp->long_at_put(index, bytes);        }        index++;   // Skip entry following eigth-byte constant, see JVM book p. 98        break;      case JVM_CONSTANT_Double :        // A mangled type might cause you to overrun allocated memory        guarantee_property(index+1 < length,                           "Invalid constant pool entry %u in class file %s",                           index, CHECK);        {          cfs->guarantee_more(9, CHECK);  // bytes, tag/access_flags          u8 bytes = cfs->get_u8_fast();          _cp->double_at_put(index, *(jdouble*)&bytes);        }        index++;   // Skip entry following eigth-byte constant, see JVM book p. 98        break;      case JVM_CONSTANT_NameAndType :        {          cfs->guarantee_more(5, CHECK);  // name_index, signature_index, tag/access_flags          u2 name_index = cfs->get_u2_fast();          u2 signature_index = cfs->get_u2_fast();          _cp->name_and_type_at_put(index, name_index, signature_index);        }        break;      case JVM_CONSTANT_Utf8 :        {          cfs->guarantee_more(2, CHECK);  // utf8_length          u2  utf8_length = cfs->get_u2_fast();          u1* utf8_buffer = cfs->get_u1_buffer();          assert(utf8_buffer != NULL, "null utf8 buffer");          // Got utf8 string, guarantee utf8_length+1 bytes, set stream position forward.          cfs->guarantee_more(utf8_length+1, CHECK);  // utf8 string, tag/access_flags          cfs->skip_u1_fast(utf8_length);          // Before storing the symbol, make sure it's legal          if (_need_verify) {            verify_legal_utf8((unsigned char*)utf8_buffer, utf8_length, CHECK);          }          if (EnableInvokeDynamic && has_cp_patch_at(index)) {            Handle patch = clear_cp_patch_at(index);            guarantee_property(java_lang_String::is_instance(patch()),                               "Illegal utf8 patch at %d in class file %s",                               index, CHECK);            char* str = java_lang_String::as_utf8_string(patch());            // (could use java_lang_String::as_symbol instead, but might as well batch them)            utf8_buffer = (u1*) str;            utf8_length = (u2) strlen(str);          }          unsigned int hash;          Symbol* result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash);          if (result == NULL) {            names[names_count] = (char*)utf8_buffer;            lengths[names_count] = utf8_length;            indices[names_count] = index;            hashValues[names_count++] = hash;            if (names_count == SymbolTable::symbol_alloc_batch_size) {              SymbolTable::new_symbols(_loader_data, _cp, names_count, names, lengths, indices, hashValues, CHECK);              names_count = 0;            }          } else {            _cp->symbol_at_put(index, result);          }        }        break;      default:        classfile_parse_error(          "Unknown constant tag %u in class file %s", tag, CHECK);        break;    }  }  // Allocate the remaining symbols  if (names_count > 0) {    SymbolTable::new_symbols(_loader_data, _cp, names_count, names, lengths, indices, hashValues, CHECK);  }  // Copy _current pointer of local copy back to stream().#ifdef ASSERT  assert(cfs0->current() == old_current, "non-exclusive use of stream()");#endif  cfs0->set_current(cfs1.current());}

2807行关于BootstrapMethods属性相关的解析:

280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884
void ClassFileParser::parse_classfile_bootstrap_methods_attribute(u4 attribute_byte_length, TRAPS) {  ClassFileStream* cfs = stream();  u1* current_start = cfs->current();  guarantee_property(attribute_byte_length >= sizeof(u2),                     "Invalid BootstrapMethods attribute length %u in class file %s",                     attribute_byte_length,                     CHECK);  cfs->guarantee_more(attribute_byte_length, CHECK);  int attribute_array_length = cfs->get_u2_fast();  guarantee_property(_max_bootstrap_specifier_index < attribute_array_length,                     "Short length on BootstrapMethods in class file %s",                     CHECK);  // The attribute contains a counted array of counted tuples of shorts,  // represending bootstrap specifiers:  //    length*{bootstrap_method_index, argument_count*{argument_index}}  int operand_count = (attribute_byte_length - sizeof(u2)) / sizeof(u2);  // operand_count = number of shorts in attr, except for leading length  // The attribute is copied into a short[] array.  // The array begins with a series of short[2] pairs, one for each tuple.  int index_size = (attribute_array_length * 2);  Array<u2>* operands = MetadataFactory::new_array<u2>(_loader_data, index_size + operand_count, CHECK);  // Eagerly assign operands so they will be deallocated with the constant  // pool if there is an error.  _cp->set_operands(operands);  int operand_fill_index = index_size;  int cp_size = _cp->length();  for (int n = 0; n < attribute_array_length; n++) {    // Store a 32-bit offset into the header of the operand array.    ConstantPool::operand_offset_at_put(operands, n, operand_fill_index);    // Read a bootstrap specifier.    cfs->guarantee_more(sizeof(u2) * 2, CHECK);  // bsm, argc    u2 bootstrap_method_index = cfs->get_u2_fast();    u2 argument_count = cfs->get_u2_fast();    check_property(      valid_cp_range(bootstrap_method_index, cp_size) &&      _cp->tag_at(bootstrap_method_index).is_method_handle(),      "bootstrap_method_index %u has bad constant type in class file %s",      bootstrap_method_index,      CHECK);    guarantee_property((operand_fill_index + 1 + argument_count) < operands->length(),      "Invalid BootstrapMethods num_bootstrap_methods or num_bootstrap_arguments value in class file %s",      CHECK);    operands->at_put(operand_fill_index++, bootstrap_method_index);    operands->at_put(operand_fill_index++, argument_count);    cfs->guarantee_more(sizeof(u2) * argument_count, CHECK);  // argv[argc]    for (int j = 0; j < argument_count; j++) {      u2 argument_index = cfs->get_u2_fast();      check_property(        valid_cp_range(argument_index, cp_size) &&        _cp->tag_at(argument_index).is_loadable_constant(),        "argument_index %u has bad constant type in class file %s",        argument_index,        CHECK);      operands->at_put(operand_fill_index++, argument_index);    }  }  assert(operand_fill_index == operands->length(), "exact fill");  u1* current_end = cfs->current();  guarantee_property(current_end == current_start + attribute_byte_length,                     "Bad length on BootstrapMethods in class file %s",                     CHECK);}

vm/classfile/classFileParser.cpp3721行,查看ClassFileParser::parseClassFile方法,源码如下:

3721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973397439753976397739783979398039813982398339843985398639873988398939903991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060406140624063406440654066406740684069407040714072407340744075407640774078407940804081408240834084408540864087408840894090409140924093409440954096409740984099410041014102410341044105410641074108410941104111411241134114411541164117411841194120412141224123412441254126412741284129413041314132413341344135413641374138413941404141414241434144414541464147414841494150415141524153415441554156415741584159416041614162416341644165416641674168416941704171417241734174417541764177417841794180418141824183418441854186418741884189419041914192419341944195419641974198419942004201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270427142724273427442754276
instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,                                                    ClassLoaderData* loader_data,                                                    Handle protection_domain,                                                    KlassHandle host_klass,                                                    GrowableArray<Handle>* cp_patches,                                                    TempNewSymbol& parsed_name,                                                    bool verify,                                                    TRAPS) {  // When a retransformable agent is attached, JVMTI caches the  // class bytes that existed before the first retransformation.  // If RedefineClasses() was used before the retransformable  // agent attached, then the cached class bytes may not be the  // original class bytes.  JvmtiCachedClassFileData *cached_class_file = NULL;  Handle class_loader(THREAD, loader_data->class_loader());  bool has_default_methods = false;  bool declares_default_methods = false;  ResourceMark rm(THREAD);  ClassFileStream* cfs = stream();  // Timing  assert(THREAD->is_Java_thread(), "must be a JavaThread");  JavaThread* jt = (JavaThread*) THREAD;  PerfClassTraceTime ctimer(ClassLoader::perf_class_parse_time(),                            ClassLoader::perf_class_parse_selftime(),                            NULL,                            jt->get_thread_stat()->perf_recursion_counts_addr(),                            jt->get_thread_stat()->perf_timers_addr(),                            PerfClassTraceTime::PARSE_CLASS);  init_parsed_class_attributes(loader_data);  if (JvmtiExport::should_post_class_file_load_hook()) {    // Get the cached class file bytes (if any) from the class that    // is being redefined or retransformed. We use jvmti_thread_state()    // instead of JvmtiThreadState::state_for(jt) so we don't allocate    // a JvmtiThreadState any earlier than necessary. This will help    // avoid the bug described by 7126851.    JvmtiThreadState *state = jt->jvmti_thread_state();    if (state != NULL) {      KlassHandle *h_class_being_redefined =                     state->get_class_being_redefined();      if (h_class_being_redefined != NULL) {        instanceKlassHandle ikh_class_being_redefined =          instanceKlassHandle(THREAD, (*h_class_being_redefined)());        cached_class_file = ikh_class_being_redefined->get_cached_class_file();      }    }    unsigned char* ptr = cfs->buffer();    unsigned char* end_ptr = cfs->buffer() + cfs->length();    JvmtiExport::post_class_file_load_hook(name, class_loader(), protection_domain,                                           &ptr, &end_ptr, &cached_class_file);    if (ptr != cfs->buffer()) {      // JVMTI agent has modified class file data.      // Set new class file stream using JVMTI agent modified      // class file data.      cfs = new ClassFileStream(ptr, end_ptr - ptr, cfs->source());      set_stream(cfs);    }  }  _host_klass = host_klass;  _cp_patches = cp_patches;  instanceKlassHandle nullHandle;  // Figure out whether we can skip format checking (matching classic VM behavior)  if (DumpSharedSpaces) {    // verify == true means it's a 'remote' class (i.e., non-boot class)    // Verification decision is based on BytecodeVerificationRemote flag    // for those classes.    _need_verify = (verify) ? BytecodeVerificationRemote :                              BytecodeVerificationLocal;  } else {    _need_verify = Verifier::should_verify_for(class_loader(), verify);  }  // Set the verify flag in stream  cfs->set_verify(_need_verify);  // Save the class file name for easier error message printing.  _class_name = (name != NULL) ? name : vmSymbols::unknown_class_name();  cfs->guarantee_more(8, CHECK_(nullHandle));  // magic, major, minor  // Magic value  u4 magic = cfs->get_u4_fast();  guarantee_property(magic == JAVA_CLASSFILE_MAGIC,                     "Incompatible magic value %u in class file %s",                     magic, CHECK_(nullHandle));  // Version numbers  u2 minor_version = cfs->get_u2_fast();  u2 major_version = cfs->get_u2_fast();  if (DumpSharedSpaces && major_version < JAVA_1_5_VERSION) {    ResourceMark rm;    warning("Pre JDK 1.5 class not supported by CDS: %u.%u %s",            major_version,  minor_version, name->as_C_string());    Exceptions::fthrow(      THREAD_AND_LOCATION,      vmSymbols::java_lang_UnsupportedClassVersionError(),      "Unsupported major.minor version for dump time %u.%u",      major_version,      minor_version);  }  // Check version numbers - we check this even with verifier off  if (!is_supported_version(major_version, minor_version)) {    if (name == NULL) {      Exceptions::fthrow(        THREAD_AND_LOCATION,        vmSymbols::java_lang_UnsupportedClassVersionError(),        "Unsupported class file version %u.%u, "        "this version of the Java Runtime only recognizes class file versions up to %u.%u",        major_version,        minor_version,        JAVA_MAX_SUPPORTED_VERSION,        JAVA_MAX_SUPPORTED_MINOR_VERSION);    } else {      ResourceMark rm(THREAD);      Exceptions::fthrow(        THREAD_AND_LOCATION,        vmSymbols::java_lang_UnsupportedClassVersionError(),        "%s has been compiled by a more recent version of the Java Runtime (class file version %u.%u), "        "this version of the Java Runtime only recognizes class file versions up to %u.%u",        name->as_C_string(),        major_version,        minor_version,        JAVA_MAX_SUPPORTED_VERSION,        JAVA_MAX_SUPPORTED_MINOR_VERSION);    }    return nullHandle;  }  _major_version = major_version;  _minor_version = minor_version;  // Check if verification needs to be relaxed for this class file  // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376)  _relax_verify = Verifier::relax_verify_for(class_loader());  // Constant pool  constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle));  int cp_size = cp->length();  cfs->guarantee_more(8, CHECK_(nullHandle));  // flags, this_class, super_class, infs_len  // Access flags  AccessFlags access_flags;  jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_CLASS_MODIFIERS;  if ((flags & JVM_ACC_INTERFACE) && _major_version < JAVA_6_VERSION) {    // Set abstract bit for old class files for backward compatibility    flags |= JVM_ACC_ABSTRACT;  }  verify_legal_class_modifiers(flags, CHECK_(nullHandle));  access_flags.set_flags(flags);  // This class and superclass  u2 this_class_index = cfs->get_u2_fast();  check_property(    valid_cp_range(this_class_index, cp_size) &&      cp->tag_at(this_class_index).is_unresolved_klass(),    "Invalid this class index %u in constant pool in class file %s",    this_class_index, CHECK_(nullHandle));  Symbol*  class_name  = cp->unresolved_klass_at(this_class_index);  assert(class_name != NULL, "class_name can't be null");  // It's important to set parsed_name *before* resolving the super class.  // (it's used for cleanup by the caller if parsing fails)  parsed_name = class_name;  // parsed_name is returned and can be used if there's an error, so add to  // its reference count.  Caller will decrement the refcount.  parsed_name->increment_refcount();  // Update _class_name which could be null previously to be class_name  _class_name = class_name;  // Don't need to check whether this class name is legal or not.  // It has been checked when constant pool is parsed.  // However, make sure it is not an array type.  if (_need_verify) {    guarantee_property(class_name->byte_at(0) != JVM_SIGNATURE_ARRAY,                       "Bad class name in class file %s",                       CHECK_(nullHandle));  }  Klass* preserve_this_klass;   // for storing result across HandleMark  // release all handles when parsing is done  { HandleMark hm(THREAD);    // Checks if name in class file matches requested name    if (name != NULL && class_name != name) {      ResourceMark rm(THREAD);      Exceptions::fthrow(        THREAD_AND_LOCATION,        vmSymbols::java_lang_NoClassDefFoundError(),        "%s (wrong name: %s)",        name->as_C_string(),        class_name->as_C_string()      );      return nullHandle;    }    if (TraceClassLoadingPreorder) {      tty->print("[Loading %s", (name != NULL) ? name->as_klass_external_name() : "NoName");      if (cfs->source() != NULL) tty->print(" from %s", cfs->source());      tty->print_cr("]");    }#if INCLUDE_CDS    if (DumpLoadedClassList != NULL && cfs->source() != NULL && classlist_file->is_open()) {      // Only dump the classes that can be stored into CDS archive      if (SystemDictionaryShared::is_sharing_possible(loader_data)) {        if (name != NULL) {          ResourceMark rm(THREAD);          classlist_file->print_cr("%s", name->as_C_string());          classlist_file->flush();        }      }    }#endif    u2 super_class_index = cfs->get_u2_fast();    instanceKlassHandle super_klass = parse_super_class(super_class_index,                                                        CHECK_NULL);    // Interfaces    u2 itfs_len = cfs->get_u2_fast();    Array<Klass*>* local_interfaces =      parse_interfaces(itfs_len, protection_domain, _class_name,                       &has_default_methods, CHECK_(nullHandle));    u2 java_fields_count = 0;    // Fields (offsets are filled in later)    FieldAllocationCount fac;    Array<u2>* fields = parse_fields(class_name,                                     access_flags.is_interface(),                                     &fac, &java_fields_count,                                     CHECK_(nullHandle));    // Methods    bool has_final_method = false;    AccessFlags promoted_flags;    promoted_flags.set_flags(0);    Array<Method*>* methods = parse_methods(access_flags.is_interface(),                                            &promoted_flags,                                            &has_final_method,                                            &declares_default_methods,                                            CHECK_(nullHandle));    if (declares_default_methods) {      has_default_methods = true;    }    // Additional attributes    ClassAnnotationCollector parsed_annotations;    parse_classfile_attributes(&parsed_annotations, CHECK_(nullHandle));    // Finalize the Annotations metadata object,    // now that all annotation arrays have been created.    create_combined_annotations(CHECK_(nullHandle));    // Make sure this is the end of class file stream    guarantee_property(cfs->at_eos(), "Extra bytes at the end of class file %s", CHECK_(nullHandle));    if (_class_name == vmSymbols::java_lang_Object()) {      check_property(_local_interfaces == Universe::the_empty_klass_array(),                     "java.lang.Object cannot implement an interface in class file %s",                     CHECK_(nullHandle));    }    // We check super class after class file is parsed and format is checked    if (super_class_index > 0 && super_klass.is_null()) {      Symbol*  sk  = cp->klass_name_at(super_class_index);      if (access_flags.is_interface()) {        // Before attempting to resolve the superclass, check for class format        // errors not checked yet.        guarantee_property(sk == vmSymbols::java_lang_Object(),                           "Interfaces must have java.lang.Object as superclass in class file %s",                           CHECK_(nullHandle));      }      Klass* k = SystemDictionary::resolve_super_or_fail(class_name, sk,                                                         class_loader,                                                         protection_domain,                                                         true,                                                         CHECK_(nullHandle));      KlassHandle kh (THREAD, k);      super_klass = instanceKlassHandle(THREAD, kh());    }    if (super_klass.not_null()) {      if (super_klass->has_default_methods()) {        has_default_methods = true;      }      if (super_klass->is_interface()) {        ResourceMark rm(THREAD);        Exceptions::fthrow(          THREAD_AND_LOCATION,          vmSymbols::java_lang_IncompatibleClassChangeError(),          "class %s has interface %s as super class",          class_name->as_klass_external_name(),          super_klass->external_name()        );        return nullHandle;      }      // Make sure super class is not final      if (super_klass->is_final()) {        THROW_MSG_(vmSymbols::java_lang_VerifyError(), "Cannot inherit from final class", nullHandle);      }    }    // save super klass for error handling.    _super_klass = super_klass;    // Compute the transitive list of all unique interfaces implemented by this class    _transitive_interfaces =          compute_transitive_interfaces(super_klass, local_interfaces, CHECK_(nullHandle));    // sort methods    intArray* method_ordering = sort_methods(methods);    // promote flags from parse_methods() to the klass' flags    access_flags.add_promoted_flags(promoted_flags.as_int());    // Size of Java vtable (in words)    int vtable_size = 0;    int itable_size = 0;    int num_miranda_methods = 0;    GrowableArray<Method*> all_mirandas(20);    klassVtable::compute_vtable_size_and_num_mirandas(        &vtable_size, &num_miranda_methods, &all_mirandas, super_klass(), methods,        access_flags, class_loader, class_name, local_interfaces,                                                      CHECK_(nullHandle));    // Size of Java itable (in words)    itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(_transitive_interfaces);    FieldLayoutInfo info;    layout_fields(class_loader, &fac, &parsed_annotations, &info, CHECK_NULL);    int total_oop_map_size2 =          InstanceKlass::nonstatic_oop_map_size(info.total_oop_map_count);    // Compute reference type    ReferenceType rt;    if (super_klass() == NULL) {      rt = REF_NONE;    } else {      rt = super_klass->reference_type();    }    // We can now create the basic Klass* for this klass    _klass = InstanceKlass::allocate_instance_klass(loader_data,                                                    vtable_size,                                                    itable_size,                                                    info.static_field_size,                                                    total_oop_map_size2,                                                    rt,                                                    access_flags,                                                    name,                                                    super_klass(),                                                    !host_klass.is_null(),                                                    CHECK_(nullHandle));    instanceKlassHandle this_klass (THREAD, _klass);    assert(this_klass->static_field_size() == info.static_field_size, "sanity");    assert(this_klass->nonstatic_oop_map_count() == info.total_oop_map_count,           "sanity");    // Fill in information already parsed    this_klass->set_should_verify_class(verify);    jint lh = Klass::instance_layout_helper(info.instance_size, false);    this_klass->set_layout_helper(lh);    assert(this_klass->oop_is_instance(), "layout is correct");    assert(this_klass->size_helper() == info.instance_size, "correct size_helper");    // Not yet: supers are done below to support the new subtype-checking fields    //this_klass->set_super(super_klass());    this_klass->set_class_loader_data(loader_data);    this_klass->set_nonstatic_field_size(info.nonstatic_field_size);    this_klass->set_has_nonstatic_fields(info.has_nonstatic_fields);    this_klass->set_static_oop_field_count(fac.count[STATIC_OOP]);    apply_parsed_class_metadata(this_klass, java_fields_count, CHECK_NULL);    if (has_final_method) {      this_klass->set_has_final_method();    }    this_klass->copy_method_ordering(method_ordering, CHECK_NULL);    // The InstanceKlass::_methods_jmethod_ids cache    // is managed on the assumption that the initial cache    // size is equal to the number of methods in the class. If    // that changes, then InstanceKlass::idnum_can_increment()    // has to be changed accordingly.    this_klass->set_initial_method_idnum(methods->length());    this_klass->set_name(cp->klass_name_at(this_class_index));    if (is_anonymous())  // I am well known to myself      cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve    this_klass->set_minor_version(minor_version);    this_klass->set_major_version(major_version);    this_klass->set_has_default_methods(has_default_methods);    this_klass->set_declares_default_methods(declares_default_methods);    if (!host_klass.is_null()) {      assert (this_klass->is_anonymous(), "should be the same");      this_klass->set_host_klass(host_klass());    }    // Set up Method*::intrinsic_id as soon as we know the names of methods.    // (We used to do this lazily, but now we query it in Rewriter,    // which is eagerly done for every method, so we might as well do it now,    // when everything is fresh in memory.)    if (Method::klass_id_for_intrinsics(this_klass()) != vmSymbols::NO_SID) {      for (int j = 0; j < methods->length(); j++) {        methods->at(j)->init_intrinsic_id();      }    }    if (cached_class_file != NULL) {      // JVMTI: we have an InstanceKlass now, tell it about the cached bytes      this_klass->set_cached_class_file(cached_class_file);    }    // Fill in field values obtained by parse_classfile_attributes    if (parsed_annotations.has_any_annotations())      parsed_annotations.apply_to(this_klass);    apply_parsed_class_attributes(this_klass);    // Miranda methods    if ((num_miranda_methods > 0) ||        // if this class introduced new miranda methods or        (super_klass.not_null() && (super_klass->has_miranda_methods()))        // super class exists and this class inherited miranda methods        ) {      this_klass->set_has_miranda_methods(); // then set a flag    }    // Fill in information needed to compute superclasses.    this_klass->initialize_supers(super_klass(), CHECK_(nullHandle));    // Initialize itable offset tables    klassItable::setup_itable_offset_table(this_klass);    // Compute transitive closure of interfaces this class implements    // Do final class setup    fill_oop_maps(this_klass, info.nonstatic_oop_map_count, info.nonstatic_oop_offsets, info.nonstatic_oop_counts);    // Fill in has_finalizer, has_vanilla_constructor, and layout_helper    set_precomputed_flags(this_klass);    // reinitialize modifiers, using the InnerClasses attribute    int computed_modifiers = this_klass->compute_modifier_flags(CHECK_(nullHandle));    this_klass->set_modifier_flags(computed_modifiers);    // check if this class can access its super class    check_super_class_access(this_klass, CHECK_(nullHandle));    // check if this class can access its superinterfaces    check_super_interface_access(this_klass, CHECK_(nullHandle));    // check if this class overrides any final method    check_final_method_override(this_klass, CHECK_(nullHandle));    // check that if this class is an interface then it doesn't have static methods    if (this_klass->is_interface()) {      /* An interface in a JAVA 8 classfile can be static */      if (_major_version < JAVA_8_VERSION) {        check_illegal_static_method(this_klass, CHECK_(nullHandle));      }    }    // Allocate mirror and initialize static fields    java_lang_Class::create_mirror(this_klass, class_loader, protection_domain,                                   CHECK_(nullHandle));    // Generate any default methods - default methods are interface methods    // that have a default implementation.  This is new with Lambda project.    if (has_default_methods ) {      DefaultMethods::generate_default_methods(          this_klass(), &all_mirandas, CHECK_(nullHandle));    }    // Update the loader_data graph.    record_defined_class_dependencies(this_klass, CHECK_NULL);    ClassLoadingService::notify_class_loaded(InstanceKlass::cast(this_klass()),                                             false /* not shared class */);    if (TraceClassLoading) {      ResourceMark rm;      // print in a single call to reduce interleaving of output      if (cfs->source() != NULL) {        tty->print("[Loaded %s from %s]\n", this_klass->external_name(),                   cfs->source());      } else if (class_loader.is_null()) {        Klass* caller =            THREAD->is_Java_thread()                ? ((JavaThread*)THREAD)->security_get_caller_class(1)                : NULL;        // caller can be NULL, for example, during a JVMTI VM_Init hook        if (caller != NULL) {          tty->print("[Loaded %s by instance of %s]\n",                     this_klass->external_name(),                     InstanceKlass::cast(caller)->external_name());        } else {          tty->print("[Loaded %s]\n", this_klass->external_name());        }      } else {        tty->print("[Loaded %s from %s]\n", this_klass->external_name(),                   InstanceKlass::cast(class_loader->klass())->external_name());      }    }    if (TraceClassResolution) {      ResourceMark rm;      // print out the superclass.      const char * from = this_klass()->external_name();      if (this_klass->java_super() != NULL) {        tty->print("RESOLVE %s %s (super)\n", from, InstanceKlass::cast(this_klass->java_super())->external_name());      }      // print out each of the interface classes referred to by this class.      Array<Klass*>* local_interfaces = this_klass->local_interfaces();      if (local_interfaces != NULL) {        int length = local_interfaces->length();        for (int i = 0; i < length; i++) {          Klass* k = local_interfaces->at(i);          InstanceKlass* to_class = InstanceKlass::cast(k);          const char * to = to_class->external_name();          tty->print("RESOLVE %s %s (interface)\n", from, to);        }      }    }    // preserve result across HandleMark    preserve_this_klass = this_klass();  }  // Create new handle outside HandleMark (might be needed for  // Extended Class Redefinition)  instanceKlassHandle this_klass (THREAD, preserve_this_klass);  debug_only(this_klass->verify();)  // Clear class if no error has occurred so destructor doesn't deallocate it  _klass = NULL;  return this_klass;}

References

  1. vm/classfile/classFileParser.cpp