Path: blob/master/src/hotspot/share/classfile/classFileParser.hpp
40949 views
/*1* Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_CLASSFILE_CLASSFILEPARSER_HPP25#define SHARE_CLASSFILE_CLASSFILEPARSER_HPP2627#include "memory/referenceType.hpp"28#include "oops/annotations.hpp"29#include "oops/constantPool.hpp"30#include "oops/instanceKlass.hpp"31#include "oops/typeArrayOop.hpp"32#include "utilities/accessFlags.hpp"3334class Annotations;35template <typename T>36class Array;37class ClassFileStream;38class ClassLoaderData;39class ClassLoadInfo;40class ClassInstanceInfo;41class CompressedLineNumberWriteStream;42class ConstMethod;43class FieldInfo;44template <typename T>45class GrowableArray;46class InstanceKlass;47class RecordComponent;48class Symbol;49class TempNewSymbol;50class FieldLayoutBuilder;5152// Utility to collect and compact oop maps during layout53class OopMapBlocksBuilder : public ResourceObj {54public:55OopMapBlock* _nonstatic_oop_maps;56unsigned int _nonstatic_oop_map_count;57unsigned int _max_nonstatic_oop_maps;5859OopMapBlocksBuilder(unsigned int max_blocks);60OopMapBlock* last_oop_map() const;61void initialize_inherited_blocks(OopMapBlock* blocks, unsigned int nof_blocks);62void add(int offset, int count);63void copy(OopMapBlock* dst);64void compact();65void print_on(outputStream* st) const;66void print_value_on(outputStream* st) const;67};6869// Values needed for oopmap and InstanceKlass creation70class FieldLayoutInfo : public ResourceObj {71public:72OopMapBlocksBuilder* oop_map_blocks;73int _instance_size;74int _nonstatic_field_size;75int _static_field_size;76bool _has_nonstatic_fields;77};7879// Parser for for .class files80//81// The bytes describing the class file structure is read from a Stream object8283class ClassFileParser {84friend class FieldLayoutBuilder;85friend class FieldLayout;8687class ClassAnnotationCollector;88class FieldAllocationCount;89class FieldAnnotationCollector;9091public:92// The ClassFileParser has an associated "publicity" level93// It is used to control which subsystems (if any)94// will observe the parsing (logging, events, tracing).95// Default level is "BROADCAST", which is equivalent to96// a "public" parsing attempt.97//98// "INTERNAL" level should be entirely private to the99// caller - this allows for internal reuse of ClassFileParser100//101enum Publicity {102INTERNAL,103BROADCAST104};105106enum { LegalClass, LegalField, LegalMethod }; // used to verify unqualified names107108private:109// Potentially unaligned pointer to various 16-bit entries in the class file110typedef void unsafe_u2;111112const ClassFileStream* _stream; // Actual input stream113Symbol* _class_name;114mutable ClassLoaderData* _loader_data;115const bool _is_hidden;116const bool _can_access_vm_annotations;117int _orig_cp_size;118119// Metadata created before the instance klass is created. Must be deallocated120// if not transferred to the InstanceKlass upon successful class loading121// in which case these pointers have been set to NULL.122const InstanceKlass* _super_klass;123ConstantPool* _cp;124Array<u2>* _fields;125Array<Method*>* _methods;126Array<u2>* _inner_classes;127Array<u2>* _nest_members;128u2 _nest_host;129Array<u2>* _permitted_subclasses;130Array<RecordComponent*>* _record_components;131Array<InstanceKlass*>* _local_interfaces;132Array<InstanceKlass*>* _transitive_interfaces;133Annotations* _combined_annotations;134AnnotationArray* _class_annotations;135AnnotationArray* _class_type_annotations;136Array<AnnotationArray*>* _fields_annotations;137Array<AnnotationArray*>* _fields_type_annotations;138InstanceKlass* _klass; // InstanceKlass* once created.139InstanceKlass* _klass_to_deallocate; // an InstanceKlass* to be destroyed140141ClassAnnotationCollector* _parsed_annotations;142FieldAllocationCount* _fac;143FieldLayoutInfo* _field_info;144const intArray* _method_ordering;145GrowableArray<Method*>* _all_mirandas;146147enum { fixed_buffer_size = 128 };148u_char _linenumbertable_buffer[fixed_buffer_size];149150// Size of Java vtable (in words)151int _vtable_size;152int _itable_size;153154int _num_miranda_methods;155156ReferenceType _rt;157Handle _protection_domain;158AccessFlags _access_flags;159160// for tracing and notifications161Publicity _pub_level;162163// Used to keep track of whether a constant pool item 19 or 20 is found. These164// correspond to CONSTANT_Module and CONSTANT_Package tags and are not allowed165// in regular class files. For class file version >= 53, a CFE cannot be thrown166// immediately when these are seen because a NCDFE must be thrown if the class's167// access_flags have ACC_MODULE set. But, the access_flags haven't been looked168// at yet. So, the bad constant pool item is cached here. A value of zero169// means that no constant pool item 19 or 20 was found.170short _bad_constant_seen;171172// class attributes parsed before the instance klass is created:173bool _synthetic_flag;174int _sde_length;175const char* _sde_buffer;176u2 _sourcefile_index;177u2 _generic_signature_index;178179u2 _major_version;180u2 _minor_version;181u2 _this_class_index;182u2 _super_class_index;183u2 _itfs_len;184u2 _java_fields_count;185186bool _need_verify;187bool _relax_verify;188189bool _has_nonstatic_concrete_methods;190bool _declares_nonstatic_concrete_methods;191bool _has_final_method;192bool _has_contended_fields;193194// precomputed flags195bool _has_finalizer;196bool _has_empty_finalizer;197bool _has_vanilla_constructor;198int _max_bootstrap_specifier_index; // detects BSS values199200void parse_stream(const ClassFileStream* const stream, TRAPS);201202void mangle_hidden_class_name(InstanceKlass* const ik);203204void post_process_parsed_stream(const ClassFileStream* const stream,205ConstantPool* cp,206TRAPS);207208void fill_instance_klass(InstanceKlass* ik, bool cf_changed_in_CFLH,209const ClassInstanceInfo& cl_inst_info, TRAPS);210211void set_klass(InstanceKlass* instance);212213void set_class_bad_constant_seen(short bad_constant);214short class_bad_constant_seen() { return _bad_constant_seen; }215void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }216void set_class_sourcefile_index(u2 x) { _sourcefile_index = x; }217void set_class_generic_signature_index(u2 x) { _generic_signature_index = x; }218void set_class_sde_buffer(const char* x, int len) { _sde_buffer = x; _sde_length = len; }219220void create_combined_annotations(TRAPS);221void apply_parsed_class_attributes(InstanceKlass* k); // update k222void apply_parsed_class_metadata(InstanceKlass* k, int fields_count);223void clear_class_metadata();224225// Constant pool parsing226void parse_constant_pool_entries(const ClassFileStream* const stream,227ConstantPool* cp,228const int length,229TRAPS);230231void parse_constant_pool(const ClassFileStream* const cfs,232ConstantPool* const cp,233const int length,234TRAPS);235236// Interface parsing237void parse_interfaces(const ClassFileStream* const stream,238const int itfs_len,239ConstantPool* const cp,240bool* has_nonstatic_concrete_methods,241TRAPS);242243const InstanceKlass* parse_super_class(ConstantPool* const cp,244const int super_class_index,245const bool need_verify,246TRAPS);247248// Field parsing249void parse_field_attributes(const ClassFileStream* const cfs,250u2 attributes_count,251bool is_static,252u2 signature_index,253u2* const constantvalue_index_addr,254bool* const is_synthetic_addr,255u2* const generic_signature_index_addr,256FieldAnnotationCollector* parsed_annotations,257TRAPS);258259void parse_fields(const ClassFileStream* const cfs,260bool is_interface,261FieldAllocationCount* const fac,262ConstantPool* cp,263const int cp_size,264u2* const java_fields_count_ptr,265TRAPS);266267// Method parsing268Method* parse_method(const ClassFileStream* const cfs,269bool is_interface,270const ConstantPool* cp,271AccessFlags* const promoted_flags,272TRAPS);273274void parse_methods(const ClassFileStream* const cfs,275bool is_interface,276AccessFlags* const promoted_flags,277bool* const has_final_method,278bool* const declares_nonstatic_concrete_methods,279TRAPS);280281const unsafe_u2* parse_exception_table(const ClassFileStream* const stream,282u4 code_length,283u4 exception_table_length,284TRAPS);285286void parse_linenumber_table(u4 code_attribute_length,287u4 code_length,288CompressedLineNumberWriteStream**const write_stream,289TRAPS);290291const unsafe_u2* parse_localvariable_table(const ClassFileStream* const cfs,292u4 code_length,293u2 max_locals,294u4 code_attribute_length,295u2* const localvariable_table_length,296bool isLVTT,297TRAPS);298299const unsafe_u2* parse_checked_exceptions(const ClassFileStream* const cfs,300u2* const checked_exceptions_length,301u4 method_attribute_length,302TRAPS);303304// Classfile attribute parsing305u2 parse_generic_signature_attribute(const ClassFileStream* const cfs, TRAPS);306void parse_classfile_sourcefile_attribute(const ClassFileStream* const cfs, TRAPS);307void parse_classfile_source_debug_extension_attribute(const ClassFileStream* const cfs,308int length,309TRAPS);310311// Check for circularity in InnerClasses attribute.312bool check_inner_classes_circularity(const ConstantPool* cp, int length, TRAPS);313314u2 parse_classfile_inner_classes_attribute(const ClassFileStream* const cfs,315const ConstantPool* cp,316const u1* const inner_classes_attribute_start,317bool parsed_enclosingmethod_attribute,318u2 enclosing_method_class_index,319u2 enclosing_method_method_index,320TRAPS);321322u2 parse_classfile_nest_members_attribute(const ClassFileStream* const cfs,323const u1* const nest_members_attribute_start,324TRAPS);325326u2 parse_classfile_permitted_subclasses_attribute(const ClassFileStream* const cfs,327const u1* const permitted_subclasses_attribute_start,328TRAPS);329330u2 parse_classfile_record_attribute(const ClassFileStream* const cfs,331const ConstantPool* cp,332const u1* const record_attribute_start,333TRAPS);334335void parse_classfile_attributes(const ClassFileStream* const cfs,336ConstantPool* cp,337ClassAnnotationCollector* parsed_annotations,338TRAPS);339340void parse_classfile_synthetic_attribute();341void parse_classfile_signature_attribute(const ClassFileStream* const cfs, TRAPS);342void parse_classfile_bootstrap_methods_attribute(const ClassFileStream* const cfs,343ConstantPool* cp,344u4 attribute_length,345TRAPS);346347// Annotations handling348AnnotationArray* assemble_annotations(const u1* const runtime_visible_annotations,349int runtime_visible_annotations_length,350const u1* const runtime_invisible_annotations,351int runtime_invisible_annotations_length,352TRAPS);353354void set_precomputed_flags(InstanceKlass* k);355356// Format checker methods357void classfile_parse_error(const char* msg, TRAPS) const;358void classfile_parse_error(const char* msg, int index, TRAPS) const;359void classfile_parse_error(const char* msg, const char *name, TRAPS) const;360void classfile_parse_error(const char* msg,361int index,362const char *name,363TRAPS) const;364void classfile_parse_error(const char* msg,365const char* name,366const char* signature,367TRAPS) const;368369void classfile_icce_error(const char* msg,370const Klass* k,371TRAPS) const;372373void classfile_ucve_error(const char* msg,374const Symbol* class_name,375u2 major,376u2 minor,377TRAPS) const;378379inline void guarantee_property(bool b, const char* msg, TRAPS) const {380if (!b) { classfile_parse_error(msg, THREAD); return; }381}382383void report_assert_property_failure(const char* msg, TRAPS) const PRODUCT_RETURN;384void report_assert_property_failure(const char* msg, int index, TRAPS) const PRODUCT_RETURN;385386inline void assert_property(bool b, const char* msg, TRAPS) const {387#ifdef ASSERT388if (!b) {389report_assert_property_failure(msg, THREAD);390}391#endif392}393394inline void assert_property(bool b, const char* msg, int index, TRAPS) const {395#ifdef ASSERT396if (!b) {397report_assert_property_failure(msg, index, THREAD);398}399#endif400}401402inline void check_property(bool property,403const char* msg,404int index,405TRAPS) const {406if (_need_verify) {407guarantee_property(property, msg, index, CHECK);408} else {409assert_property(property, msg, index, CHECK);410}411}412413inline void check_property(bool property, const char* msg, TRAPS) const {414if (_need_verify) {415guarantee_property(property, msg, CHECK);416} else {417assert_property(property, msg, CHECK);418}419}420421inline void guarantee_property(bool b,422const char* msg,423int index,424TRAPS) const {425if (!b) { classfile_parse_error(msg, index, THREAD); return; }426}427428inline void guarantee_property(bool b,429const char* msg,430const char *name,431TRAPS) const {432if (!b) { classfile_parse_error(msg, name, THREAD); return; }433}434435inline void guarantee_property(bool b,436const char* msg,437int index,438const char *name,439TRAPS) const {440if (!b) { classfile_parse_error(msg, index, name, THREAD); return; }441}442443void throwIllegalSignature(const char* type,444const Symbol* name,445const Symbol* sig,446TRAPS) const;447448void verify_constantvalue(const ConstantPool* const cp,449int constantvalue_index,450int signature_index,451TRAPS) const;452453void verify_legal_utf8(const unsigned char* buffer, int length, TRAPS) const;454void verify_legal_class_name(const Symbol* name, TRAPS) const;455void verify_legal_field_name(const Symbol* name, TRAPS) const;456void verify_legal_method_name(const Symbol* name, TRAPS) const;457458void verify_legal_field_signature(const Symbol* fieldname,459const Symbol* signature,460TRAPS) const;461int verify_legal_method_signature(const Symbol* methodname,462const Symbol* signature,463TRAPS) const;464465void verify_class_version(u2 major, u2 minor, Symbol* class_name, TRAPS);466467void verify_legal_class_modifiers(jint flags, TRAPS) const;468void verify_legal_field_modifiers(jint flags, bool is_interface, TRAPS) const;469void verify_legal_method_modifiers(jint flags,470bool is_interface,471const Symbol* name,472TRAPS) const;473474void check_super_class_access(const InstanceKlass* this_klass,475TRAPS);476477void check_super_interface_access(const InstanceKlass* this_klass,478TRAPS);479480const char* skip_over_field_signature(const char* signature,481bool void_ok,482unsigned int length,483TRAPS) const;484485// Wrapper for constantTag.is_klass_[or_]reference.486// In older versions of the VM, Klass*s cannot sneak into early phases of487// constant pool construction, but in later versions they can.488// %%% Let's phase out the old is_klass_reference.489bool valid_klass_reference_at(int index) const {490return _cp->is_within_bounds(index) &&491_cp->tag_at(index).is_klass_or_reference();492}493494// Checks that the cpool index is in range and is a utf8495bool valid_symbol_at(int cpool_index) const {496return _cp->is_within_bounds(cpool_index) &&497_cp->tag_at(cpool_index).is_utf8();498}499500void copy_localvariable_table(const ConstMethod* cm,501int lvt_cnt,502u2* const localvariable_table_length,503const unsafe_u2** const localvariable_table_start,504int lvtt_cnt,505u2* const localvariable_type_table_length,506const unsafe_u2** const localvariable_type_table_start,507TRAPS);508509void copy_method_annotations(ConstMethod* cm,510const u1* runtime_visible_annotations,511int runtime_visible_annotations_length,512const u1* runtime_invisible_annotations,513int runtime_invisible_annotations_length,514const u1* runtime_visible_parameter_annotations,515int runtime_visible_parameter_annotations_length,516const u1* runtime_invisible_parameter_annotations,517int runtime_invisible_parameter_annotations_length,518const u1* runtime_visible_type_annotations,519int runtime_visible_type_annotations_length,520const u1* runtime_invisible_type_annotations,521int runtime_invisible_type_annotations_length,522const u1* annotation_default,523int annotation_default_length,524TRAPS);525526void update_class_name(Symbol* new_name);527528public:529ClassFileParser(ClassFileStream* stream,530Symbol* name,531ClassLoaderData* loader_data,532const ClassLoadInfo* cl_info,533Publicity pub_level,534TRAPS);535536~ClassFileParser();537538InstanceKlass* create_instance_klass(bool cf_changed_in_CFLH, const ClassInstanceInfo& cl_inst_info, TRAPS);539540const ClassFileStream* clone_stream() const;541542void set_klass_to_deallocate(InstanceKlass* klass);543544int static_field_size() const;545int total_oop_map_count() const;546jint layout_size() const;547548int vtable_size() const { return _vtable_size; }549int itable_size() const { return _itable_size; }550551u2 this_class_index() const { return _this_class_index; }552553bool is_hidden() const { return _is_hidden; }554bool is_interface() const { return _access_flags.is_interface(); }555556ClassLoaderData* loader_data() const { return _loader_data; }557const Symbol* class_name() const { return _class_name; }558const InstanceKlass* super_klass() const { return _super_klass; }559560ReferenceType reference_type() const { return _rt; }561AccessFlags access_flags() const { return _access_flags; }562563bool is_internal() const { return INTERNAL == _pub_level; }564565static bool verify_unqualified_name(const char* name, unsigned int length, int type);566567#ifdef ASSERT568static bool is_internal_format(Symbol* class_name);569#endif570571};572573#endif // SHARE_CLASSFILE_CLASSFILEPARSER_HPP574575576