Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/classfile/classFileParser.hpp
32285 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_VM_CLASSFILE_CLASSFILEPARSER_HPP25#define SHARE_VM_CLASSFILE_CLASSFILEPARSER_HPP2627#include "classfile/classFileStream.hpp"28#include "memory/resourceArea.hpp"29#include "oops/oop.inline.hpp"30#include "oops/typeArrayOop.hpp"31#include "runtime/handles.inline.hpp"32#include "utilities/accessFlags.hpp"33#include "classfile/symbolTable.hpp"3435class FieldAllocationCount;36class FieldLayoutInfo;373839// Parser for for .class files40//41// The bytes describing the class file structure is read from a Stream object4243class ClassFileParser VALUE_OBJ_CLASS_SPEC {44private:45bool _need_verify;46bool _relax_verify;47u2 _major_version;48u2 _minor_version;49u2 _this_class_index;50Symbol* _class_name;51ClassLoaderData* _loader_data;52KlassHandle _host_klass;53GrowableArray<Handle>* _cp_patches; // overrides for CP entries5455// precomputed flags56bool _has_finalizer;57bool _has_empty_finalizer;58bool _has_vanilla_constructor;59int _max_bootstrap_specifier_index; // detects BSS values6061// class attributes parsed before the instance klass is created:62bool _synthetic_flag;63int _sde_length;64char* _sde_buffer;65u2 _sourcefile_index;66u2 _generic_signature_index;6768// Metadata created before the instance klass is created. Must be deallocated69// if not transferred to the InstanceKlass upon successful class loading70// in which case these pointers have been set to NULL.71instanceKlassHandle _super_klass;72ConstantPool* _cp;73Array<u2>* _fields;74Array<Method*>* _methods;75Array<u2>* _inner_classes;76Array<Klass*>* _local_interfaces;77Array<Klass*>* _transitive_interfaces;78Annotations* _combined_annotations;79AnnotationArray* _annotations;80AnnotationArray* _type_annotations;81Array<AnnotationArray*>* _fields_annotations;82Array<AnnotationArray*>* _fields_type_annotations;83InstanceKlass* _klass; // InstanceKlass once created.8485void set_class_synthetic_flag(bool x) { _synthetic_flag = x; }86void set_class_sourcefile_index(u2 x) { _sourcefile_index = x; }87void set_class_generic_signature_index(u2 x) { _generic_signature_index = x; }88void set_class_sde_buffer(char* x, int len) { _sde_buffer = x; _sde_length = len; }8990void create_combined_annotations(TRAPS);9192void init_parsed_class_attributes(ClassLoaderData* loader_data) {93_loader_data = loader_data;94_synthetic_flag = false;95_sourcefile_index = 0;96_generic_signature_index = 0;97_sde_buffer = NULL;98_sde_length = 0;99// initialize the other flags too:100_has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;101_max_bootstrap_specifier_index = -1;102clear_class_metadata();103_klass = NULL;104}105void apply_parsed_class_attributes(instanceKlassHandle k); // update k106void apply_parsed_class_metadata(instanceKlassHandle k, int fields_count, TRAPS);107void clear_class_metadata() {108// metadata created before the instance klass is created. Must be109// deallocated if classfile parsing returns an error.110_cp = NULL;111_fields = NULL;112_methods = NULL;113_inner_classes = NULL;114_local_interfaces = NULL;115_transitive_interfaces = NULL;116_combined_annotations = NULL;117_annotations = _type_annotations = NULL;118_fields_annotations = _fields_type_annotations = NULL;119}120121class AnnotationCollector {122public:123enum Location { _in_field, _in_method, _in_class };124enum ID {125_unknown = 0,126_method_CallerSensitive,127_method_ForceInline,128_method_DontInline,129_method_InjectedProfile,130_method_LambdaForm_Compiled,131_method_LambdaForm_Hidden,132_sun_misc_Contended,133_field_Stable,134_annotation_LIMIT135};136const Location _location;137int _annotations_present;138u2 _contended_group;139140AnnotationCollector(Location location)141: _location(location), _annotations_present(0), _contended_group(0)142{143assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");144}145// If this annotation name has an ID, report it (or _none).146ID annotation_index(ClassLoaderData* loader_data, Symbol* name);147// Set the annotation name:148void set_annotation(ID id) {149assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");150_annotations_present |= nth_bit((int)id);151}152153void remove_annotation(ID id) {154assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");155_annotations_present &= ~nth_bit((int)id);156}157158// Report if the annotation is present.159bool has_any_annotations() const { return _annotations_present != 0; }160bool has_annotation(ID id) const { return (nth_bit((int)id) & _annotations_present) != 0; }161162void set_contended_group(u2 group) { _contended_group = group; }163u2 contended_group() const { return _contended_group; }164165bool is_contended() const { return has_annotation(_sun_misc_Contended); }166167void set_stable(bool stable) { set_annotation(_field_Stable); }168bool is_stable() const { return has_annotation(_field_Stable); }169};170171// This class also doubles as a holder for metadata cleanup.172class FieldAnnotationCollector: public AnnotationCollector {173ClassLoaderData* _loader_data;174AnnotationArray* _field_annotations;175AnnotationArray* _field_type_annotations;176public:177FieldAnnotationCollector(ClassLoaderData* loader_data) :178AnnotationCollector(_in_field),179_loader_data(loader_data),180_field_annotations(NULL),181_field_type_annotations(NULL) {}182void apply_to(FieldInfo* f);183~FieldAnnotationCollector();184AnnotationArray* field_annotations() { return _field_annotations; }185AnnotationArray* field_type_annotations() { return _field_type_annotations; }186187void set_field_annotations(AnnotationArray* a) { _field_annotations = a; }188void set_field_type_annotations(AnnotationArray* a) { _field_type_annotations = a; }189};190191class MethodAnnotationCollector: public AnnotationCollector {192public:193MethodAnnotationCollector() : AnnotationCollector(_in_method) { }194void apply_to(methodHandle m);195};196class ClassAnnotationCollector: public AnnotationCollector {197public:198ClassAnnotationCollector() : AnnotationCollector(_in_class) { }199void apply_to(instanceKlassHandle k);200};201202enum { fixed_buffer_size = 128 };203u_char linenumbertable_buffer[fixed_buffer_size];204205ClassFileStream* _stream; // Actual input stream206207enum { LegalClass, LegalField, LegalMethod }; // used to verify unqualified names208209// Accessors210ClassFileStream* stream() { return _stream; }211void set_stream(ClassFileStream* st) { _stream = st; }212213// Constant pool parsing214void parse_constant_pool_entries(int length, TRAPS);215216constantPoolHandle parse_constant_pool(TRAPS);217218// Interface parsing219Array<Klass*>* parse_interfaces(int length,220Handle protection_domain,221Symbol* class_name,222bool* has_default_methods,223TRAPS);224void record_defined_class_dependencies(instanceKlassHandle defined_klass, TRAPS);225226instanceKlassHandle parse_super_class(int super_class_index, TRAPS);227// Field parsing228void parse_field_attributes(u2 attributes_count,229bool is_static, u2 signature_index,230u2* constantvalue_index_addr,231bool* is_synthetic_addr,232u2* generic_signature_index_addr,233FieldAnnotationCollector* parsed_annotations,234TRAPS);235Array<u2>* parse_fields(Symbol* class_name,236bool is_interface,237FieldAllocationCount *fac,238u2* java_fields_count_ptr, TRAPS);239240void print_field_layout(Symbol* name,241Array<u2>* fields,242constantPoolHandle cp,243int instance_size,244int instance_fields_start,245int instance_fields_end,246int static_fields_end);247248// Method parsing249methodHandle parse_method(bool is_interface,250AccessFlags* promoted_flags,251TRAPS);252Array<Method*>* parse_methods(bool is_interface,253AccessFlags* promoted_flags,254bool* has_final_method,255bool* declares_default_methods,256TRAPS);257intArray* sort_methods(Array<Method*>* methods);258259u2* parse_exception_table(u4 code_length, u4 exception_table_length,260TRAPS);261void parse_linenumber_table(262u4 code_attribute_length, u4 code_length,263CompressedLineNumberWriteStream** write_stream, TRAPS);264u2* parse_localvariable_table(u4 code_length, u2 max_locals, u4 code_attribute_length,265u2* localvariable_table_length,266bool isLVTT, TRAPS);267u2* parse_checked_exceptions(u2* checked_exceptions_length, u4 method_attribute_length,268TRAPS);269void parse_type_array(u2 array_length, u4 code_length, u4* u1_index, u4* u2_index,270u1* u1_array, u2* u2_array, TRAPS);271u1* parse_stackmap_table(u4 code_attribute_length, TRAPS);272273// Classfile attribute parsing274u2 parse_generic_signature_attribute(TRAPS);275void parse_classfile_sourcefile_attribute(TRAPS);276void parse_classfile_source_debug_extension_attribute(int length, TRAPS);277278// Check for circularity in InnerClasses attribute.279bool check_inner_classes_circularity(const ConstantPool* cp, int length, TRAPS);280281u2 parse_classfile_inner_classes_attribute(const ConstantPool* cp,282u1* inner_classes_attribute_start,283bool parsed_enclosingmethod_attribute,284u2 enclosing_method_class_index,285u2 enclosing_method_method_index,286TRAPS);287void parse_classfile_attributes(ClassAnnotationCollector* parsed_annotations,288TRAPS);289void parse_classfile_synthetic_attribute(TRAPS);290void parse_classfile_signature_attribute(TRAPS);291void parse_classfile_bootstrap_methods_attribute(u4 attribute_length, TRAPS);292293// Annotations handling294AnnotationArray* assemble_annotations(u1* runtime_visible_annotations,295int runtime_visible_annotations_length,296u1* runtime_invisible_annotations,297int runtime_invisible_annotations_length, TRAPS);298int skip_annotation(u1* buffer, int limit, int index);299int skip_annotation_value(u1* buffer, int limit, int index);300void parse_annotations(u1* buffer, int limit,301/* Results (currently, only one result is supported): */302AnnotationCollector* result,303TRAPS);304305// Final setup306unsigned int compute_oop_map_count(instanceKlassHandle super,307unsigned int nonstatic_oop_count,308int first_nonstatic_oop_offset);309void fill_oop_maps(instanceKlassHandle k,310unsigned int nonstatic_oop_map_count,311int* nonstatic_oop_offsets,312unsigned int* nonstatic_oop_counts);313void set_precomputed_flags(instanceKlassHandle k);314Array<Klass*>* compute_transitive_interfaces(instanceKlassHandle super,315Array<Klass*>* local_ifs, TRAPS);316317// Format checker methods318void classfile_parse_error(const char* msg, TRAPS);319void classfile_parse_error(const char* msg, int index, TRAPS);320void classfile_parse_error(const char* msg, const char *name, TRAPS);321void classfile_parse_error(const char* msg, int index, const char *name, TRAPS);322void classfile_parse_error(const char* msg, const char* name, const char* signature, TRAPS);323inline void guarantee_property(bool b, const char* msg, TRAPS) {324if (!b) { classfile_parse_error(msg, CHECK); }325}326327PRAGMA_DIAG_PUSH328PRAGMA_FORMAT_NONLITERAL_IGNORED329inline void assert_property(bool b, const char* msg, TRAPS) {330#ifdef ASSERT331if (!b) {332ResourceMark rm(THREAD);333fatal(err_msg(msg, _class_name->as_C_string()));334}335#endif336}337338inline void assert_property(bool b, const char* msg, int index, TRAPS) {339#ifdef ASSERT340if (!b) {341ResourceMark rm(THREAD);342fatal(err_msg(msg, index, _class_name->as_C_string()));343}344#endif345}346PRAGMA_DIAG_POP347348inline void check_property(bool property, const char* msg, int index, TRAPS) {349if (_need_verify) {350guarantee_property(property, msg, index, CHECK);351} else {352assert_property(property, msg, index, CHECK);353}354}355356inline void check_property(bool property, const char* msg, TRAPS) {357if (_need_verify) {358guarantee_property(property, msg, CHECK);359} else {360assert_property(property, msg, CHECK);361}362}363364inline void guarantee_property(bool b, const char* msg, int index, TRAPS) {365if (!b) { classfile_parse_error(msg, index, CHECK); }366}367inline void guarantee_property(bool b, const char* msg, const char *name, TRAPS) {368if (!b) { classfile_parse_error(msg, name, CHECK); }369}370inline void guarantee_property(bool b, const char* msg, int index, const char *name, TRAPS) {371if (!b) { classfile_parse_error(msg, index, name, CHECK); }372}373374void throwIllegalSignature(375const char* type, Symbol* name, Symbol* sig, TRAPS);376377bool is_supported_version(u2 major, u2 minor);378bool has_illegal_visibility(jint flags);379380void verify_constantvalue(int constantvalue_index, int signature_index, TRAPS);381void verify_legal_utf8(const unsigned char* buffer, int length, TRAPS);382void verify_legal_class_name(Symbol* name, TRAPS);383void verify_legal_field_name(Symbol* name, TRAPS);384void verify_legal_method_name(Symbol* name, TRAPS);385void verify_legal_field_signature(Symbol* fieldname, Symbol* signature, TRAPS);386int verify_legal_method_signature(Symbol* methodname, Symbol* signature, TRAPS);387void verify_legal_class_modifiers(jint flags, TRAPS);388void verify_legal_field_modifiers(jint flags, bool is_interface, TRAPS);389void verify_legal_method_modifiers(jint flags, bool is_interface, Symbol* name, TRAPS);390bool verify_unqualified_name(char* name, unsigned int length, int type);391char* skip_over_field_name(char* name, bool slash_ok, unsigned int length);392char* skip_over_field_signature(char* signature, bool void_ok, unsigned int length, TRAPS);393394bool is_anonymous() {395assert(EnableInvokeDynamic || _host_klass.is_null(), "");396return _host_klass.not_null();397}398bool has_cp_patch_at(int index) {399assert(EnableInvokeDynamic, "");400assert(index >= 0, "oob");401return (_cp_patches != NULL402&& index < _cp_patches->length()403&& _cp_patches->adr_at(index)->not_null());404}405Handle cp_patch_at(int index) {406assert(has_cp_patch_at(index), "oob");407return _cp_patches->at(index);408}409Handle clear_cp_patch_at(int index) {410Handle patch = cp_patch_at(index);411_cp_patches->at_put(index, Handle());412assert(!has_cp_patch_at(index), "");413return patch;414}415void patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS);416417// Wrapper for constantTag.is_klass_[or_]reference.418// In older versions of the VM, Klass*s cannot sneak into early phases of419// constant pool construction, but in later versions they can.420// %%% Let's phase out the old is_klass_reference.421bool valid_klass_reference_at(int index) {422return _cp->is_within_bounds(index) &&423(EnableInvokeDynamic424? _cp->tag_at(index).is_klass_or_reference()425: _cp->tag_at(index).is_klass_reference());426}427428// Checks that the cpool index is in range and is a utf8429bool valid_symbol_at(int cpool_index) {430return (_cp->is_within_bounds(cpool_index) &&431_cp->tag_at(cpool_index).is_utf8());432}433434void copy_localvariable_table(ConstMethod* cm, int lvt_cnt,435u2* localvariable_table_length,436u2** localvariable_table_start,437int lvtt_cnt,438u2* localvariable_type_table_length,439u2** localvariable_type_table_start,440TRAPS);441442void copy_method_annotations(ConstMethod* cm,443u1* runtime_visible_annotations,444int runtime_visible_annotations_length,445u1* runtime_invisible_annotations,446int runtime_invisible_annotations_length,447u1* runtime_visible_parameter_annotations,448int runtime_visible_parameter_annotations_length,449u1* runtime_invisible_parameter_annotations,450int runtime_invisible_parameter_annotations_length,451u1* runtime_visible_type_annotations,452int runtime_visible_type_annotations_length,453u1* runtime_invisible_type_annotations,454int runtime_invisible_type_annotations_length,455u1* annotation_default,456int annotation_default_length,457TRAPS);458459// lays out fields in class and returns the total oopmap count460void layout_fields(Handle class_loader, FieldAllocationCount* fac,461ClassAnnotationCollector* parsed_annotations,462FieldLayoutInfo* info, TRAPS);463464public:465// Constructor466ClassFileParser(ClassFileStream* st) { set_stream(st); }467~ClassFileParser();468469// Parse .class file and return new Klass*. The Klass* is not hooked up470// to the system dictionary or any other structures, so a .class file can471// be loaded several times if desired.472// The system dictionary hookup is done by the caller.473//474// "parsed_name" is updated by this method, and is the name found475// while parsing the stream.476instanceKlassHandle parseClassFile(Symbol* name,477ClassLoaderData* loader_data,478Handle protection_domain,479TempNewSymbol& parsed_name,480bool verify,481TRAPS) {482KlassHandle no_host_klass;483return parseClassFile(name, loader_data, protection_domain, no_host_klass, NULL, parsed_name, verify, THREAD);484}485instanceKlassHandle parseClassFile(Symbol* name,486ClassLoaderData* loader_data,487Handle protection_domain,488KlassHandle host_klass,489GrowableArray<Handle>* cp_patches,490TempNewSymbol& parsed_name,491bool verify,492TRAPS);493494// Verifier checks495static void check_super_class_access(instanceKlassHandle this_klass, TRAPS);496static void check_super_interface_access(instanceKlassHandle this_klass, TRAPS);497static void check_final_method_override(instanceKlassHandle this_klass, TRAPS);498static void check_illegal_static_method(instanceKlassHandle this_klass, TRAPS);499500u2 this_class_index() const { return _this_class_index; }501502#if INCLUDE_JFR503ClassFileStream* clone_stream() const;504void set_klass_to_deallocate(InstanceKlass* klass);505#endif // INCLUDE_JFR506};507508#endif // SHARE_VM_CLASSFILE_CLASSFILEPARSER_HPP509510511