Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/oops/constMethod.hpp
32285 views
/*1* Copyright (c) 2003, 2016, 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_OOPS_CONSTMETHODOOP_HPP25#define SHARE_VM_OOPS_CONSTMETHODOOP_HPP2627#include "oops/oop.hpp"2829// An ConstMethod* represents portions of a Java method which30// do not vary.31//32// Memory layout (each line represents a word). Note that most33// applications load thousands of methods, so keeping the size of this34// structure small has a big impact on footprint.35//36// |------------------------------------------------------|37// | header |38// | klass |39// |------------------------------------------------------|40// | fingerprint 1 |41// | fingerprint 2 |42// | constants (oop) |43// | stackmap_data (oop) |44// | constMethod_size |45// | interp_kind | flags | code_size |46// | name index | signature index |47// | method_idnum | max_stack |48// | max_locals | size_of_parameters |49// |------------------------------------------------------|50// | |51// | byte codes |52// | |53// |------------------------------------------------------|54// | compressed linenumber table |55// | (see class CompressedLineNumberReadStream) |56// | (note that length is unknown until decompressed) |57// | (access flags bit tells whether table is present) |58// | (indexed from start of ConstMethod*) |59// | (elements not necessarily sorted!) |60// |------------------------------------------------------|61// | localvariable table elements + length (length last) |62// | (length is u2, elements are 6-tuples of u2) |63// | (see class LocalVariableTableElement) |64// | (access flags bit tells whether table is present) |65// | (indexed from end of ConstMethod*) |66// |------------------------------------------------------|67// | exception table + length (length last) |68// | (length is u2, elements are 4-tuples of u2) |69// | (see class ExceptionTableElement) |70// | (access flags bit tells whether table is present) |71// | (indexed from end of ConstMethod*) |72// |------------------------------------------------------|73// | checked exceptions elements + length (length last) |74// | (length is u2, elements are u2) |75// | (see class CheckedExceptionElement) |76// | (access flags bit tells whether table is present) |77// | (indexed from end of ConstMethod*) |78// |------------------------------------------------------|79// | method parameters elements + length (length last) |80// | (length is u2, elements are u2, u4 structures) |81// | (see class MethodParametersElement) |82// | (access flags bit tells whether table is present) |83// | (indexed from end of ConstMethod*) |84// |------------------------------------------------------|85// | generic signature index (u2) |86// | (indexed from start of constMethodOop) |87// |------------------------------------------------------|88// | annotations arrays - method, parameter, type, default|89// | pointer to Array<u1> if annotation is present |90// |------------------------------------------------------|91//92// IMPORTANT: If anything gets added here, there need to be changes to93// ensure that ServicabilityAgent doesn't get broken as a result!949596// Utility class describing elements in checked exceptions table inlined in Method*.97class CheckedExceptionElement VALUE_OBJ_CLASS_SPEC {98public:99u2 class_cp_index;100};101102103// Utility class describing elements in local variable table inlined in Method*.104class LocalVariableTableElement VALUE_OBJ_CLASS_SPEC {105public:106u2 start_bci;107u2 length;108u2 name_cp_index;109u2 descriptor_cp_index;110u2 signature_cp_index;111u2 slot;112};113114// Utility class describing elements in exception table115class ExceptionTableElement VALUE_OBJ_CLASS_SPEC {116public:117u2 start_pc;118u2 end_pc;119u2 handler_pc;120u2 catch_type_index;121};122123// Utility class describing elements in method parameters124class MethodParametersElement VALUE_OBJ_CLASS_SPEC {125public:126u2 name_cp_index;127u2 flags;128};129130class KlassSizeStats;131132// Class to collect the sizes of ConstMethod inline tables133#define INLINE_TABLES_DO(do_element) \134do_element(localvariable_table_length) \135do_element(compressed_linenumber_size) \136do_element(exception_table_length) \137do_element(checked_exceptions_length) \138do_element(method_parameters_length) \139do_element(generic_signature_index) \140do_element(method_annotations_length) \141do_element(parameter_annotations_length) \142do_element(type_annotations_length) \143do_element(default_annotations_length)144145#define INLINE_TABLE_DECLARE(sym) int _##sym;146#define INLINE_TABLE_PARAM(sym) int sym,147#define INLINE_TABLE_INIT(sym) _##sym(sym),148#define INLINE_TABLE_NULL(sym) _##sym(0),149#define INLINE_TABLE_ACCESSOR(sym) int sym() const { return _##sym; }150151class InlineTableSizes : StackObj {152// declarations153INLINE_TABLES_DO(INLINE_TABLE_DECLARE)154int _end;155public:156InlineTableSizes(157INLINE_TABLES_DO(INLINE_TABLE_PARAM)158int end) :159INLINE_TABLES_DO(INLINE_TABLE_INIT)160_end(end) {}161162// Default constructor for no inlined tables163InlineTableSizes() :164INLINE_TABLES_DO(INLINE_TABLE_NULL)165_end(0) {}166167// Accessors168INLINE_TABLES_DO(INLINE_TABLE_ACCESSOR)169};170#undef INLINE_TABLE_ACCESSOR171#undef INLINE_TABLE_NULL172#undef INLINE_TABLE_INIT173#undef INLINE_TABLE_PARAM174#undef INLINE_TABLE_DECLARE175176177class ConstMethod : public MetaspaceObj {178friend class VMStructs;179180public:181typedef enum { NORMAL, OVERPASS } MethodType;182183private:184enum {185_has_linenumber_table = 0x0001,186_has_checked_exceptions = 0x0002,187_has_localvariable_table = 0x0004,188_has_exception_table = 0x0008,189_has_generic_signature = 0x0010,190_has_method_parameters = 0x0020,191_is_overpass = 0x0040,192_has_method_annotations = 0x0080,193_has_parameter_annotations = 0x0100,194_has_type_annotations = 0x0200,195_has_default_annotations = 0x0400196};197198// Bit vector of signature199// Callers interpret 0=not initialized yet and200// -1=too many args to fix, must parse the slow way.201// The real initial value is special to account for nonatomicity of 64 bit202// loads and stores. This value may updated and read without a lock by203// multiple threads, so is volatile.204volatile uint64_t _fingerprint;205206ConstantPool* _constants; // Constant pool207208// Raw stackmap data for the method209Array<u1>* _stackmap_data;210211int _constMethod_size;212u2 _flags;213u1 _result_type; // BasicType of result214215// Size of Java bytecodes allocated immediately after Method*.216u2 _code_size;217u2 _name_index; // Method name (index in constant pool)218u2 _signature_index; // Method signature (index in constant pool)219u2 _method_idnum; // unique identification number for the method within the class220// initially corresponds to the index into the methods array.221// but this may change with redefinition222u2 _max_stack; // Maximum number of entries on the expression stack223u2 _max_locals; // Number of local variables used by this method224u2 _size_of_parameters; // size of the parameter block (receiver + arguments) in words225u2 _orig_method_idnum; // Original unique identification number for the method226227// Constructor228ConstMethod(int byte_code_size,229InlineTableSizes* sizes,230MethodType is_overpass,231int size);232public:233234static ConstMethod* allocate(ClassLoaderData* loader_data,235int byte_code_size,236InlineTableSizes* sizes,237MethodType mt,238TRAPS);239240bool is_constMethod() const { return true; }241242// Inlined tables243void set_inlined_tables_length(InlineTableSizes* sizes);244245bool has_generic_signature() const246{ return (_flags & _has_generic_signature) != 0; }247248bool has_linenumber_table() const249{ return (_flags & _has_linenumber_table) != 0; }250251bool has_checked_exceptions() const252{ return (_flags & _has_checked_exceptions) != 0; }253254bool has_localvariable_table() const255{ return (_flags & _has_localvariable_table) != 0; }256257bool has_exception_handler() const258{ return (_flags & _has_exception_table) != 0; }259260bool has_method_parameters() const261{ return (_flags & _has_method_parameters) != 0; }262263MethodType method_type() const {264return ((_flags & _is_overpass) == 0) ? NORMAL : OVERPASS;265}266267void set_method_type(MethodType mt) {268if (mt == NORMAL) {269_flags &= ~(_is_overpass);270} else {271_flags |= _is_overpass;272}273}274275// constant pool276ConstantPool* constants() const { return _constants; }277void set_constants(ConstantPool* c) { _constants = c; }278279Method* method() const;280281// stackmap table data282Array<u1>* stackmap_data() const { return _stackmap_data; }283void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; }284void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS);285bool has_stackmap_table() const { return _stackmap_data != NULL; }286287void init_fingerprint() {288const uint64_t initval = CONST64(0x8000000000000000);289_fingerprint = initval;290}291292uint64_t fingerprint() const {293// Since reads aren't atomic for 64 bits, if any of the high or low order294// word is the initial value, return 0. See init_fingerprint for initval.295uint high_fp = (uint)(_fingerprint >> 32);296if ((int) _fingerprint == 0 || high_fp == 0x80000000) {297return 0L;298} else {299return _fingerprint;300}301}302303uint64_t set_fingerprint(uint64_t new_fingerprint) {304#ifdef ASSERT305// Assert only valid if complete/valid 64 bit _fingerprint value is read.306uint64_t oldfp = fingerprint();307#endif // ASSERT308_fingerprint = new_fingerprint;309assert(oldfp == 0L || new_fingerprint == oldfp,310"fingerprint cannot change");311assert(((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0,312"fingerprint should call init to set initial value");313return new_fingerprint;314}315316// name317int name_index() const { return _name_index; }318void set_name_index(int index) { _name_index = index; }319320// signature321int signature_index() const { return _signature_index; }322void set_signature_index(int index) { _signature_index = index; }323324// generics support325int generic_signature_index() const {326if (has_generic_signature()) {327return *generic_signature_index_addr();328} else {329return 0;330}331}332void set_generic_signature_index(u2 index) {333assert(has_generic_signature(), "");334u2* addr = generic_signature_index_addr();335*addr = index;336}337338// Sizing339static int header_size() {340return sizeof(ConstMethod)/HeapWordSize;341}342343// Size needed344static int size(int code_size, InlineTableSizes* sizes);345346int size() const { return _constMethod_size;}347void set_constMethod_size(int size) { _constMethod_size = size; }348#if INCLUDE_SERVICES349void collect_statistics(KlassSizeStats *sz) const;350#endif351352// code size353int code_size() const { return _code_size; }354void set_code_size(int size) {355assert(max_method_code_size < (1 << 16),356"u2 is too small to hold method code size in general");357assert(0 <= size && size <= max_method_code_size, "invalid code size");358_code_size = size;359}360361// linenumber table - note that length is unknown until decompression,362// see class CompressedLineNumberReadStream.363u_char* compressed_linenumber_table() const; // not preserved by gc364u2* generic_signature_index_addr() const;365u2* checked_exceptions_length_addr() const;366u2* localvariable_table_length_addr() const;367u2* exception_table_length_addr() const;368u2* method_parameters_length_addr() const;369370// checked exceptions371int checked_exceptions_length() const;372CheckedExceptionElement* checked_exceptions_start() const;373374// localvariable table375int localvariable_table_length() const;376LocalVariableTableElement* localvariable_table_start() const;377378// exception table379int exception_table_length() const;380ExceptionTableElement* exception_table_start() const;381382// method parameters table383int method_parameters_length() const;384MethodParametersElement* method_parameters_start() const;385386// method annotations387bool has_method_annotations() const388{ return (_flags & _has_method_annotations) != 0; }389390bool has_parameter_annotations() const391{ return (_flags & _has_parameter_annotations) != 0; }392393bool has_type_annotations() const394{ return (_flags & _has_type_annotations) != 0; }395396bool has_default_annotations() const397{ return (_flags & _has_default_annotations) != 0; }398399400AnnotationArray** method_annotations_addr() const;401AnnotationArray* method_annotations() const {402return has_method_annotations() ? *(method_annotations_addr()) : NULL;403}404void set_method_annotations(AnnotationArray* anno) {405*(method_annotations_addr()) = anno;406}407408AnnotationArray** parameter_annotations_addr() const;409AnnotationArray* parameter_annotations() const {410return has_parameter_annotations() ? *(parameter_annotations_addr()) : NULL;411}412void set_parameter_annotations(AnnotationArray* anno) {413*(parameter_annotations_addr()) = anno;414}415416AnnotationArray** type_annotations_addr() const;417AnnotationArray* type_annotations() const {418return has_type_annotations() ? *(type_annotations_addr()) : NULL;419}420void set_type_annotations(AnnotationArray* anno) {421*(type_annotations_addr()) = anno;422}423424AnnotationArray** default_annotations_addr() const;425AnnotationArray* default_annotations() const {426return has_default_annotations() ? *(default_annotations_addr()) : NULL;427}428void set_default_annotations(AnnotationArray* anno) {429*(default_annotations_addr()) = anno;430}431432int method_annotations_length() const {433return has_method_annotations() ? method_annotations()->length() : 0;434}435int parameter_annotations_length() const {436return has_parameter_annotations() ? parameter_annotations()->length() : 0;437}438int type_annotations_length() const {439return has_type_annotations() ? type_annotations()->length() : 0;440}441int default_annotations_length() const {442return has_default_annotations() ? default_annotations()->length() : 0;443}444445// Copy annotations from other ConstMethod446void copy_annotations_from(ConstMethod* cm);447448// byte codes449void set_code(address code) {450if (code_size() > 0) {451memcpy(code_base(), code, code_size());452}453}454address code_base() const { return (address) (this+1); }455address code_end() const { return code_base() + code_size(); }456bool contains(address bcp) const { return code_base() <= bcp457&& bcp < code_end(); }458// Offset to bytecodes459static ByteSize codes_offset()460{ return in_ByteSize(sizeof(ConstMethod)); }461462static ByteSize constants_offset()463{ return byte_offset_of(ConstMethod, _constants); }464465static ByteSize max_stack_offset()466{ return byte_offset_of(ConstMethod, _max_stack); }467static ByteSize size_of_locals_offset()468{ return byte_offset_of(ConstMethod, _max_locals); }469static ByteSize size_of_parameters_offset()470{ return byte_offset_of(ConstMethod, _size_of_parameters); }471472static ByteSize result_type_offset()473{ return byte_offset_of(ConstMethod, _result_type); }474475// Unique id for the method476static const u2 MAX_IDNUM;477static const u2 UNSET_IDNUM;478u2 method_idnum() const { return _method_idnum; }479void set_method_idnum(u2 idnum) { _method_idnum = idnum; }480481u2 orig_method_idnum() const { return _orig_method_idnum; }482void set_orig_method_idnum(u2 idnum) { _orig_method_idnum = idnum; }483484// max stack485int max_stack() const { return _max_stack; }486void set_max_stack(int size) { _max_stack = size; }487488// max locals489int max_locals() const { return _max_locals; }490void set_max_locals(int size) { _max_locals = size; }491492// size of parameters493int size_of_parameters() const { return _size_of_parameters; }494void set_size_of_parameters(int size) { _size_of_parameters = size; }495496void set_result_type(BasicType rt) { assert(rt < 16, "result type too large");497_result_type = (u1)rt; }498// Deallocation for RedefineClasses499void deallocate_contents(ClassLoaderData* loader_data);500bool is_klass() const { return false; }501DEBUG_ONLY(bool on_stack() { return false; })502503private:504// Since the size of the compressed line number table is unknown, the505// offsets of the other variable sized sections are computed backwards506// from the end of the ConstMethod*.507508// First byte after ConstMethod*509address constMethod_end() const510{ return (address)((intptr_t*)this + _constMethod_size); }511512// Last short in ConstMethod*513u2* last_u2_element() const;514515public:516// Printing517void print_on (outputStream* st) const;518void print_value_on(outputStream* st) const;519520const char* internal_name() const { return "{constMethod}"; }521522// Verify523void verify_on(outputStream* st);524};525526#endif // SHARE_VM_OOPS_CONSTMETHODOOP_HPP527528529