/*
 * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#ifndef SHARE_OOPS_CONSTMETHOD_HPP
#define SHARE_OOPS_CONSTMETHOD_HPP

#include "oops/constMethodFlags.hpp"
#include "oops/oop.hpp"
#include "utilities/align.hpp"
#include "utilities/checkedCast.hpp"

// An ConstMethod represents portions of a Java method which are not written to after
// the classfile is parsed(*see below).  This part of the method can be shared across
// processes in a read-only section with Class Data Sharing (CDS).  It's important
// that this class doesn't have virtual functions because the vptr cannot be shared
// with CDS.
//
// Note that most applications load thousands of methods, so keeping the size of this
// structure small has a big impact on footprint.

// The actual bytecodes are inlined after the end of the ConstMethod struct.
//
// The line number table is compressed and inlined following the byte codes. It is
// found as the first byte following the byte codes.  Note that accessing the line
// number and local variable tables is not performance critical at all.
//
// The checked exceptions table and the local variable table are inlined after the
// line number table, and indexed from the end of the method. We do not compress the
// checked exceptions table since the average length is less than 2, and it is used
// by reflection so access should be fast.  We do not bother to compress the local
// variable table either since it is mostly absent.
//
//
//  ConstMethod embedded field layout (after declared fields):
//    [EMBEDDED byte codes]
//    [EMBEDDED compressed linenumber table]
//     (see class CompressedLineNumberReadStream)
//     (note that length is unknown until decompressed)
//     (access flags bit tells whether table is present)
//     (indexed from start of ConstMethod)
//     (elements not necessarily sorted!)
//    [EMBEDDED localvariable table elements + length (length last)]
//     (length is u2, elements are 6-tuples of u2)
//     (see class LocalVariableTableElement)
//     (access flags bit tells whether table is present)
//     (indexed from end of ConstMethod*)
//    [EMBEDDED exception table + length (length last)]
//     (length is u2, elements are 4-tuples of u2)
//     (see class ExceptionTableElement)
//     (access flags bit tells whether table is present)
//     (indexed from end of ConstMethod*)
//    [EMBEDDED checked exceptions elements + length (length last)]
//     (length is u2, elements are u2)
//     (see class CheckedExceptionElement)
//     (access flags bit tells whether table is present)
//     (indexed from end of ConstMethod*)
//    [EMBEDDED method parameters elements + length (length last)]
//     (length is u2, elements are u2, u4 structures)
//     (see class MethodParametersElement)
//     (access flags bit tells whether table is present)
//     (indexed from end of ConstMethod*)
//    [EMBEDDED generic signature index (u2)]
//     (indexed from end of constMethodOop)
//    [EMBEDDED annotations arrays - method, parameter, type, default]
//      pointer to Array<u1> if annotation is present
//
// IMPORTANT: If anything gets added here, there need to be changes to
// ensure that ServicabilityAgent doesn't get broken as a result!


// Utility class describing elements in checked exceptions table inlined in Method*.
class CheckedExceptionElement {
 public:
  u2 class_cp_index;
};


// Utility class describing elements in local variable table inlined in Method*.
class LocalVariableTableElement {
 public:
  u2 start_bci;
  u2 length;
  u2 name_cp_index;
  u2 descriptor_cp_index;
  u2 signature_cp_index;
  u2 slot;
};

// Utility class describing elements in exception table
class ExceptionTableElement {
 public:
  u2 start_pc;
  u2 end_pc;
  u2 handler_pc;
  u2 catch_type_index;
};

// Utility class describing elements in method parameters
class MethodParametersElement {
 public:
  u2 name_cp_index;
  u2 flags;
};

// Class to collect the sizes of ConstMethod inline tables
#define INLINE_TABLES_DO(do_element)            \
  do_element(localvariable_table_length)        \
  do_element(compressed_linenumber_size)        \
  do_element(exception_table_length)            \
  do_element(checked_exceptions_length)         \
  do_element(method_parameters_length)          \
  do_element(generic_signature_index)           \
  do_element(method_annotations_length)         \
  do_element(parameter_annotations_length)      \
  do_element(type_annotations_length)           \
  do_element(default_annotations_length)

#define INLINE_TABLE_DECLARE(sym)    int _##sym;
#define INLINE_TABLE_PARAM(sym)      int sym,
#define INLINE_TABLE_INIT(sym)       _##sym(sym),
#define INLINE_TABLE_NULL(sym)       _##sym(0),
#define INLINE_TABLE_ACCESSOR(sym)   int sym() const { return _##sym; }

class InlineTableSizes : StackObj {
  // declarations
  INLINE_TABLES_DO(INLINE_TABLE_DECLARE)
  int _end;
 public:
  InlineTableSizes(
      INLINE_TABLES_DO(INLINE_TABLE_PARAM)
      int end) :
      INLINE_TABLES_DO(INLINE_TABLE_INIT)
      _end(end) {}

  // Default constructor for no inlined tables
  InlineTableSizes() :
      INLINE_TABLES_DO(INLINE_TABLE_NULL)
      _end(0) {}

  // Accessors
  INLINE_TABLES_DO(INLINE_TABLE_ACCESSOR)
};
#undef INLINE_TABLE_ACCESSOR
#undef INLINE_TABLE_NULL
#undef INLINE_TABLE_INIT
#undef INLINE_TABLE_PARAM
#undef INLINE_TABLE_DECLARE

class ConstMethod : public MetaspaceObj {
  friend class VMStructs;
  friend class JVMCIVMStructs;

public:
  typedef enum { NORMAL, OVERPASS } MethodType;

private:

  // Bit vector of signature
  // Callers interpret 0=not initialized yet and
  // -1=too many args to fix, must parse the slow way.
  // The real initial value is special to account for nonatomicity of 64 bit
  // loads and stores.  This value may updated and read without a lock by
  // multiple threads, so is volatile.
  volatile uint64_t _fingerprint;

  // If you add a new field that points to any metaspace object, you
  // must add this field to ConstMethod::metaspace_pointers_do().

  ConstantPool*     _constants;                  // Constant pool

  // Raw stackmap data for the method
  Array<u1>*        _stackmap_data;

  int               _constMethod_size;
  ConstMethodFlags  _flags;                       // for sizing
  u1                _result_type;                 // BasicType of result

  // Size of Java bytecodes allocated immediately after Method*.
  u2                _code_size;
  u2                _name_index;                 // Method name (index in constant pool)
  u2                _signature_index;            // Method signature (index in constant pool)
  u2                _method_idnum;               // unique identification number for the method within the class
                                                 // initially corresponds to the index into the methods array.
                                                 // but this may change with redefinition
  u2                _max_stack;                  // Maximum number of entries on the expression stack
  u2                _max_locals;                 // Number of local variables used by this method
  u2                _size_of_parameters;         // size of the parameter block (receiver + arguments) in words
  u2                _num_stack_arg_slots;        // Number of arguments passed on the stack even when compiled
  u2                _orig_method_idnum;          // Original unique identification number for the method

  // Constructor
  ConstMethod(int byte_code_size,
              InlineTableSizes* sizes,
              MethodType is_overpass,
              int size);

  void set_size_of_parameters(int size)          { _size_of_parameters = checked_cast<u2>(size); }
  void set_num_stack_arg_slots(int n)            { _num_stack_arg_slots = checked_cast<u2>(n); }
  void set_result_type(BasicType rt)             { assert(rt < 16, "result type too large");
                                                   _result_type = (u1)rt; }
public:

  static ConstMethod* allocate(ClassLoaderData* loader_data,
                               int byte_code_size,
                               InlineTableSizes* sizes,
                               MethodType mt,
                               TRAPS);

  // Inlined tables
  void set_inlined_tables_length(InlineTableSizes* sizes);

  // Create getters and setters for the flag values.
#define CM_FLAGS_GET_SET(name, ignore)          \
  bool name() const       { return _flags.name(); } \
  void set_##name()       { _flags.set_##name(); }
  CM_FLAGS_DO(CM_FLAGS_GET_SET)
#undef CM_FLAGS_GET_SET

  MethodType method_type() const {
    return (_flags.is_overpass()) ? OVERPASS : NORMAL;
  }

  void set_method_type(MethodType mt) {
    if (mt != NORMAL) {
      set_is_overpass();
    }
  }

  // constant pool
  ConstantPool* constants() const        { return _constants; }
  void set_constants(ConstantPool* c)    { _constants = c; }

  Method* method() const;

  // stackmap table data
  Array<u1>* stackmap_data() const { return _stackmap_data; }
  void set_stackmap_data(Array<u1>* sd) { _stackmap_data = sd; }
  void copy_stackmap_data(ClassLoaderData* loader_data, u1* sd, int length, TRAPS);
  bool has_stackmap_table() const { return _stackmap_data != nullptr; }

  void init_fingerprint() {
    const uint64_t initval = UCONST64(0x8000000000000000);
    _fingerprint = initval;
  }

  uint64_t fingerprint() const                   {
    // Since reads aren't atomic for 64 bits, if any of the high or low order
    // word is the initial value, return 0.  See init_fingerprint for initval.
    uint high_fp = (uint)(_fingerprint >> 32);
    if ((int) _fingerprint == 0 || high_fp == 0x80000000) {
      return 0L;
    } else {
      return _fingerprint;
    }
  }

  uint64_t set_fingerprint(uint64_t new_fingerprint) {
#ifdef ASSERT
    // Assert only valid if complete/valid 64 bit _fingerprint value is read.
    uint64_t oldfp = fingerprint();
#endif // ASSERT
    _fingerprint = new_fingerprint;
    assert(oldfp == 0L || new_fingerprint == oldfp,
           "fingerprint cannot change");
    assert(((new_fingerprint >> 32) != 0x80000000) && (int)new_fingerprint !=0,
           "fingerprint should call init to set initial value");
    return new_fingerprint;
  }

  // name
  u2 name_index() const                          { return _name_index; }
  void set_name_index(int index)                 { _name_index = checked_cast<u2>(index); }

  // signature
  u2 signature_index() const                     { return _signature_index; }
  void set_signature_index(int index)            { _signature_index = checked_cast<u2>(index); }

  // generics support
  u2 generic_signature_index() const             {
    if (has_generic_signature()) {
      return *generic_signature_index_addr();
    } else {
      return 0;
    }
  }
  void set_generic_signature_index(u2 index)     {
    assert(has_generic_signature(), "");
    u2* addr = generic_signature_index_addr();
    *addr = index;
  }

  // Sizing
  static int header_size() {
    return align_up((int)sizeof(ConstMethod), wordSize) / wordSize;
  }

  // Size needed
  static int size(int code_size, InlineTableSizes* sizes);

  int size() const                    { return _constMethod_size;}
  void set_constMethod_size(int size)     { _constMethod_size = size; }

  // ConstMethods should be stored in the read-only region of CDS archive.
  static bool is_read_only_by_default() { return true; }

  // code size
  u2 code_size() const                          { return _code_size; }
  void set_code_size(int size) {
    assert(max_method_code_size < (1 << 16),
           "u2 is too small to hold method code size in general");
    assert(0 <= size && size <= max_method_code_size, "invalid code size");
    _code_size = (u2)size;
  }

  // linenumber table - note that length is unknown until decompression,
  // see class CompressedLineNumberReadStream.
  u_char* compressed_linenumber_table() const;         // not preserved by gc
  u2* generic_signature_index_addr() const;
  u2* checked_exceptions_length_addr() const;
  u2* localvariable_table_length_addr() const;
  u2* exception_table_length_addr() const;
  u2* method_parameters_length_addr() const;

  // checked exceptions
  u2 checked_exceptions_length() const;
  CheckedExceptionElement* checked_exceptions_start() const;

  // localvariable table
  u2 localvariable_table_length() const;
  LocalVariableTableElement* localvariable_table_start() const;

  // exception table
  u2 exception_table_length() const;
  ExceptionTableElement* exception_table_start() const;

  // method parameters table

  // This returns -1 if no parameters are present, a non-negative
  // value otherwise.  Note: sometimes, there are 0-length parameters
  // attributes that must be reported up to the reflection API all the
  // same.
  int method_parameters_length() const;
  MethodParametersElement* method_parameters_start() const;

  AnnotationArray** method_annotations_addr() const;
  AnnotationArray* method_annotations() const  {
    return has_method_annotations() ? *(method_annotations_addr()) : nullptr;
  }
  void set_method_annotations(AnnotationArray* anno) {
    *(method_annotations_addr()) = anno;
  }

  AnnotationArray** parameter_annotations_addr() const;
  AnnotationArray* parameter_annotations() const {
    return has_parameter_annotations() ? *(parameter_annotations_addr()) : nullptr;
  }
  void set_parameter_annotations(AnnotationArray* anno) {
    *(parameter_annotations_addr()) = anno;
  }

  AnnotationArray** type_annotations_addr() const;
  AnnotationArray* type_annotations() const {
    return has_type_annotations() ? *(type_annotations_addr()) : nullptr;
  }
  void set_type_annotations(AnnotationArray* anno) {
    *(type_annotations_addr()) = anno;
  }

  AnnotationArray** default_annotations_addr() const;
  AnnotationArray* default_annotations() const {
    return has_default_annotations() ? *(default_annotations_addr()) : nullptr;
  }
  void set_default_annotations(AnnotationArray* anno) {
    *(default_annotations_addr()) = anno;
  }

  int method_annotations_length() const {
    return has_method_annotations() ? method_annotations()->length() : 0;
  }
  int parameter_annotations_length() const {
    return has_parameter_annotations() ? parameter_annotations()->length() : 0;
  }
  int type_annotations_length() const {
    return has_type_annotations() ? type_annotations()->length() : 0;
  }
  int default_annotations_length() const {
    return has_default_annotations() ? default_annotations()->length() : 0;
  }

  // Copy annotations from other ConstMethod
  void copy_annotations_from(ClassLoaderData* loader_data, ConstMethod* cm, TRAPS);

  // byte codes
  void    set_code(address code) {
    if (code_size() > 0) {
      memcpy(code_base(), code, code_size());
    }
  }
  address code_base() const            { return (address) (this+1); }
  address code_end() const             { return code_base() + code_size(); }
  bool    contains(address bcp) const  { return code_base() <= bcp
                                                     && bcp < code_end(); }
  // Offset to bytecodes
  static ByteSize codes_offset()
                            { return in_ByteSize(sizeof(ConstMethod)); }

  static ByteSize constants_offset()
                            { return byte_offset_of(ConstMethod, _constants); }

  static ByteSize max_stack_offset()
                            { return byte_offset_of(ConstMethod, _max_stack); }
  static ByteSize size_of_locals_offset()
                            { return byte_offset_of(ConstMethod, _max_locals); }
  static ByteSize size_of_parameters_offset()
                            { return byte_offset_of(ConstMethod, _size_of_parameters); }

  static ByteSize result_type_offset()
                            { return byte_offset_of(ConstMethod, _result_type); }

  // Unique id for the method
  static const u2 MAX_IDNUM;
  static const u2 UNSET_IDNUM;
  u2 method_idnum() const                        { return _method_idnum; }
  void set_method_idnum(u2 idnum)                { _method_idnum = idnum; }

  u2 orig_method_idnum() const                   { return _orig_method_idnum; }
  void set_orig_method_idnum(u2 idnum)           { _orig_method_idnum = idnum; }

  // Derive stuff from the signature at load time.
  void compute_from_signature(Symbol* sig, bool is_static);

  // max stack
  u2   max_stack() const                         { return _max_stack; }
  void set_max_stack(int size)                   { _max_stack = checked_cast<u2>(size); }

  // max locals
  u2  max_locals() const                         { return _max_locals; }
  void set_max_locals(int size)                  { _max_locals = checked_cast<u2>(size); }

  // size of parameters
  u2 size_of_parameters() const                  { return _size_of_parameters; }

  // Number of arguments passed on the stack even when compiled
  u2 num_stack_arg_slots() const                 { return _num_stack_arg_slots; }

  // result type (basic type of return value)
  BasicType result_type() const                  { assert(_result_type >= T_BOOLEAN, "Must be set");
                                                   return (BasicType)_result_type; }

  // Deallocation for RedefineClasses
  void deallocate_contents(ClassLoaderData* loader_data);
  DEBUG_ONLY(bool on_stack() { return false; })

  void metaspace_pointers_do(MetaspaceClosure* it);
  MetaspaceObj::Type type() const { return ConstMethodType; }
private:
  // Since the size of the compressed line number table is unknown, the
  // offsets of the other variable sized sections are computed backwards
  // from the end of the ConstMethod*.

  // First byte after ConstMethod*
  address constMethod_end() const
                          { return (address)((intptr_t*)this + _constMethod_size); }

  // Last short in ConstMethod*
  u2* last_u2_element() const;

 public:
  // Printing
  void print_on      (outputStream* st) const;
  void print_value_on(outputStream* st) const;

  const char* internal_name() const { return "{constMethod}"; }

  // Verify
  void verify_on(outputStream* st);
};

#endif // SHARE_OOPS_CONSTMETHOD_HPP
