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// 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// Used for backward compatibility reasons:// - to check NameAndType_info signatures more aggressively// Extension method support. |
Java7 常量池中新增加了3个常量类型,如InvokeDynamic,MethodHandle和MethodType,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; assert(cfs->allocated_on_stack(),"should be local"); u1* old_current = cfs0->current(); 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(). assert(cfs0->current() == old_current, "non-exclusive use of stream()"); 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.cpp第3721行,查看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 (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(); } } } 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;} |