/*
 * Copyright (c) 1997, 2025, 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.
 *
 */
#include "cds/cdsConfig.hpp"
#include "classfile/classFileParser.hpp"
#include "classfile/classFileStream.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/classLoaderData.inline.hpp"
#include "classfile/classLoadInfo.hpp"
#include "classfile/defaultMethods.hpp"
#include "classfile/fieldLayoutBuilder.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/moduleEntry.hpp"
#include "classfile/packageEntry.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/verificationType.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "jvm.h"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/allocation.hpp"
#include "memory/metadataFactory.hpp"
#include "memory/oopFactory.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/annotations.hpp"
#include "oops/constantPool.inline.hpp"
#include "oops/fieldInfo.hpp"
#include "oops/fieldStreams.inline.hpp"
#include "oops/instanceKlass.inline.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/klassVtable.hpp"
#include "oops/metadata.hpp"
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
#include "oops/recordComponent.hpp"
#include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/arguments.hpp"
#include "runtime/fieldDescriptor.inline.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/os.hpp"
#include "runtime/perfData.hpp"
#include "runtime/reflection.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "runtime/signature.hpp"
#include "runtime/timer.hpp"
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"
#include "utilities/align.hpp"
#include "utilities/bitMap.inline.hpp"
#include "utilities/checkedCast.hpp"
#include "utilities/copy.hpp"
#include "utilities/formatBuffer.hpp"
#include "utilities/exceptions.hpp"
#include "utilities/globalDefinitions.hpp"
#include "utilities/growableArray.hpp"
#include "utilities/macros.hpp"
#include "utilities/ostream.hpp"
#include "utilities/resourceHash.hpp"
#include "utilities/utf8.hpp"
#if INCLUDE_CDS
#include "classfile/systemDictionaryShared.hpp"
#endif
#if INCLUDE_JFR
#include "jfr/support/jfrTraceIdExtension.hpp"
#endif

// We generally try to create the oops directly when parsing, rather than
// allocating temporary data structures and copying the bytes twice. A
// temporary area is only needed when parsing utf8 entries in the constant
// pool and when parsing line number tables.

// We add assert in debug mode when class format is not checked.

#define JAVA_CLASSFILE_MAGIC              0xCAFEBABE
#define JAVA_MIN_SUPPORTED_VERSION        45
#define JAVA_PREVIEW_MINOR_VERSION        65535

// 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
#define JAVA_1_5_VERSION                  49

// 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
#define JAVA_6_VERSION                    50

// Used for backward compatibility reasons:
// - to disallow argument and require ACC_STATIC for <clinit> methods
#define JAVA_7_VERSION                    51

// Extension method support.
#define JAVA_8_VERSION                    52

#define JAVA_9_VERSION                    53

#define JAVA_10_VERSION                   54

#define JAVA_11_VERSION                   55

#define JAVA_12_VERSION                   56

#define JAVA_13_VERSION                   57

#define JAVA_14_VERSION                   58

#define JAVA_15_VERSION                   59

#define JAVA_16_VERSION                   60

#define JAVA_17_VERSION                   61

#define JAVA_18_VERSION                   62

#define JAVA_19_VERSION                   63

#define JAVA_20_VERSION                   64

#define JAVA_21_VERSION                   65

#define JAVA_22_VERSION                   66

#define JAVA_23_VERSION                   67

#define JAVA_24_VERSION                   68

#define JAVA_25_VERSION                   69

void ClassFileParser::set_class_bad_constant_seen(short bad_constant) {
  assert((bad_constant == JVM_CONSTANT_Module ||
          bad_constant == JVM_CONSTANT_Package) && _major_version >= JAVA_9_VERSION,
         "Unexpected bad constant pool entry");
  if (_bad_constant_seen == 0) _bad_constant_seen = bad_constant;
}

void ClassFileParser::parse_constant_pool_entries(const ClassFileStream* const stream,
                                                  ConstantPool* cp,
                                                  const int length,
                                                  TRAPS) {
  assert(stream != nullptr, "invariant");
  assert(cp != nullptr, "invariant");

  // 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().
  const ClassFileStream cfs1 = *stream;
  const ClassFileStream* const cfs = &cfs1;

  DEBUG_ONLY(const u1* const old_current = stream->current();)

  // 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.
    const u1 tag = cfs->get_u1_fast();
    switch (tag) {
      case JVM_CONSTANT_Class : {
        cfs->guarantee_more(3, CHECK);  // name_index, tag/access_flags
        const 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
        const u2 class_index = cfs->get_u2_fast();
        const 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
        const u2 class_index = cfs->get_u2_fast();
        const 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
        const u2 class_index = cfs->get_u2_fast();
        const 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
        const 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, THREAD);
          return;
        }
        if (tag == JVM_CONSTANT_MethodHandle) {
          cfs->guarantee_more(4, CHECK);  // ref_kind, method_index, tag/access_flags
          const u1 ref_kind = cfs->get_u1_fast();
          const 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
          const u2 signature_index = cfs->get_u2_fast();
          cp->method_type_index_at_put(index, signature_index);
        }
        else {
          ShouldNotReachHere();
        }
        break;
      }
      case JVM_CONSTANT_Dynamic : {
        if (_major_version < Verifier::DYNAMICCONSTANT_MAJOR_VERSION) {
          classfile_parse_error(
              "Class file version does not support constant tag %u in class file %s",
              tag, THREAD);
          return;
        }
        cfs->guarantee_more(5, CHECK);  // bsm_index, nt, tag/access_flags
        const u2 bootstrap_specifier_index = cfs->get_u2_fast();
        const 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->dynamic_constant_at_put(index, bootstrap_specifier_index, name_and_type_index);
        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, THREAD);
          return;
        }
        cfs->guarantee_more(5, CHECK);  // bsm_index, nt, tag/access_flags
        const u2 bootstrap_specifier_index = cfs->get_u2_fast();
        const 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
        const 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
        const 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
        const 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
        const 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
        const u2 name_index = cfs->get_u2_fast();
        const 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();
        const u1* utf8_buffer = cfs->current();
        assert(utf8_buffer != nullptr, "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(utf8_buffer, utf8_length, CHECK);
        }

        unsigned int hash;
        Symbol* const result = SymbolTable::lookup_only((const char*)utf8_buffer,
                                                        utf8_length,
                                                        hash);
        if (result == nullptr) {
          names[names_count] = (const 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,
                                     constantPoolHandle(THREAD, cp),
                                     names_count,
                                     names,
                                     lengths,
                                     indices,
                                     hashValues);
            names_count = 0;
          }
        } else {
          cp->symbol_at_put(index, result);
        }
        break;
      }
      case JVM_CONSTANT_Module:
      case JVM_CONSTANT_Package: {
        // Record that an error occurred in these two cases but keep parsing so
        // that ACC_Module can be checked for in the access_flags.  Need to
        // throw NoClassDefFoundError in that case.
        if (_major_version >= JAVA_9_VERSION) {
          cfs->guarantee_more(3, CHECK);
          cfs->get_u2_fast();
          set_class_bad_constant_seen(tag);
          break;
        }
      }
      default: {
        classfile_parse_error("Unknown constant tag %u in class file %s",
                              tag,
                              THREAD);
        return;
      }
    } // end of switch(tag)
  } // end of for

  // Allocate the remaining symbols
  if (names_count > 0) {
    SymbolTable::new_symbols(_loader_data,
                             constantPoolHandle(THREAD, cp),
                             names_count,
                             names,
                             lengths,
                             indices,
                             hashValues);
  }

  // Copy _current pointer of local copy back to stream.
  assert(stream->current() == old_current, "non-exclusive use of stream");
  stream->set_current(cfs1.current());

}

static inline bool valid_cp_range(int index, int length) {
  return (index > 0 && index < length);
}

static inline Symbol* check_symbol_at(const ConstantPool* cp, int index) {
  assert(cp != nullptr, "invariant");
  if (valid_cp_range(index, cp->length()) && cp->tag_at(index).is_utf8()) {
    return cp->symbol_at(index);
  }
  return nullptr;
}

void ClassFileParser::parse_constant_pool(const ClassFileStream* const stream,
                                         ConstantPool* const cp,
                                         const int length,
                                         TRAPS) {
  assert(cp != nullptr, "invariant");
  assert(stream != nullptr, "invariant");

  // parsing constant pool entries
  parse_constant_pool_entries(stream, cp, length, CHECK);
  if (class_bad_constant_seen() != 0) {
    // a bad CP entry has been detected previously so stop parsing and just return.
    return;
  }

  int index = 1;  // declared outside of loops for portability
  int num_klasses = 0;

  // first verification pass - validate cross references
  // and fixup class and string constants
  for (index = 1; index < length; index++) {          // Index 0 is unused
    const jbyte tag = cp->tag_at(index).value();
    switch (tag) {
      case JVM_CONSTANT_Class: {
        ShouldNotReachHere();     // Only JVM_CONSTANT_ClassIndex should be present
        break;
      }
      case JVM_CONSTANT_Fieldref:
        // fall through
      case JVM_CONSTANT_Methodref:
        // fall through
      case JVM_CONSTANT_InterfaceMethodref: {
        if (!_need_verify) break;
        const int klass_ref_index = cp->uncached_klass_ref_index_at(index);
        const int name_and_type_ref_index = cp->uncached_name_and_type_ref_index_at(index);
        guarantee_property(valid_klass_reference_at(klass_ref_index),
                       "Invalid constant pool index %u in class file %s",
                       klass_ref_index, CHECK);
        guarantee_property(valid_cp_range(name_and_type_ref_index, length) &&
          cp->tag_at(name_and_type_ref_index).is_name_and_type(),
          "Invalid constant pool index %u in class file %s",
          name_and_type_ref_index, CHECK);
        break;
      }
      case JVM_CONSTANT_String: {
        ShouldNotReachHere();     // Only JVM_CONSTANT_StringIndex should be present
        break;
      }
      case JVM_CONSTANT_Integer:
        break;
      case JVM_CONSTANT_Float:
        break;
      case JVM_CONSTANT_Long:
      case JVM_CONSTANT_Double: {
        index++;
        guarantee_property(
          (index < length && cp->tag_at(index).is_invalid()),
          "Improper constant pool long/double index %u in class file %s",
          index, CHECK);
        break;
      }
      case JVM_CONSTANT_NameAndType: {
        if (!_need_verify) break;
        const int name_ref_index = cp->name_ref_index_at(index);
        const int signature_ref_index = cp->signature_ref_index_at(index);
        guarantee_property(valid_symbol_at(name_ref_index),
          "Invalid constant pool index %u in class file %s",
          name_ref_index, CHECK);
        guarantee_property(valid_symbol_at(signature_ref_index),
          "Invalid constant pool index %u in class file %s",
          signature_ref_index, CHECK);
        break;
      }
      case JVM_CONSTANT_Utf8:
        break;
      case JVM_CONSTANT_UnresolvedClass:         // fall-through
      case JVM_CONSTANT_UnresolvedClassInError: {
        ShouldNotReachHere();     // Only JVM_CONSTANT_ClassIndex should be present
        break;
      }
      case JVM_CONSTANT_ClassIndex: {
        const int class_index = cp->klass_index_at(index);
        guarantee_property(valid_symbol_at(class_index),
          "Invalid constant pool index %u in class file %s",
          class_index, CHECK);
        cp->unresolved_klass_at_put(index, class_index, num_klasses++);
        break;
      }
      case JVM_CONSTANT_StringIndex: {
        const int string_index = cp->string_index_at(index);
        guarantee_property(valid_symbol_at(string_index),
          "Invalid constant pool index %u in class file %s",
          string_index, CHECK);
        Symbol* const sym = cp->symbol_at(string_index);
        cp->unresolved_string_at_put(index, sym);
        break;
      }
      case JVM_CONSTANT_MethodHandle: {
        const int ref_index = cp->method_handle_index_at(index);
        guarantee_property(valid_cp_range(ref_index, length),
          "Invalid constant pool index %u in class file %s",
          ref_index, CHECK);
        const constantTag tag = cp->tag_at(ref_index);
        const int ref_kind = cp->method_handle_ref_kind_at(index);

        switch (ref_kind) {
          case JVM_REF_getField:
          case JVM_REF_getStatic:
          case JVM_REF_putField:
          case JVM_REF_putStatic: {
            guarantee_property(
              tag.is_field(),
              "Invalid constant pool index %u in class file %s (not a field)",
              ref_index, CHECK);
            break;
          }
          case JVM_REF_invokeVirtual:
          case JVM_REF_newInvokeSpecial: {
            guarantee_property(
              tag.is_method(),
              "Invalid constant pool index %u in class file %s (not a method)",
              ref_index, CHECK);
            break;
          }
          case JVM_REF_invokeStatic:
          case JVM_REF_invokeSpecial: {
            guarantee_property(
              tag.is_method() ||
              ((_major_version >= JAVA_8_VERSION) && tag.is_interface_method()),
              "Invalid constant pool index %u in class file %s (not a method)",
              ref_index, CHECK);
            break;
          }
          case JVM_REF_invokeInterface: {
            guarantee_property(
              tag.is_interface_method(),
              "Invalid constant pool index %u in class file %s (not an interface method)",
              ref_index, CHECK);
            break;
          }
          default: {
            classfile_parse_error(
              "Bad method handle kind at constant pool index %u in class file %s",
              index, THREAD);
            return;
          }
        } // switch(refkind)
        // Keep the ref_index unchanged.  It will be indirected at link-time.
        break;
      } // case MethodHandle
      case JVM_CONSTANT_MethodType: {
        const int ref_index = cp->method_type_index_at(index);
        guarantee_property(valid_symbol_at(ref_index),
          "Invalid constant pool index %u in class file %s",
          ref_index, CHECK);
        break;
      }
      case JVM_CONSTANT_Dynamic: {
        const int name_and_type_ref_index =
          cp->bootstrap_name_and_type_ref_index_at(index);

        guarantee_property(valid_cp_range(name_and_type_ref_index, length) &&
          cp->tag_at(name_and_type_ref_index).is_name_and_type(),
          "Invalid constant pool index %u in class file %s",
          name_and_type_ref_index, CHECK);
        // bootstrap specifier index must be checked later,
        // when BootstrapMethods attr is available

        // Mark the constant pool as having a CONSTANT_Dynamic_info structure
        cp->set_has_dynamic_constant();
        break;
      }
      case JVM_CONSTANT_InvokeDynamic: {
        const int name_and_type_ref_index =
          cp->bootstrap_name_and_type_ref_index_at(index);

        guarantee_property(valid_cp_range(name_and_type_ref_index, length) &&
          cp->tag_at(name_and_type_ref_index).is_name_and_type(),
          "Invalid constant pool index %u in class file %s",
          name_and_type_ref_index, CHECK);
        // bootstrap specifier index must be checked later,
        // when BootstrapMethods attr is available
        break;
      }
      default: {
        fatal("bad constant pool tag value %u", cp->tag_at(index).value());
        ShouldNotReachHere();
        break;
      }
    } // switch(tag)
  } // end of for

  cp->allocate_resolved_klasses(_loader_data, num_klasses, CHECK);

  if (!_need_verify) {
    return;
  }

  // second verification pass - checks the strings are of the right format.
  // but not yet to the other entries
  for (index = 1; index < length; index++) {
    const jbyte tag = cp->tag_at(index).value();
    switch (tag) {
      case JVM_CONSTANT_UnresolvedClass: {
        const Symbol* const class_name = cp->klass_name_at(index);
        // check the name
        verify_legal_class_name(class_name, CHECK);
        break;
      }
      case JVM_CONSTANT_NameAndType: {
        if (_need_verify) {
          const int sig_index = cp->signature_ref_index_at(index);
          const int name_index = cp->name_ref_index_at(index);
          const Symbol* const name = cp->symbol_at(name_index);
          const Symbol* const sig = cp->symbol_at(sig_index);
          guarantee_property(sig->utf8_length() != 0,
            "Illegal zero length constant pool entry at %d in class %s",
            sig_index, CHECK);
          guarantee_property(name->utf8_length() != 0,
            "Illegal zero length constant pool entry at %d in class %s",
            name_index, CHECK);

          if (Signature::is_method(sig)) {
            // Format check method name and signature
            verify_legal_method_name(name, CHECK);
            verify_legal_method_signature(name, sig, CHECK);
          } else {
            // Format check field name and signature
            verify_legal_field_name(name, CHECK);
            verify_legal_field_signature(name, sig, CHECK);
          }
        }
        break;
      }
      case JVM_CONSTANT_Dynamic: {
        const int name_and_type_ref_index =
          cp->uncached_name_and_type_ref_index_at(index);
        // already verified to be utf8
        const int name_ref_index =
          cp->name_ref_index_at(name_and_type_ref_index);
        // already verified to be utf8
        const int signature_ref_index =
          cp->signature_ref_index_at(name_and_type_ref_index);
        const Symbol* const name = cp->symbol_at(name_ref_index);
        const Symbol* const signature = cp->symbol_at(signature_ref_index);
        if (_need_verify) {
          // CONSTANT_Dynamic's name and signature are verified above, when iterating NameAndType_info.
          // Need only to be sure signature is the right type.
          if (Signature::is_method(signature)) {
            throwIllegalSignature("CONSTANT_Dynamic", name, signature, CHECK);
          }
        }
        break;
      }
      case JVM_CONSTANT_InvokeDynamic:
      case JVM_CONSTANT_Fieldref:
      case JVM_CONSTANT_Methodref:
      case JVM_CONSTANT_InterfaceMethodref: {
        const int name_and_type_ref_index =
          cp->uncached_name_and_type_ref_index_at(index);
        // already verified to be utf8
        const int name_ref_index =
          cp->name_ref_index_at(name_and_type_ref_index);
        // already verified to be utf8
        const int signature_ref_index =
          cp->signature_ref_index_at(name_and_type_ref_index);
        const Symbol* const name = cp->symbol_at(name_ref_index);
        const Symbol* const signature = cp->symbol_at(signature_ref_index);
        if (tag == JVM_CONSTANT_Fieldref) {
          if (_need_verify) {
            // Field name and signature are verified above, when iterating NameAndType_info.
            // Need only to be sure signature is non-zero length and the right type.
            if (Signature::is_method(signature)) {
              throwIllegalSignature("Field", name, signature, CHECK);
            }
          }
        } else {
          if (_need_verify) {
            // Method name and signature are individually verified above, when iterating
            // NameAndType_info.  Need to check here that signature is non-zero length and
            // the right type.
            if (!Signature::is_method(signature)) {
              throwIllegalSignature("Method", name, signature, CHECK);
            }
          }
          // If a class method name begins with '<', it must be "<init>" and have void signature.
          const unsigned int name_len = name->utf8_length();
          if (tag == JVM_CONSTANT_Methodref && name_len != 0 &&
              name->char_at(0) == JVM_SIGNATURE_SPECIAL) {
            if (name != vmSymbols::object_initializer_name()) {
              classfile_parse_error(
                "Bad method name at constant pool index %u in class file %s",
                name_ref_index, THREAD);
              return;
            } else if (!Signature::is_void_method(signature)) { // must have void signature.
              throwIllegalSignature("Method", name, signature, CHECK);
            }
          }
        }
        break;
      }
      case JVM_CONSTANT_MethodHandle: {
        const int ref_index = cp->method_handle_index_at(index);
        const int ref_kind = cp->method_handle_ref_kind_at(index);
        switch (ref_kind) {
          case JVM_REF_invokeVirtual:
          case JVM_REF_invokeStatic:
          case JVM_REF_invokeSpecial:
          case JVM_REF_newInvokeSpecial: {
            const int name_and_type_ref_index =
              cp->uncached_name_and_type_ref_index_at(ref_index);
            const int name_ref_index =
              cp->name_ref_index_at(name_and_type_ref_index);
            const Symbol* const name = cp->symbol_at(name_ref_index);
            if (ref_kind == JVM_REF_newInvokeSpecial) {
              if (name != vmSymbols::object_initializer_name()) {
                classfile_parse_error(
                  "Bad constructor name at constant pool index %u in class file %s",
                    name_ref_index, THREAD);
                return;
              }
            } else {
              if (name == vmSymbols::object_initializer_name()) {
                classfile_parse_error(
                  "Bad method name at constant pool index %u in class file %s",
                  name_ref_index, THREAD);
                return;
              }
            }
            break;
          }
          // Other ref_kinds are already fully checked in previous pass.
        } // switch(ref_kind)
        break;
      }
      case JVM_CONSTANT_MethodType: {
        const Symbol* const no_name = vmSymbols::type_name(); // place holder
        const Symbol* const signature = cp->method_type_signature_at(index);
        verify_legal_method_signature(no_name, signature, CHECK);
        break;
      }
      case JVM_CONSTANT_Utf8: {
        assert(cp->symbol_at(index)->refcount() != 0, "count corrupted");
      }
    }  // switch(tag)
  }  // end of for
}

class NameSigHash: public ResourceObj {
 public:
  const Symbol*       _name;       // name
  const Symbol*       _sig;        // signature

  static const int HASH_ROW_SIZE = 256;

  NameSigHash(Symbol* name, Symbol* sig) :
    _name(name),
    _sig(sig) {}

  static unsigned int hash(NameSigHash const& namesig) {
    return namesig._name->identity_hash() ^ namesig._sig->identity_hash();
  }

  static bool equals(NameSigHash const& e0, NameSigHash const& e1) {
    return (e0._name == e1._name) &&
          (e0._sig  == e1._sig);
  }
};

using NameSigHashtable = ResourceHashtable<NameSigHash, int,
                                           NameSigHash::HASH_ROW_SIZE,
                                           AnyObj::RESOURCE_AREA, mtInternal,
                                           &NameSigHash::hash, &NameSigHash::equals>;

// Side-effects: populates the _local_interfaces field
void ClassFileParser::parse_interfaces(const ClassFileStream* const stream,
                                       const int itfs_len,
                                       ConstantPool* const cp,
                                       bool* const has_nonstatic_concrete_methods,
                                       TRAPS) {
  assert(stream != nullptr, "invariant");
  assert(cp != nullptr, "invariant");
  assert(has_nonstatic_concrete_methods != nullptr, "invariant");

  if (itfs_len == 0) {
    _local_interfaces = Universe::the_empty_instance_klass_array();
  } else {
    assert(itfs_len > 0, "only called for len>0");
    _local_interfaces = MetadataFactory::new_array<InstanceKlass*>(_loader_data, itfs_len, nullptr, CHECK);

    int index;
    for (index = 0; index < itfs_len; index++) {
      const u2 interface_index = stream->get_u2(CHECK);
      Klass* interf;
      guarantee_property(
        valid_klass_reference_at(interface_index),
        "Interface name has bad constant pool index %u in class file %s",
        interface_index, CHECK);
      if (cp->tag_at(interface_index).is_klass()) {
        interf = cp->resolved_klass_at(interface_index);
      } else {
        Symbol* const unresolved_klass  = cp->klass_name_at(interface_index);

        // Don't need to check legal name because it's checked when parsing constant pool.
        // But need to make sure it's not an array type.
        guarantee_property(unresolved_klass->char_at(0) != JVM_SIGNATURE_ARRAY,
                           "Bad interface name in class file %s", CHECK);

        // Call resolve on the interface class name with class circularity checking
        interf = SystemDictionary::resolve_super_or_fail(_class_name,
                                                         unresolved_klass,
                                                         Handle(THREAD, _loader_data->class_loader()),
                                                         false, CHECK);
      }

      if (!interf->is_interface()) {
        THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),
                  err_msg("class %s can not implement %s, because it is not an interface (%s)",
                          _class_name->as_klass_external_name(),
                          interf->external_name(),
                          interf->class_in_module_of_loader()));
      }

      if (InstanceKlass::cast(interf)->has_nonstatic_concrete_methods()) {
        *has_nonstatic_concrete_methods = true;
      }
      _local_interfaces->at_put(index, InstanceKlass::cast(interf));
    }

    if (!_need_verify || itfs_len <= 1) {
      return;
    }

    // Check if there's any duplicates in interfaces
    ResourceMark rm(THREAD);
    // Set containing interface names
    ResourceHashtable<Symbol*, int>* interface_names = new ResourceHashtable<Symbol*, int>();
    for (index = 0; index < itfs_len; index++) {
      const InstanceKlass* const k = _local_interfaces->at(index);
      Symbol* interface_name = k->name();
      // If no duplicates, add (name, nullptr) in hashtable interface_names.
      if (!interface_names->put(interface_name, 0)) {
        classfile_parse_error("Duplicate interface name \"%s\" in class file %s",
                               interface_name->as_C_string(), THREAD);
        return;
      }
    }
  }
}

void ClassFileParser::verify_constantvalue(const ConstantPool* const cp,
                                           int constantvalue_index,
                                           int signature_index,
                                           TRAPS) const {
  // Make sure the constant pool entry is of a type appropriate to this field
  guarantee_property(
    (constantvalue_index > 0 &&
      constantvalue_index < cp->length()),
    "Bad initial value index %u in ConstantValue attribute in class file %s",
    constantvalue_index, CHECK);

  const constantTag value_type = cp->tag_at(constantvalue_index);
  switch(cp->basic_type_for_signature_at(signature_index)) {
    case T_LONG: {
      guarantee_property(value_type.is_long(),
                         "Inconsistent constant value type in class file %s",
                         CHECK);
      break;
    }
    case T_FLOAT: {
      guarantee_property(value_type.is_float(),
                         "Inconsistent constant value type in class file %s",
                         CHECK);
      break;
    }
    case T_DOUBLE: {
      guarantee_property(value_type.is_double(),
                         "Inconsistent constant value type in class file %s",
                         CHECK);
      break;
    }
    case T_BYTE:
    case T_CHAR:
    case T_SHORT:
    case T_BOOLEAN:
    case T_INT: {
      guarantee_property(value_type.is_int(),
                         "Inconsistent constant value type in class file %s",
                         CHECK);
      break;
    }
    case T_OBJECT: {
      guarantee_property((cp->symbol_at(signature_index)->equals("Ljava/lang/String;")
                         && value_type.is_string()),
                         "Bad string initial value in class file %s",
                         CHECK);
      break;
    }
    default: {
      classfile_parse_error("Unable to set initial value %u in class file %s",
                             constantvalue_index,
                             THREAD);
    }
  }
}

class AnnotationCollector : public ResourceObj{
public:
  enum Location { _in_field, _in_method, _in_class };
  enum ID {
    _unknown = 0,
    _method_CallerSensitive,
    _method_ForceInline,
    _method_DontInline,
    _method_ChangesCurrentThread,
    _method_JvmtiHideEvents,
    _method_JvmtiMountTransition,
    _method_InjectedProfile,
    _method_LambdaForm_Compiled,
    _method_Hidden,
    _method_Scoped,
    _method_IntrinsicCandidate,
    _jdk_internal_vm_annotation_Contended,
    _field_Stable,
    _jdk_internal_vm_annotation_ReservedStackAccess,
    _jdk_internal_ValueBased,
    _java_lang_Deprecated,
    _java_lang_Deprecated_for_removal,
    _annotation_LIMIT
  };
  const Location _location;
  int _annotations_present;
  u2 _contended_group;

  AnnotationCollector(Location location)
    : _location(location), _annotations_present(0), _contended_group(0)
  {
    assert((int)_annotation_LIMIT <= (int)sizeof(_annotations_present) * BitsPerByte, "");
  }
  // If this annotation name has an ID, report it (or _none).
  ID annotation_index(const ClassLoaderData* loader_data, const Symbol* name, bool can_access_vm_annotations);
  // Set the annotation name:
  void set_annotation(ID id) {
    assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
    _annotations_present |= (int)nth_bit((int)id);
  }

  void remove_annotation(ID id) {
    assert((int)id >= 0 && (int)id < (int)_annotation_LIMIT, "oob");
    _annotations_present &= (int)~nth_bit((int)id);
  }

  // Report if the annotation is present.
  bool has_any_annotations() const { return _annotations_present != 0; }
  bool has_annotation(ID id) const { return (nth_bit((int)id) & _annotations_present) != 0; }

  void set_contended_group(u2 group) { _contended_group = group; }
  u2 contended_group() const { return _contended_group; }

  bool is_contended() const { return has_annotation(_jdk_internal_vm_annotation_Contended); }

  void set_stable(bool stable) { set_annotation(_field_Stable); }
  bool is_stable() const { return has_annotation(_field_Stable); }
};

// This class also doubles as a holder for metadata cleanup.
class ClassFileParser::FieldAnnotationCollector : public AnnotationCollector {
private:
  ClassLoaderData* _loader_data;
  AnnotationArray* _field_annotations;
  AnnotationArray* _field_type_annotations;
public:
  FieldAnnotationCollector(ClassLoaderData* loader_data) :
    AnnotationCollector(_in_field),
    _loader_data(loader_data),
    _field_annotations(nullptr),
    _field_type_annotations(nullptr) {}
  ~FieldAnnotationCollector();
  void apply_to(FieldInfo* f);
  AnnotationArray* field_annotations()      { return _field_annotations; }
  AnnotationArray* field_type_annotations() { return _field_type_annotations; }

  void set_field_annotations(AnnotationArray* a)      { _field_annotations = a; }
  void set_field_type_annotations(AnnotationArray* a) { _field_type_annotations = a; }
};

class MethodAnnotationCollector : public AnnotationCollector{
public:
  MethodAnnotationCollector() : AnnotationCollector(_in_method) { }
  void apply_to(const methodHandle& m);
};

class ClassFileParser::ClassAnnotationCollector : public AnnotationCollector{
public:
  ClassAnnotationCollector() : AnnotationCollector(_in_class) { }
  void apply_to(InstanceKlass* ik);
};


static int skip_annotation_value(const u1*, int, int); // fwd decl

// Safely increment index by val if does not pass limit
#define SAFE_ADD(index, limit, val) \
if (index >= limit - val) return limit; \
index += val;

// Skip an annotation.  Return >=limit if there is any problem.
static int skip_annotation(const u1* buffer, int limit, int index) {
  assert(buffer != nullptr, "invariant");
  // annotation := atype:u2 do(nmem:u2) {member:u2 value}
  // value := switch (tag:u1) { ... }
  SAFE_ADD(index, limit, 4); // skip atype and read nmem
  int nmem = Bytes::get_Java_u2((address)buffer + index - 2);
  while (--nmem >= 0 && index < limit) {
    SAFE_ADD(index, limit, 2); // skip member
    index = skip_annotation_value(buffer, limit, index);
  }
  return index;
}

// Skip an annotation value.  Return >=limit if there is any problem.
static int skip_annotation_value(const u1* buffer, int limit, int index) {
  assert(buffer != nullptr, "invariant");

  // value := switch (tag:u1) {
  //   case B, C, I, S, Z, D, F, J, c: con:u2;
  //   case e: e_class:u2 e_name:u2;
  //   case s: s_con:u2;
  //   case [: do(nval:u2) {value};
  //   case @: annotation;
  //   case s: s_con:u2;
  // }
  SAFE_ADD(index, limit, 1); // read tag
  const u1 tag = buffer[index - 1];
  switch (tag) {
    case 'B':
    case 'C':
    case 'I':
    case 'S':
    case 'Z':
    case 'D':
    case 'F':
    case 'J':
    case 'c':
    case 's':
      SAFE_ADD(index, limit, 2);  // skip con or s_con
      break;
    case 'e':
      SAFE_ADD(index, limit, 4);  // skip e_class, e_name
      break;
    case '[':
    {
      SAFE_ADD(index, limit, 2); // read nval
      int nval = Bytes::get_Java_u2((address)buffer + index - 2);
      while (--nval >= 0 && index < limit) {
        index = skip_annotation_value(buffer, limit, index);
      }
    }
    break;
    case '@':
      index = skip_annotation(buffer, limit, index);
      break;
    default:
      return limit;  //  bad tag byte
  }
  return index;
}

// Sift through annotations, looking for those significant to the VM:
static void parse_annotations(const ConstantPool* const cp,
                              const u1* buffer, int limit,
                              AnnotationCollector* coll,
                              ClassLoaderData* loader_data,
                              const bool can_access_vm_annotations) {

  assert(cp != nullptr, "invariant");
  assert(buffer != nullptr, "invariant");
  assert(coll != nullptr, "invariant");
  assert(loader_data != nullptr, "invariant");

  // annotations := do(nann:u2) {annotation}
  int index = 2; // read nann
  if (index >= limit)  return;
  int nann = Bytes::get_Java_u2((address)buffer + index - 2);
  enum {  // initial annotation layout
    atype_off = 0,      // utf8 such as 'Ljava/lang/annotation/Retention;'
    count_off = 2,      // u2   such as 1 (one value)
    member_off = 4,     // utf8 such as 'value'
    tag_off = 6,        // u1   such as 'c' (type) or 'e' (enum)
    e_tag_val = 'e',
    e_type_off = 7,   // utf8 such as 'Ljava/lang/annotation/RetentionPolicy;'
    e_con_off = 9,    // utf8 payload, such as 'SOURCE', 'CLASS', 'RUNTIME'
    e_size = 11,     // end of 'e' annotation
    c_tag_val = 'c',    // payload is type
    c_con_off = 7,    // utf8 payload, such as 'I'
    c_size = 9,       // end of 'c' annotation
    s_tag_val = 's',    // payload is String
    s_con_off = 7,    // utf8 payload, such as 'Ljava/lang/String;'
    s_size = 9,
    b_tag_val = 'Z',  // payload is boolean
    min_size = 6        // smallest possible size (zero members)
  };
  // Cannot add min_size to index in case of overflow MAX_INT
  while ((--nann) >= 0 && (index - 2 <= limit - min_size)) {
    int index0 = index;
    index = skip_annotation(buffer, limit, index);
    const u1* const abase = buffer + index0;
    const int atype = Bytes::get_Java_u2((address)abase + atype_off);
    const int count = Bytes::get_Java_u2((address)abase + count_off);
    const Symbol* const aname = check_symbol_at(cp, atype);
    if (aname == nullptr)  break;  // invalid annotation name
    const Symbol* member = nullptr;
    if (count >= 1) {
      const int member_index = Bytes::get_Java_u2((address)abase + member_off);
      member = check_symbol_at(cp, member_index);
      if (member == nullptr)  break;  // invalid member name
    }

    // Here is where parsing particular annotations will take place.
    AnnotationCollector::ID id = coll->annotation_index(loader_data, aname, can_access_vm_annotations);
    if (AnnotationCollector::_unknown == id)  continue;
    coll->set_annotation(id);
    if (AnnotationCollector::_java_lang_Deprecated == id) {
      // @Deprecated can specify forRemoval=true, which we need
      // to record for JFR to use. If the annotation is not well-formed
      // then we may not be able to determine that.
      const u1* offset = abase + member_off;
      // There are only 2 members in @Deprecated.
      int n_members = MIN2(count, 2);
      for (int i = 0; i < n_members; ++i) {
        int member_index = Bytes::get_Java_u2((address)offset);
        offset += 2;
        member = check_symbol_at(cp, member_index);
        if (member == vmSymbols::since() &&
            (*((address)offset) == s_tag_val)) {
          // Found `since` first so skip over it
          offset += 3;
        }
        else if (member == vmSymbols::for_removal() &&
                 (*((address)offset) == b_tag_val)) {
          const u2 boolean_value_index = Bytes::get_Java_u2((address)offset + 1);
          // No guarantee the entry is valid so check it refers to an int in the CP.
          if (cp->is_within_bounds(boolean_value_index) &&
              cp->tag_at(boolean_value_index).is_int() &&
              cp->int_at(boolean_value_index) == 1) {
            // forRemoval == true
            coll->set_annotation(AnnotationCollector::_java_lang_Deprecated_for_removal);
          }
          break; // no need to check further
        }
        else {
          // This @Deprecated annotation is malformed so we don't try to
          // determine whether forRemoval is set.
          break;
        }
      }
      continue; // proceed to next annotation
    }

    if (AnnotationCollector::_jdk_internal_vm_annotation_Contended == id) {
      // @Contended can optionally specify the contention group.
      //
      // Contended group defines the equivalence class over the fields:
      // the fields within the same contended group are not treated distinct.
      // The only exception is default group, which does not incur the
      // equivalence. Naturally, contention group for classes is meaningless.
      //
      // While the contention group is specified as String, annotation
      // values are already interned, and we might as well use the constant
      // pool index as the group tag.
      //
      u2 group_index = 0; // default contended group
      if (count == 1
        && s_size == (index - index0)  // match size
        && s_tag_val == *(abase + tag_off)
        && member == vmSymbols::value_name()) {
        group_index = Bytes::get_Java_u2((address)abase + s_con_off);
        // No guarantee the group_index is valid so check it refers to a
        // symbol in the CP.
        if (cp->is_within_bounds(group_index) &&
            cp->tag_at(group_index).is_utf8()) {
          // Seems valid, so check for empty string and reset
          if (cp->symbol_at(group_index)->utf8_length() == 0) {
            group_index = 0; // default contended group
          }
        } else {
          // Not valid so use the default
          group_index = 0;
        }
      }
      coll->set_contended_group(group_index);
      continue; // proceed to next annotation
    }
  }
}


// Parse attributes for a field.
void ClassFileParser::parse_field_attributes(const ClassFileStream* const cfs,
                                             u2 attributes_count,
                                             bool is_static, u2 signature_index,
                                             u2* const constantvalue_index_addr,
                                             bool* const is_synthetic_addr,
                                             u2* const generic_signature_index_addr,
                                             ClassFileParser::FieldAnnotationCollector* parsed_annotations,
                                             TRAPS) {
  assert(cfs != nullptr, "invariant");
  assert(constantvalue_index_addr != nullptr, "invariant");
  assert(is_synthetic_addr != nullptr, "invariant");
  assert(generic_signature_index_addr != nullptr, "invariant");
  assert(parsed_annotations != nullptr, "invariant");
  assert(attributes_count > 0, "attributes_count should be greater than 0");

  u2 constantvalue_index = 0;
  u2 generic_signature_index = 0;
  bool is_synthetic = false;
  const u1* runtime_visible_annotations = nullptr;
  int runtime_visible_annotations_length = 0;
  const u1* runtime_visible_type_annotations = nullptr;
  int runtime_visible_type_annotations_length = 0;
  bool runtime_invisible_annotations_exists = false;
  bool runtime_invisible_type_annotations_exists = false;
  const ConstantPool* const cp = _cp;

  while (attributes_count--) {
    cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
    const u2 attribute_name_index = cfs->get_u2_fast();
    const u4 attribute_length = cfs->get_u4_fast();
    guarantee_property(valid_symbol_at(attribute_name_index),
                       "Invalid field attribute index %u in class file %s",
                       attribute_name_index,
                       CHECK);

    const Symbol* const attribute_name = cp->symbol_at(attribute_name_index);
    if (is_static && attribute_name == vmSymbols::tag_constant_value()) {
      // ignore if non-static
      if (constantvalue_index != 0) {
        classfile_parse_error("Duplicate ConstantValue attribute in class file %s", THREAD);
        return;
      }
      guarantee_property(
        attribute_length == 2,
        "Invalid ConstantValue field attribute length %u in class file %s",
        attribute_length, CHECK);

      constantvalue_index = cfs->get_u2(CHECK);
      if (_need_verify) {
        verify_constantvalue(cp, constantvalue_index, signature_index, CHECK);
      }
    } else if (attribute_name == vmSymbols::tag_synthetic()) {
      if (attribute_length != 0) {
        classfile_parse_error(
          "Invalid Synthetic field attribute length %u in class file %s",
          attribute_length, THREAD);
        return;
      }
      is_synthetic = true;
    } else if (attribute_name == vmSymbols::tag_deprecated()) { // 4276120
      if (attribute_length != 0) {
        classfile_parse_error(
          "Invalid Deprecated field attribute length %u in class file %s",
          attribute_length, THREAD);
        return;
      }
    } else if (_major_version >= JAVA_1_5_VERSION) {
      if (attribute_name == vmSymbols::tag_signature()) {
        if (generic_signature_index != 0) {
          classfile_parse_error(
            "Multiple Signature attributes for field in class file %s", THREAD);
          return;
        }
        if (attribute_length != 2) {
          classfile_parse_error(
            "Wrong size %u for field's Signature attribute in class file %s",
            attribute_length, THREAD);
          return;
        }
        generic_signature_index = parse_generic_signature_attribute(cfs, CHECK);
      } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
        if (runtime_visible_annotations != nullptr) {
          classfile_parse_error(
            "Multiple RuntimeVisibleAnnotations attributes for field in class file %s", THREAD);
          return;
        }
        runtime_visible_annotations_length = attribute_length;
        runtime_visible_annotations = cfs->current();
        assert(runtime_visible_annotations != nullptr, "null visible annotations");
        cfs->guarantee_more(runtime_visible_annotations_length, CHECK);
        parse_annotations(cp,
                          runtime_visible_annotations,
                          runtime_visible_annotations_length,
                          parsed_annotations,
                          _loader_data,
                          _can_access_vm_annotations);
        cfs->skip_u1_fast(runtime_visible_annotations_length);
      } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
        if (runtime_invisible_annotations_exists) {
          classfile_parse_error(
            "Multiple RuntimeInvisibleAnnotations attributes for field in class file %s", THREAD);
          return;
        }
        runtime_invisible_annotations_exists = true;
        cfs->skip_u1(attribute_length, CHECK);
      } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
        if (runtime_visible_type_annotations != nullptr) {
          classfile_parse_error(
            "Multiple RuntimeVisibleTypeAnnotations attributes for field in class file %s", THREAD);
          return;
        }
        runtime_visible_type_annotations_length = attribute_length;
        runtime_visible_type_annotations = cfs->current();
        assert(runtime_visible_type_annotations != nullptr, "null visible type annotations");
        cfs->skip_u1(runtime_visible_type_annotations_length, CHECK);
      } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
        if (runtime_invisible_type_annotations_exists) {
          classfile_parse_error(
            "Multiple RuntimeInvisibleTypeAnnotations attributes for field in class file %s", THREAD);
          return;
        } else {
          runtime_invisible_type_annotations_exists = true;
        }
        cfs->skip_u1(attribute_length, CHECK);
      } else {
        cfs->skip_u1(attribute_length, CHECK);  // Skip unknown attributes
      }
    } else {
      cfs->skip_u1(attribute_length, CHECK);  // Skip unknown attributes
    }
  }

  *constantvalue_index_addr = constantvalue_index;
  *is_synthetic_addr = is_synthetic;
  *generic_signature_index_addr = generic_signature_index;
  AnnotationArray* a = allocate_annotations(runtime_visible_annotations,
                                            runtime_visible_annotations_length,
                                            CHECK);
  parsed_annotations->set_field_annotations(a);
  a = allocate_annotations(runtime_visible_type_annotations,
                           runtime_visible_type_annotations_length,
                           CHECK);
  parsed_annotations->set_field_type_annotations(a);
  return;
}


// Side-effects: populates the _fields, _fields_annotations,
// _fields_type_annotations fields
void ClassFileParser::parse_fields(const ClassFileStream* const cfs,
                                   bool is_interface,
                                   ConstantPool* cp,
                                   const int cp_size,
                                   u2* const java_fields_count_ptr,
                                   TRAPS) {

  assert(cfs != nullptr, "invariant");
  assert(cp != nullptr, "invariant");
  assert(java_fields_count_ptr != nullptr, "invariant");

  assert(nullptr == _fields_annotations, "invariant");
  assert(nullptr == _fields_type_annotations, "invariant");

  cfs->guarantee_more(2, CHECK);  // length
  const u2 length = cfs->get_u2_fast();
  *java_fields_count_ptr = length;

  int num_injected = 0;
  const InjectedField* const injected = JavaClasses::get_injected(_class_name,
                                                                  &num_injected);
  const int total_fields = length + num_injected;

  // Allocate a temporary resource array to collect field data.
  // After parsing all fields, data are stored in a UNSIGNED5 compressed stream.
  _temp_field_info = new GrowableArray<FieldInfo>(total_fields);

  ResourceMark rm(THREAD);
  for (int n = 0; n < length; n++) {
    // access_flags, name_index, descriptor_index, attributes_count
    cfs->guarantee_more(8, CHECK);

    AccessFlags access_flags;
    const jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_FIELD_MODIFIERS;
    verify_legal_field_modifiers(flags, is_interface, CHECK);
    access_flags.set_flags(flags);
    FieldInfo::FieldFlags fieldFlags(0);

    const u2 name_index = cfs->get_u2_fast();
    guarantee_property(valid_symbol_at(name_index),
      "Invalid constant pool index %u for field name in class file %s",
      name_index, CHECK);
    const Symbol* const name = cp->symbol_at(name_index);
    verify_legal_field_name(name, CHECK);

    const u2 signature_index = cfs->get_u2_fast();
    guarantee_property(valid_symbol_at(signature_index),
      "Invalid constant pool index %u for field signature in class file %s",
      signature_index, CHECK);
    const Symbol* const sig = cp->symbol_at(signature_index);
    verify_legal_field_signature(name, sig, CHECK);

    u2 constantvalue_index = 0;
    bool is_synthetic = false;
    u2 generic_signature_index = 0;
    const bool is_static = access_flags.is_static();
    FieldAnnotationCollector parsed_annotations(_loader_data);

    const u2 attributes_count = cfs->get_u2_fast();
    if (attributes_count > 0) {
      parse_field_attributes(cfs,
                             attributes_count,
                             is_static,
                             signature_index,
                             &constantvalue_index,
                             &is_synthetic,
                             &generic_signature_index,
                             &parsed_annotations,
                             CHECK);

      if (parsed_annotations.field_annotations() != nullptr) {
        if (_fields_annotations == nullptr) {
          _fields_annotations = MetadataFactory::new_array<AnnotationArray*>(
                                             _loader_data, length, nullptr,
                                             CHECK);
        }
        _fields_annotations->at_put(n, parsed_annotations.field_annotations());
        parsed_annotations.set_field_annotations(nullptr);
      }
      if (parsed_annotations.field_type_annotations() != nullptr) {
        if (_fields_type_annotations == nullptr) {
          _fields_type_annotations =
            MetadataFactory::new_array<AnnotationArray*>(_loader_data,
                                                         length,
                                                         nullptr,
                                                         CHECK);
        }
        _fields_type_annotations->at_put(n, parsed_annotations.field_type_annotations());
        parsed_annotations.set_field_type_annotations(nullptr);
      }

      if (is_synthetic) {
        access_flags.set_is_synthetic();
      }
      if (generic_signature_index != 0) {
        fieldFlags.update_generic(true);
      }
    }

    const BasicType type = cp->basic_type_for_signature_at(signature_index);

    // Update number of static oop fields.
    if (is_static && is_reference_type(type)) {
      _static_oop_count++;
    }

    FieldInfo fi(access_flags, name_index, signature_index, constantvalue_index, fieldFlags);
    fi.set_index(n);
    if (fieldFlags.is_generic()) {
      fi.set_generic_signature_index(generic_signature_index);
    }
    parsed_annotations.apply_to(&fi);
    if (fi.field_flags().is_contended()) {
      _has_contended_fields = true;
    }
    _temp_field_info->append(fi);
  }
  assert(_temp_field_info->length() == length, "Must be");

  int index = length;
  if (num_injected != 0) {
    for (int n = 0; n < num_injected; n++) {
      // Check for duplicates
      if (injected[n].may_be_java) {
        const Symbol* const name      = injected[n].name();
        const Symbol* const signature = injected[n].signature();
        bool duplicate = false;
        for (int i = 0; i < length; i++) {
          const FieldInfo* const f = _temp_field_info->adr_at(i);
          if (name      == cp->symbol_at(f->name_index()) &&
              signature == cp->symbol_at(f->signature_index())) {
            // Symbol is desclared in Java so skip this one
            duplicate = true;
            break;
          }
        }
        if (duplicate) {
          // These will be removed from the field array at the end
          continue;
        }
      }

      // Injected field
      FieldInfo::FieldFlags fflags(0);
      fflags.update_injected(true);
      AccessFlags aflags;
      FieldInfo fi(aflags, (u2)(injected[n].name_index), (u2)(injected[n].signature_index), 0, fflags);
      fi.set_index(index);
      _temp_field_info->append(fi);
      index++;
    }
  }

  assert(_temp_field_info->length() == index, "Must be");

  if (_need_verify && length > 1) {
    // Check duplicated fields
    ResourceMark rm(THREAD);
    // Set containing name-signature pairs
    NameSigHashtable* names_and_sigs = new NameSigHashtable();
    for (int i = 0; i < _temp_field_info->length(); i++) {
      NameSigHash name_and_sig(_temp_field_info->adr_at(i)->name(_cp),
                               _temp_field_info->adr_at(i)->signature(_cp));
      // If no duplicates, add name/signature in hashtable names_and_sigs.
      if(!names_and_sigs->put(name_and_sig, 0)) {
        classfile_parse_error("Duplicate field name \"%s\" with signature \"%s\" in class file %s",
                               name_and_sig._name->as_C_string(), name_and_sig._sig->as_klass_external_name(), THREAD);
        return;
      }
    }
  }
}


const ClassFileParser::unsafe_u2* ClassFileParser::parse_exception_table(const ClassFileStream* const cfs,
                                                                         u4 code_length,
                                                                         u4 exception_table_length,
                                                                         TRAPS) {
  assert(cfs != nullptr, "invariant");

  const unsafe_u2* const exception_table_start = cfs->current();
  assert(exception_table_start != nullptr, "null exception table");

  cfs->guarantee_more(8 * exception_table_length, CHECK_NULL); // start_pc,
                                                               // end_pc,
                                                               // handler_pc,
                                                               // catch_type_index

  // Will check legal target after parsing code array in verifier.
  if (_need_verify) {
    for (unsigned int i = 0; i < exception_table_length; i++) {
      const u2 start_pc = cfs->get_u2_fast();
      const u2 end_pc = cfs->get_u2_fast();
      const u2 handler_pc = cfs->get_u2_fast();
      const u2 catch_type_index = cfs->get_u2_fast();
      guarantee_property((start_pc < end_pc) && (end_pc <= code_length),
                         "Illegal exception table range in class file %s",
                         CHECK_NULL);
      guarantee_property(handler_pc < code_length,
                         "Illegal exception table handler in class file %s",
                         CHECK_NULL);
      if (catch_type_index != 0) {
        guarantee_property(valid_klass_reference_at(catch_type_index),
                           "Catch type in exception table has bad constant type in class file %s", CHECK_NULL);
      }
    }
  } else {
    cfs->skip_u2_fast(exception_table_length * 4);
  }
  return exception_table_start;
}

void ClassFileParser::parse_linenumber_table(u4 code_attribute_length,
                                             u4 code_length,
                                             CompressedLineNumberWriteStream**const write_stream,
                                             TRAPS) {

  const ClassFileStream* const cfs = _stream;
  unsigned int num_entries = cfs->get_u2(CHECK);

  // Each entry is a u2 start_pc, and a u2 line_number
  const unsigned int length_in_bytes = num_entries * (sizeof(u2) * 2);

  // Verify line number attribute and table length
  guarantee_property(
    code_attribute_length == sizeof(u2) + length_in_bytes,
    "LineNumberTable attribute has wrong length in class file %s", CHECK);

  cfs->guarantee_more(length_in_bytes, CHECK);

  if ((*write_stream) == nullptr) {
    if (length_in_bytes > fixed_buffer_size) {
      (*write_stream) = new CompressedLineNumberWriteStream(length_in_bytes);
    } else {
      (*write_stream) = new CompressedLineNumberWriteStream(
        _linenumbertable_buffer, fixed_buffer_size);
    }
  }

  while (num_entries-- > 0) {
    const u2 bci  = cfs->get_u2_fast(); // start_pc
    const u2 line = cfs->get_u2_fast(); // line_number
    guarantee_property(bci < code_length,
        "Invalid pc in LineNumberTable in class file %s", CHECK);
    (*write_stream)->write_pair(bci, line);
  }
}


class LVT_Hash : public AllStatic {
 public:

  static bool equals(LocalVariableTableElement const& e0, LocalVariableTableElement const& e1) {
  /*
   * 3-tuple start_bci/length/slot has to be unique key,
   * so the following comparison seems to be redundant:
   *       && elem->name_cp_index == entry->_elem->name_cp_index
   */
    return (e0.start_bci     == e1.start_bci &&
            e0.length        == e1.length &&
            e0.name_cp_index == e1.name_cp_index &&
            e0.slot          == e1.slot);
  }

  static unsigned int hash(LocalVariableTableElement const& e0) {
    unsigned int raw_hash = e0.start_bci;

    raw_hash = e0.length        + raw_hash * 37;
    raw_hash = e0.name_cp_index + raw_hash * 37;
    raw_hash = e0.slot          + raw_hash * 37;

    return raw_hash;
  }
};


// Class file LocalVariableTable elements.
class Classfile_LVT_Element {
 public:
  u2 start_bci;
  u2 length;
  u2 name_cp_index;
  u2 descriptor_cp_index;
  u2 slot;
};

static void copy_lvt_element(const Classfile_LVT_Element* const src,
                             LocalVariableTableElement* const lvt) {
  lvt->start_bci           = Bytes::get_Java_u2((u1*) &src->start_bci);
  lvt->length              = Bytes::get_Java_u2((u1*) &src->length);
  lvt->name_cp_index       = Bytes::get_Java_u2((u1*) &src->name_cp_index);
  lvt->descriptor_cp_index = Bytes::get_Java_u2((u1*) &src->descriptor_cp_index);
  lvt->signature_cp_index  = 0;
  lvt->slot                = Bytes::get_Java_u2((u1*) &src->slot);
}

// Function is used to parse both attributes:
// LocalVariableTable (LVT) and LocalVariableTypeTable (LVTT)
const ClassFileParser::unsafe_u2* ClassFileParser::parse_localvariable_table(const ClassFileStream* cfs,
                                                                             u4 code_length,
                                                                             u2 max_locals,
                                                                             u4 code_attribute_length,
                                                                             u2* const localvariable_table_length,
                                                                             bool isLVTT,
                                                                             TRAPS) {
  const char* const tbl_name = (isLVTT) ? "LocalVariableTypeTable" : "LocalVariableTable";
  *localvariable_table_length = cfs->get_u2(CHECK_NULL);
  const unsigned int size = checked_cast<unsigned>(
    (*localvariable_table_length) * sizeof(Classfile_LVT_Element) / sizeof(u2));

  const ConstantPool* const cp = _cp;

  // Verify local variable table attribute has right length
  if (_need_verify) {
    guarantee_property(code_attribute_length == (sizeof(*localvariable_table_length) + size * sizeof(u2)),
                       "%s has wrong length in class file %s", tbl_name, CHECK_NULL);
  }

  const unsafe_u2* const localvariable_table_start = cfs->current();
  assert(localvariable_table_start != nullptr, "null local variable table");
  if (!_need_verify) {
    cfs->skip_u2_fast(size);
  } else {
    cfs->guarantee_more(size * 2, CHECK_NULL);
    for(int i = 0; i < (*localvariable_table_length); i++) {
      const u2 start_pc = cfs->get_u2_fast();
      const u2 length = cfs->get_u2_fast();
      const u2 name_index = cfs->get_u2_fast();
      const u2 descriptor_index = cfs->get_u2_fast();
      const u2 index = cfs->get_u2_fast();
      // Assign to a u4 to avoid overflow
      const u4 end_pc = (u4)start_pc + (u4)length;

      if (start_pc >= code_length) {
        classfile_parse_error(
          "Invalid start_pc %u in %s in class file %s",
          start_pc, tbl_name, THREAD);
        return nullptr;
      }
      if (end_pc > code_length) {
        classfile_parse_error(
          "Invalid length %u in %s in class file %s",
          length, tbl_name, THREAD);
        return nullptr;
      }
      const int cp_size = cp->length();
      guarantee_property(valid_symbol_at(name_index),
        "Name index %u in %s has bad constant type in class file %s",
        name_index, tbl_name, CHECK_NULL);
      guarantee_property(valid_symbol_at(descriptor_index),
        "Signature index %u in %s has bad constant type in class file %s",
        descriptor_index, tbl_name, CHECK_NULL);

      const Symbol* const name = cp->symbol_at(name_index);
      const Symbol* const sig = cp->symbol_at(descriptor_index);
      verify_legal_field_name(name, CHECK_NULL);
      u2 extra_slot = 0;
      if (!isLVTT) {
        verify_legal_field_signature(name, sig, CHECK_NULL);

        // 4894874: check special cases for double and long local variables
        if (sig == vmSymbols::type_signature(T_DOUBLE) ||
            sig == vmSymbols::type_signature(T_LONG)) {
          extra_slot = 1;
        }
      }
      guarantee_property((index + extra_slot) < max_locals,
                          "Invalid index %u in %s in class file %s",
                          index, tbl_name, CHECK_NULL);
    }
  }
  return localvariable_table_start;
}

static const u1* parse_stackmap_table(const ClassFileStream* const cfs,
                                      u4 code_attribute_length,
                                      TRAPS) {
  assert(cfs != nullptr, "invariant");

  if (0 == code_attribute_length) {
    return nullptr;
  }

  const u1* const stackmap_table_start = cfs->current();
  assert(stackmap_table_start != nullptr, "null stackmap table");

  // check code_attribute_length
  cfs->skip_u1(code_attribute_length, CHECK_NULL);

  return stackmap_table_start;
}

const ClassFileParser::unsafe_u2* ClassFileParser::parse_checked_exceptions(const ClassFileStream* const cfs,
                                                                            u2* const checked_exceptions_length,
                                                                            u4 method_attribute_length,
                                                                            TRAPS) {
  assert(cfs != nullptr, "invariant");
  assert(checked_exceptions_length != nullptr, "invariant");

  cfs->guarantee_more(2, CHECK_NULL);  // checked_exceptions_length
  *checked_exceptions_length = cfs->get_u2_fast();
  const unsigned int size =
    (*checked_exceptions_length) * sizeof(CheckedExceptionElement) / sizeof(u2);
  const unsafe_u2* const checked_exceptions_start = cfs->current();
  assert(checked_exceptions_start != nullptr, "null checked exceptions");
  if (!_need_verify) {
    cfs->skip_u2_fast(size);
  } else {
    // Verify each value in the checked exception table
    u2 checked_exception;
    const u2 len = *checked_exceptions_length;
    cfs->guarantee_more(2 * len, CHECK_NULL);
    for (int i = 0; i < len; i++) {
      checked_exception = cfs->get_u2_fast();
      guarantee_property(
        valid_klass_reference_at(checked_exception),
        "Exception name has bad type at constant pool %u in class file %s",
        checked_exception, CHECK_NULL);
    }
  }
  // check exceptions attribute length
  if (_need_verify) {
    guarantee_property(method_attribute_length == (sizeof(*checked_exceptions_length) +
                                                   sizeof(u2) * size),
                      "Exceptions attribute has wrong length in class file %s", CHECK_NULL);
  }
  return checked_exceptions_start;
}

void ClassFileParser::throwIllegalSignature(const char* type,
                                            const Symbol* name,
                                            const Symbol* sig,
                                            TRAPS) const {
  assert(name != nullptr, "invariant");
  assert(sig != nullptr, "invariant");

  ResourceMark rm(THREAD);
  // Names are all known to be < 64k so we know this formatted message is not excessively large.
  Exceptions::fthrow(THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "%s \"%s\" in class %s has illegal signature \"%s\"", type,
      name->as_C_string(), _class_name->as_C_string(), sig->as_C_string());
}

AnnotationCollector::ID
AnnotationCollector::annotation_index(const ClassLoaderData* loader_data,
                                      const Symbol* name,
                                      const bool can_access_vm_annotations) {
  const vmSymbolID sid = vmSymbols::find_sid(name);
  // Privileged code can use all annotations.  Other code silently drops some.
  const bool privileged = loader_data->is_boot_class_loader_data() ||
                          loader_data->is_platform_class_loader_data() ||
                          can_access_vm_annotations;
  switch (sid) {
    case VM_SYMBOL_ENUM_NAME(reflect_CallerSensitive_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_CallerSensitive;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_ForceInline_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_ForceInline;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_DontInline_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_DontInline;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_ChangesCurrentThread_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_ChangesCurrentThread;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_JvmtiHideEvents_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_JvmtiHideEvents;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_JvmtiMountTransition_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_JvmtiMountTransition;
    }
    case VM_SYMBOL_ENUM_NAME(java_lang_invoke_InjectedProfile_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_InjectedProfile;
    }
    case VM_SYMBOL_ENUM_NAME(java_lang_invoke_LambdaForm_Compiled_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_LambdaForm_Compiled;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_Hidden_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_Hidden;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_misc_Scoped_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_Scoped;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_IntrinsicCandidate_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (!privileged)              break;  // only allow in privileged code
      return _method_IntrinsicCandidate;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_Stable_signature): {
      if (_location != _in_field)   break;  // only allow for fields
      if (!privileged)              break;  // only allow in privileged code
      return _field_Stable;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_Contended_signature): {
      if (_location != _in_field && _location != _in_class) {
        break;  // only allow for fields and classes
      }
      if (!EnableContended || (RestrictContended && !privileged)) {
        break;  // honor privileges
      }
      return _jdk_internal_vm_annotation_Contended;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_vm_annotation_ReservedStackAccess_signature): {
      if (_location != _in_method)  break;  // only allow for methods
      if (RestrictReservedStack && !privileged) break; // honor privileges
      return _jdk_internal_vm_annotation_ReservedStackAccess;
    }
    case VM_SYMBOL_ENUM_NAME(jdk_internal_ValueBased_signature): {
      if (_location != _in_class)   break;  // only allow for classes
      if (!privileged)              break;  // only allow in privileged code
      return _jdk_internal_ValueBased;
    }
    case VM_SYMBOL_ENUM_NAME(java_lang_Deprecated): {
      return _java_lang_Deprecated;
    }
    default: {
      break;
    }
  }
  return AnnotationCollector::_unknown;
}

void ClassFileParser::FieldAnnotationCollector::apply_to(FieldInfo* f) {
  if (is_contended())
    // Setting the contended group also sets the contended bit in field flags
    f->set_contended_group(contended_group());
  if (is_stable())
    (f->field_flags_addr())->update_stable(true);
}

ClassFileParser::FieldAnnotationCollector::~FieldAnnotationCollector() {
  // If there's an error deallocate metadata for field annotations
  MetadataFactory::free_array<u1>(_loader_data, _field_annotations);
  MetadataFactory::free_array<u1>(_loader_data, _field_type_annotations);
}

void MethodAnnotationCollector::apply_to(const methodHandle& m) {
  if (has_annotation(_method_CallerSensitive))
    m->set_caller_sensitive();
  if (has_annotation(_method_ForceInline))
    m->set_force_inline();
  if (has_annotation(_method_DontInline))
    m->set_dont_inline();
  if (has_annotation(_method_ChangesCurrentThread))
    m->set_changes_current_thread();
  if (has_annotation(_method_JvmtiHideEvents))
    m->set_jvmti_hide_events();
  if (has_annotation(_method_JvmtiMountTransition))
    m->set_jvmti_mount_transition();
  if (has_annotation(_method_InjectedProfile))
    m->set_has_injected_profile();
  if (has_annotation(_method_LambdaForm_Compiled) && m->intrinsic_id() == vmIntrinsics::_none)
    m->set_intrinsic_id(vmIntrinsics::_compiledLambdaForm);
  if (has_annotation(_method_Hidden))
    m->set_is_hidden();
  if (has_annotation(_method_Scoped))
    m->set_scoped();
  if (has_annotation(_method_IntrinsicCandidate) && !m->is_synthetic())
    m->set_intrinsic_candidate();
  if (has_annotation(_jdk_internal_vm_annotation_ReservedStackAccess))
    m->set_has_reserved_stack_access();
  if (has_annotation(_java_lang_Deprecated))
    m->set_deprecated();
  if (has_annotation(_java_lang_Deprecated_for_removal))
    m->set_deprecated_for_removal();
}

void ClassFileParser::ClassAnnotationCollector::apply_to(InstanceKlass* ik) {
  assert(ik != nullptr, "invariant");
  if (has_annotation(_jdk_internal_vm_annotation_Contended)) {
    ik->set_is_contended(is_contended());
  }
  if (has_annotation(_jdk_internal_ValueBased)) {
    ik->set_has_value_based_class_annotation();
    if (DiagnoseSyncOnValueBasedClasses) {
      ik->set_is_value_based();
    }
  }
  if (has_annotation(_java_lang_Deprecated)) {
    Array<Method*>* methods = ik->methods();
    int length = ik->methods()->length();
    for (int i = 0; i < length; i++) {
      Method* m = methods->at(i);
      m->set_deprecated();
    }
  }
  if (has_annotation(_java_lang_Deprecated_for_removal)) {
    Array<Method*>* methods = ik->methods();
    int length = ik->methods()->length();
    for (int i = 0; i < length; i++) {
      Method* m = methods->at(i);
      m->set_deprecated_for_removal();
    }
  }
}

#define MAX_ARGS_SIZE 255
#define MAX_CODE_SIZE 65535
#define INITIAL_MAX_LVT_NUMBER 256

/* Copy class file LVT's/LVTT's into the HotSpot internal LVT.
 *
 * Rules for LVT's and LVTT's are:
 *   - There can be any number of LVT's and LVTT's.
 *   - If there are n LVT's, it is the same as if there was just
 *     one LVT containing all the entries from the n LVT's.
 *   - There may be no more than one LVT entry per local variable.
 *     Two LVT entries are 'equal' if these fields are the same:
 *        start_pc, length, name, slot
 *   - There may be no more than one LVTT entry per each LVT entry.
 *     Each LVTT entry has to match some LVT entry.
 *   - HotSpot internal LVT keeps natural ordering of class file LVT entries.
 */
void ClassFileParser::copy_localvariable_table(const ConstMethod* cm,
                                               int lvt_cnt,
                                               u2* const localvariable_table_length,
                                               const unsafe_u2** const localvariable_table_start,
                                               int lvtt_cnt,
                                               u2* const localvariable_type_table_length,
                                               const unsafe_u2** const localvariable_type_table_start,
                                               TRAPS) {

  ResourceMark rm(THREAD);

  typedef ResourceHashtable<LocalVariableTableElement, LocalVariableTableElement*,
                            256, AnyObj::RESOURCE_AREA, mtInternal,
                            &LVT_Hash::hash, &LVT_Hash::equals> LVT_HashTable;

  LVT_HashTable* const table = new LVT_HashTable();

  // To fill LocalVariableTable in
  const Classfile_LVT_Element* cf_lvt;
  LocalVariableTableElement* lvt = cm->localvariable_table_start();

  for (int tbl_no = 0; tbl_no < lvt_cnt; tbl_no++) {
    cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no];
    for (int idx = 0; idx < localvariable_table_length[tbl_no]; idx++, lvt++) {
      copy_lvt_element(&cf_lvt[idx], lvt);
      // If no duplicates, add LVT elem in hashtable.
      if (table->put(*lvt, lvt) == false
          && _need_verify
          && _major_version >= JAVA_1_5_VERSION) {
        classfile_parse_error("Duplicated LocalVariableTable attribute "
                              "entry for '%s' in class file %s",
                               _cp->symbol_at(lvt->name_cp_index)->as_utf8(),
                               THREAD);
        return;
      }
    }
  }

  // To merge LocalVariableTable and LocalVariableTypeTable
  const Classfile_LVT_Element* cf_lvtt;
  LocalVariableTableElement lvtt_elem;

  for (int tbl_no = 0; tbl_no < lvtt_cnt; tbl_no++) {
    cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no];
    for (int idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) {
      copy_lvt_element(&cf_lvtt[idx], &lvtt_elem);
      LocalVariableTableElement** entry = table->get(lvtt_elem);
      if (entry == nullptr) {
        if (_need_verify) {
          classfile_parse_error("LVTT entry for '%s' in class file %s "
                                "does not match any LVT entry",
                                 _cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
                                 THREAD);
          return;
        }
      } else if ((*entry)->signature_cp_index != 0 && _need_verify) {
        classfile_parse_error("Duplicated LocalVariableTypeTable attribute "
                              "entry for '%s' in class file %s",
                               _cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
                               THREAD);
        return;
      } else {
        // to add generic signatures into LocalVariableTable
        (*entry)->signature_cp_index = lvtt_elem.descriptor_cp_index;
      }
    }
  }
}


void ClassFileParser::copy_method_annotations(ConstMethod* cm,
                                       const u1* runtime_visible_annotations,
                                       int runtime_visible_annotations_length,
                                       const u1* runtime_visible_parameter_annotations,
                                       int runtime_visible_parameter_annotations_length,
                                       const u1* runtime_visible_type_annotations,
                                       int runtime_visible_type_annotations_length,
                                       const u1* annotation_default,
                                       int annotation_default_length,
                                       TRAPS) {

  AnnotationArray* a;

  if (runtime_visible_annotations_length > 0) {
     a = allocate_annotations(runtime_visible_annotations,
                              runtime_visible_annotations_length,
                              CHECK);
     cm->set_method_annotations(a);
  }

  if (runtime_visible_parameter_annotations_length > 0) {
    a = allocate_annotations(runtime_visible_parameter_annotations,
                             runtime_visible_parameter_annotations_length,
                             CHECK);
    cm->set_parameter_annotations(a);
  }

  if (annotation_default_length > 0) {
    a = allocate_annotations(annotation_default,
                             annotation_default_length,
                             CHECK);
    cm->set_default_annotations(a);
  }

  if (runtime_visible_type_annotations_length > 0) {
    a = allocate_annotations(runtime_visible_type_annotations,
                             runtime_visible_type_annotations_length,
                             CHECK);
    cm->set_type_annotations(a);
  }
}


// Note: the parse_method below is big and clunky because all parsing of the code and exceptions
// attribute is inlined. This is cumbersome to avoid since we inline most of the parts in the
// Method* to save footprint, so we only know the size of the resulting Method* when the
// entire method attribute is parsed.
//
// The has_localvariable_table parameter is used to pass up the value to InstanceKlass.

Method* ClassFileParser::parse_method(const ClassFileStream* const cfs,
                                      bool is_interface,
                                      const ConstantPool* cp,
                                      bool* const has_localvariable_table,
                                      TRAPS) {
  assert(cfs != nullptr, "invariant");
  assert(cp != nullptr, "invariant");
  assert(has_localvariable_table != nullptr, "invariant");

  ResourceMark rm(THREAD);
  // Parse fixed parts:
  // access_flags, name_index, descriptor_index, attributes_count
  cfs->guarantee_more(8, CHECK_NULL);

  u2 flags = cfs->get_u2_fast();
  const u2 name_index = cfs->get_u2_fast();
  const int cp_size = cp->length();
  guarantee_property(
    valid_symbol_at(name_index),
    "Illegal constant pool index %u for method name in class file %s",
    name_index, CHECK_NULL);
  const Symbol* const name = cp->symbol_at(name_index);
  verify_legal_method_name(name, CHECK_NULL);

  const u2 signature_index = cfs->get_u2_fast();
  guarantee_property(
    valid_symbol_at(signature_index),
    "Illegal constant pool index %u for method signature in class file %s",
    signature_index, CHECK_NULL);
  const Symbol* const signature = cp->symbol_at(signature_index);

  if (name == vmSymbols::class_initializer_name()) {
    // We ignore the other access flags for a valid class initializer.
    // (JVM Spec 2nd ed., chapter 4.6)
    if (_major_version < 51) { // backward compatibility
      flags = JVM_ACC_STATIC;
    } else if ((flags & JVM_ACC_STATIC) == JVM_ACC_STATIC) {
      flags &= JVM_ACC_STATIC | (_major_version <= JAVA_16_VERSION ? JVM_ACC_STRICT : 0);
    } else {
      classfile_parse_error("Method <clinit> is not static in class file %s", THREAD);
      return nullptr;
    }
  } else {
    verify_legal_method_modifiers(flags, is_interface, name, CHECK_NULL);
  }

  if (name == vmSymbols::object_initializer_name() && is_interface) {
    classfile_parse_error("Interface cannot have a method named <init>, class file %s", THREAD);
    return nullptr;
  }

  int args_size = -1;  // only used when _need_verify is true
  if (_need_verify) {
    verify_legal_name_with_signature(name, signature, CHECK_NULL);
    args_size = ((flags & JVM_ACC_STATIC) ? 0 : 1) +
                 verify_legal_method_signature(name, signature, CHECK_NULL);
    if (args_size > MAX_ARGS_SIZE) {
      classfile_parse_error("Too many arguments in method signature in class file %s", THREAD);
      return nullptr;
    }
  }

  AccessFlags access_flags(flags & JVM_RECOGNIZED_METHOD_MODIFIERS);

  // Default values for code and exceptions attribute elements
  u2 max_stack = 0;
  u2 max_locals = 0;
  u4 code_length = 0;
  const u1* code_start = nullptr;
  u2 exception_table_length = 0;
  const unsafe_u2* exception_table_start = nullptr; // (potentially unaligned) pointer to array of u2 elements
  Array<int>* exception_handlers = Universe::the_empty_int_array();
  u2 checked_exceptions_length = 0;
  const unsafe_u2* checked_exceptions_start = nullptr; // (potentially unaligned) pointer to array of u2 elements
  CompressedLineNumberWriteStream* linenumber_table = nullptr;
  int linenumber_table_length = 0;
  int total_lvt_length = 0;
  u2 lvt_cnt = 0;
  u2 lvtt_cnt = 0;
  bool lvt_allocated = false;
  u2 max_lvt_cnt = INITIAL_MAX_LVT_NUMBER;
  u2 max_lvtt_cnt = INITIAL_MAX_LVT_NUMBER;
  u2* localvariable_table_length = nullptr;
  const unsafe_u2** localvariable_table_start = nullptr; // (potentially unaligned) pointer to array of LVT attributes
  u2* localvariable_type_table_length = nullptr;
  const unsafe_u2** localvariable_type_table_start = nullptr; // (potentially unaligned) pointer to LVTT attributes
  int method_parameters_length = -1;
  const u1* method_parameters_data = nullptr;
  bool method_parameters_seen = false;
  bool parsed_code_attribute = false;
  bool parsed_checked_exceptions_attribute = false;
  bool parsed_stackmap_attribute = false;
  // stackmap attribute - JDK1.5
  const u1* stackmap_data = nullptr;
  int stackmap_data_length = 0;
  u2 generic_signature_index = 0;
  MethodAnnotationCollector parsed_annotations;
  const u1* runtime_visible_annotations = nullptr;
  int runtime_visible_annotations_length = 0;
  const u1* runtime_visible_parameter_annotations = nullptr;
  int runtime_visible_parameter_annotations_length = 0;
  const u1* runtime_visible_type_annotations = nullptr;
  int runtime_visible_type_annotations_length = 0;
  bool runtime_invisible_annotations_exists = false;
  bool runtime_invisible_type_annotations_exists = false;
  bool runtime_invisible_parameter_annotations_exists = false;
  const u1* annotation_default = nullptr;
  int annotation_default_length = 0;

  // Parse code and exceptions attribute
  u2 method_attributes_count = cfs->get_u2_fast();
  while (method_attributes_count--) {
    cfs->guarantee_more(6, CHECK_NULL);  // method_attribute_name_index, method_attribute_length
    const u2 method_attribute_name_index = cfs->get_u2_fast();
    const u4 method_attribute_length = cfs->get_u4_fast();
    guarantee_property(
      valid_symbol_at(method_attribute_name_index),
      "Invalid method attribute name index %u in class file %s",
      method_attribute_name_index, CHECK_NULL);

    const Symbol* const method_attribute_name = cp->symbol_at(method_attribute_name_index);
    if (method_attribute_name == vmSymbols::tag_code()) {
      // Parse Code attribute
      if (_need_verify) {
        guarantee_property(
            !access_flags.is_native() && !access_flags.is_abstract(),
                        "Code attribute in native or abstract methods in class file %s",
                         CHECK_NULL);
      }
      if (parsed_code_attribute) {
        classfile_parse_error("Multiple Code attributes in class file %s",
                              THREAD);
        return nullptr;
      }
      parsed_code_attribute = true;

      // Stack size, locals size, and code size
      cfs->guarantee_more(8, CHECK_NULL);
      max_stack = cfs->get_u2_fast();
      max_locals = cfs->get_u2_fast();
      code_length = cfs->get_u4_fast();
      if (_need_verify) {
        guarantee_property(args_size <= max_locals,
                           "Arguments can't fit into locals in class file %s",
                           CHECK_NULL);
        guarantee_property(code_length > 0 && code_length <= MAX_CODE_SIZE,
                           "Invalid method Code length %u in class file %s",
                           code_length, CHECK_NULL);
      }
      // Code pointer
      code_start = cfs->current();
      assert(code_start != nullptr, "null code start");
      cfs->guarantee_more(code_length, CHECK_NULL);
      cfs->skip_u1_fast(code_length);

      // Exception handler table
      cfs->guarantee_more(2, CHECK_NULL);  // exception_table_length
      exception_table_length = cfs->get_u2_fast();
      if (exception_table_length > 0) {
        exception_table_start = parse_exception_table(cfs,
                                                      code_length,
                                                      exception_table_length,
                                                      CHECK_NULL);
      }

      // Parse additional attributes in code attribute
      cfs->guarantee_more(2, CHECK_NULL);  // code_attributes_count
      u2 code_attributes_count = cfs->get_u2_fast();

      unsigned int calculated_attribute_length = 0;

      calculated_attribute_length =
          sizeof(max_stack) + sizeof(max_locals) + sizeof(code_length);
      calculated_attribute_length += checked_cast<unsigned int>(
        code_length +
        sizeof(exception_table_length) +
        sizeof(code_attributes_count) +
        exception_table_length *
            ( sizeof(u2) +   // start_pc
              sizeof(u2) +   // end_pc
              sizeof(u2) +   // handler_pc
              sizeof(u2) )); // catch_type_index

      while (code_attributes_count--) {
        cfs->guarantee_more(6, CHECK_NULL);  // code_attribute_name_index, code_attribute_length
        const u2 code_attribute_name_index = cfs->get_u2_fast();
        const u4 code_attribute_length = cfs->get_u4_fast();
        calculated_attribute_length += code_attribute_length +
                                       (unsigned)sizeof(code_attribute_name_index) +
                                       (unsigned)sizeof(code_attribute_length);
        guarantee_property(valid_symbol_at(code_attribute_name_index),
                           "Invalid code attribute name index %u in class file %s",
                           code_attribute_name_index,
                           CHECK_NULL);
        if (LoadLineNumberTables &&
            cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_line_number_table()) {
          // Parse and compress line number table
          parse_linenumber_table(code_attribute_length,
                                 code_length,
                                 &linenumber_table,
                                 CHECK_NULL);

        } else if (LoadLocalVariableTables &&
                   cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_table()) {
          // Parse local variable table
          if (!lvt_allocated) {
            localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
            localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
            localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
            localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
            lvt_allocated = true;
          }
          if (lvt_cnt == max_lvt_cnt) {
            max_lvt_cnt <<= 1;
            localvariable_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt);
            localvariable_table_start  = REALLOC_RESOURCE_ARRAY(const unsafe_u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt);
          }
          localvariable_table_start[lvt_cnt] =
            parse_localvariable_table(cfs,
                                      code_length,
                                      max_locals,
                                      code_attribute_length,
                                      &localvariable_table_length[lvt_cnt],
                                      false,    // is not LVTT
                                      CHECK_NULL);
          total_lvt_length += localvariable_table_length[lvt_cnt];
          lvt_cnt++;
        } else if (LoadLocalVariableTypeTables &&
                   _major_version >= JAVA_1_5_VERSION &&
                   cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_local_variable_type_table()) {
          if (!lvt_allocated) {
            localvariable_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
            localvariable_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
            localvariable_type_table_length = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, u2,  INITIAL_MAX_LVT_NUMBER);
            localvariable_type_table_start = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, const unsafe_u2*, INITIAL_MAX_LVT_NUMBER);
            lvt_allocated = true;
          }
          // Parse local variable type table
          if (lvtt_cnt == max_lvtt_cnt) {
            max_lvtt_cnt <<= 1;
            localvariable_type_table_length = REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt);
            localvariable_type_table_start  = REALLOC_RESOURCE_ARRAY(const unsafe_u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt);
          }
          localvariable_type_table_start[lvtt_cnt] =
            parse_localvariable_table(cfs,
                                      code_length,
                                      max_locals,
                                      code_attribute_length,
                                      &localvariable_type_table_length[lvtt_cnt],
                                      true,     // is LVTT
                                      CHECK_NULL);
          lvtt_cnt++;
        } else if (_major_version >= Verifier::STACKMAP_ATTRIBUTE_MAJOR_VERSION &&
                   cp->symbol_at(code_attribute_name_index) == vmSymbols::tag_stack_map_table()) {
          // Stack map is only needed by the new verifier in JDK1.5.
          if (parsed_stackmap_attribute) {
            classfile_parse_error("Multiple StackMapTable attributes in class file %s", THREAD);
            return nullptr;
          }
          stackmap_data = parse_stackmap_table(cfs, code_attribute_length, CHECK_NULL);
          stackmap_data_length = code_attribute_length;
          parsed_stackmap_attribute = true;
        } else {
          // Skip unknown attributes
          cfs->skip_u1(code_attribute_length, CHECK_NULL);
        }
      }
      // check method attribute length
      if (_need_verify) {
        guarantee_property(method_attribute_length == calculated_attribute_length,
                           "Code segment has wrong length in class file %s",
                           CHECK_NULL);
      }
    } else if (method_attribute_name == vmSymbols::tag_exceptions()) {
      // Parse Exceptions attribute
      if (parsed_checked_exceptions_attribute) {
        classfile_parse_error("Multiple Exceptions attributes in class file %s",
                              THREAD);
        return nullptr;
      }
      parsed_checked_exceptions_attribute = true;
      checked_exceptions_start =
            parse_checked_exceptions(cfs,
                                     &checked_exceptions_length,
                                     method_attribute_length,
                                     CHECK_NULL);
    } else if (method_attribute_name == vmSymbols::tag_method_parameters()) {
      // reject multiple method parameters
      if (method_parameters_seen) {
        classfile_parse_error("Multiple MethodParameters attributes in class file %s",
                              THREAD);
        return nullptr;
      }
      method_parameters_seen = true;
      method_parameters_length = cfs->get_u1_fast();
      const u4 real_length = (method_parameters_length * 4u) + 1u;
      if (method_attribute_length != real_length) {
        classfile_parse_error(
          "Invalid MethodParameters method attribute length %u in class file",
          method_attribute_length, THREAD);
        return nullptr;
      }
      method_parameters_data = cfs->current();
      cfs->skip_u2_fast(method_parameters_length);
      cfs->skip_u2_fast(method_parameters_length);
      // ignore this attribute if it cannot be reflected
      if (!vmClasses::Parameter_klass_loaded())
        method_parameters_length = -1;
    } else if (method_attribute_name == vmSymbols::tag_synthetic()) {
      if (method_attribute_length != 0) {
        classfile_parse_error(
          "Invalid Synthetic method attribute length %u in class file %s",
          method_attribute_length, THREAD);
        return nullptr;
      }
      // Should we check that there hasn't already been a synthetic attribute?
      access_flags.set_is_synthetic();
    } else if (method_attribute_name == vmSymbols::tag_deprecated()) { // 4276120
      if (method_attribute_length != 0) {
        classfile_parse_error(
          "Invalid Deprecated method attribute length %u in class file %s",
          method_attribute_length, THREAD);
        return nullptr;
      }
    } else if (_major_version >= JAVA_1_5_VERSION) {
      if (method_attribute_name == vmSymbols::tag_signature()) {
        if (generic_signature_index != 0) {
          classfile_parse_error(
            "Multiple Signature attributes for method in class file %s",
            THREAD);
          return nullptr;
        }
        if (method_attribute_length != 2) {
          classfile_parse_error(
            "Invalid Signature attribute length %u in class file %s",
            method_attribute_length, THREAD);
          return nullptr;
        }
        generic_signature_index = parse_generic_signature_attribute(cfs, CHECK_NULL);
      } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
        if (runtime_visible_annotations != nullptr) {
          classfile_parse_error(
            "Multiple RuntimeVisibleAnnotations attributes for method in class file %s",
            THREAD);
          return nullptr;
        }
        runtime_visible_annotations_length = method_attribute_length;
        runtime_visible_annotations = cfs->current();
        assert(runtime_visible_annotations != nullptr, "null visible annotations");
        cfs->guarantee_more(runtime_visible_annotations_length, CHECK_NULL);
        parse_annotations(cp,
                          runtime_visible_annotations,
                          runtime_visible_annotations_length,
                          &parsed_annotations,
                          _loader_data,
                          _can_access_vm_annotations);
        cfs->skip_u1_fast(runtime_visible_annotations_length);
      } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
        if (runtime_invisible_annotations_exists) {
          classfile_parse_error(
            "Multiple RuntimeInvisibleAnnotations attributes for method in class file %s",
            THREAD);
          return nullptr;
        }
        runtime_invisible_annotations_exists = true;
        cfs->skip_u1(method_attribute_length, CHECK_NULL);
      } else if (method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) {
        if (runtime_visible_parameter_annotations != nullptr) {
          classfile_parse_error(
            "Multiple RuntimeVisibleParameterAnnotations attributes for method in class file %s",
            THREAD);
          return nullptr;
        }
        runtime_visible_parameter_annotations_length = method_attribute_length;
        runtime_visible_parameter_annotations = cfs->current();
        assert(runtime_visible_parameter_annotations != nullptr, "null visible parameter annotations");
        cfs->skip_u1(runtime_visible_parameter_annotations_length, CHECK_NULL);
      } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) {
        if (runtime_invisible_parameter_annotations_exists) {
          classfile_parse_error(
            "Multiple RuntimeInvisibleParameterAnnotations attributes for method in class file %s",
            THREAD);
          return nullptr;
        }
        runtime_invisible_parameter_annotations_exists = true;
        cfs->skip_u1(method_attribute_length, CHECK_NULL);
      } else if (method_attribute_name == vmSymbols::tag_annotation_default()) {
        if (annotation_default != nullptr) {
          classfile_parse_error(
            "Multiple AnnotationDefault attributes for method in class file %s",
            THREAD);
          return nullptr;
        }
        annotation_default_length = method_attribute_length;
        annotation_default = cfs->current();
        assert(annotation_default != nullptr, "null annotation default");
        cfs->skip_u1(annotation_default_length, CHECK_NULL);
      } else if (method_attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
        if (runtime_visible_type_annotations != nullptr) {
          classfile_parse_error(
            "Multiple RuntimeVisibleTypeAnnotations attributes for method in class file %s",
            THREAD);
          return nullptr;
        }
        runtime_visible_type_annotations_length = method_attribute_length;
        runtime_visible_type_annotations = cfs->current();
        assert(runtime_visible_type_annotations != nullptr, "null visible type annotations");
        // No need for the VM to parse Type annotations
        cfs->skip_u1(runtime_visible_type_annotations_length, CHECK_NULL);
      } else if (method_attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
        if (runtime_invisible_type_annotations_exists) {
          classfile_parse_error(
            "Multiple RuntimeInvisibleTypeAnnotations attributes for method in class file %s",
            THREAD);
          return nullptr;
        }
        runtime_invisible_type_annotations_exists = true;
        cfs->skip_u1(method_attribute_length, CHECK_NULL);
      } else {
        // Skip unknown attributes
        cfs->skip_u1(method_attribute_length, CHECK_NULL);
      }
    } else {
      // Skip unknown attributes
      cfs->skip_u1(method_attribute_length, CHECK_NULL);
    }
  }

  if (linenumber_table != nullptr) {
    linenumber_table->write_terminator();
    linenumber_table_length = linenumber_table->position();
  }

  // Make sure there's at least one Code attribute in non-native/non-abstract method
  if (_need_verify) {
    guarantee_property(access_flags.is_native() ||
                       access_flags.is_abstract() ||
                       parsed_code_attribute,
                       "Absent Code attribute in method that is not native or abstract in class file %s",
                       CHECK_NULL);
  }

  // All sizing information for a Method* is finally available, now create it
  InlineTableSizes sizes(
      total_lvt_length,
      linenumber_table_length,
      exception_table_length,
      checked_exceptions_length,
      method_parameters_length,
      generic_signature_index,
      runtime_visible_annotations_length,
      runtime_visible_parameter_annotations_length,
      runtime_visible_type_annotations_length,
      annotation_default_length,
      0);

  Method* const m = Method::allocate(_loader_data,
                                     code_length,
                                     access_flags,
                                     &sizes,
                                     ConstMethod::NORMAL,
                                     _cp->symbol_at(name_index),
                                     CHECK_NULL);

  ClassLoadingService::add_class_method_size(m->size()*wordSize);

  // Fill in information from fixed part (access_flags already set)
  m->set_constants(_cp);
  m->set_name_index(name_index);
  m->set_signature_index(signature_index);
  m->constMethod()->compute_from_signature(cp->symbol_at(signature_index), access_flags.is_static());
  assert(args_size < 0 || args_size == m->size_of_parameters(), "");

  // Fill in code attribute information
  m->set_max_stack(max_stack);
  m->set_max_locals(max_locals);
  if (stackmap_data != nullptr) {
    m->constMethod()->copy_stackmap_data(_loader_data,
                                         (u1*)stackmap_data,
                                         stackmap_data_length,
                                         CHECK_NULL);
  }

  // Copy byte codes
  m->set_code((u1*)code_start);

  // Copy line number table
  if (linenumber_table != nullptr) {
    memcpy(m->compressed_linenumber_table(),
           linenumber_table->buffer(),
           linenumber_table_length);
  }

  // Copy exception table
  if (exception_table_length > 0) {
    Copy::conjoint_swap_if_needed<Endian::JAVA>(exception_table_start,
                                                m->exception_table_start(),
                                                exception_table_length * sizeof(ExceptionTableElement),
                                                sizeof(u2));
  }

  // Copy method parameters
  if (method_parameters_length > 0) {
    MethodParametersElement* elem = m->constMethod()->method_parameters_start();
    for (int i = 0; i < method_parameters_length; i++) {
      elem[i].name_cp_index = Bytes::get_Java_u2((address)method_parameters_data);
      method_parameters_data += 2;
      elem[i].flags = Bytes::get_Java_u2((address)method_parameters_data);
      method_parameters_data += 2;
    }
  }

  // Copy checked exceptions
  if (checked_exceptions_length > 0) {
    Copy::conjoint_swap_if_needed<Endian::JAVA>(checked_exceptions_start,
                                                m->checked_exceptions_start(),
                                                checked_exceptions_length * sizeof(CheckedExceptionElement),
                                                sizeof(u2));
  }

  // Copy class file LVT's/LVTT's into the HotSpot internal LVT.
  if (total_lvt_length > 0) {
    *has_localvariable_table = true;
    copy_localvariable_table(m->constMethod(),
                             lvt_cnt,
                             localvariable_table_length,
                             localvariable_table_start,
                             lvtt_cnt,
                             localvariable_type_table_length,
                             localvariable_type_table_start,
                             CHECK_NULL);
  }

  if (parsed_annotations.has_any_annotations())
    parsed_annotations.apply_to(methodHandle(THREAD, m));

  if (is_hidden()) { // Mark methods in hidden classes as 'hidden'.
    m->set_is_hidden();
  }

  // Copy annotations
  copy_method_annotations(m->constMethod(),
                          runtime_visible_annotations,
                          runtime_visible_annotations_length,
                          runtime_visible_parameter_annotations,
                          runtime_visible_parameter_annotations_length,
                          runtime_visible_type_annotations,
                          runtime_visible_type_annotations_length,
                          annotation_default,
                          annotation_default_length,
                          CHECK_NULL);

  if (InstanceKlass::is_finalization_enabled() &&
      name == vmSymbols::finalize_method_name() &&
      signature == vmSymbols::void_method_signature()) {
    if (m->is_empty_method()) {
      _has_empty_finalizer = true;
    } else {
      _has_finalizer = true;
    }
  }

  NOT_PRODUCT(m->verify());
  return m;
}


// Side-effects: populates the _methods field in the parser
void ClassFileParser::parse_methods(const ClassFileStream* const cfs,
                                    bool is_interface,
                                    bool* const has_localvariable_table,
                                    bool* has_final_method,
                                    bool* declares_nonstatic_concrete_methods,
                                    TRAPS) {
  assert(cfs != nullptr, "invariant");
  assert(has_localvariable_table != nullptr, "invariant");
  assert(has_final_method != nullptr, "invariant");
  assert(declares_nonstatic_concrete_methods != nullptr, "invariant");

  assert(nullptr == _methods, "invariant");

  cfs->guarantee_more(2, CHECK);  // length
  const u2 length = cfs->get_u2_fast();
  if (length == 0) {
    _methods = Universe::the_empty_method_array();
  } else {
    _methods = MetadataFactory::new_array<Method*>(_loader_data,
                                                   length,
                                                   nullptr,
                                                   CHECK);

    for (int index = 0; index < length; index++) {
      Method* method = parse_method(cfs,
                                    is_interface,
                                    _cp,
                                    has_localvariable_table,
                                    CHECK);

      if (method->is_final()) {
        *has_final_method = true;
      }
      // declares_nonstatic_concrete_methods: declares concrete instance methods, any access flags
      // used for interface initialization, and default method inheritance analysis
      if (is_interface && !(*declares_nonstatic_concrete_methods)
        && !method->is_abstract() && !method->is_static()) {
        *declares_nonstatic_concrete_methods = true;
      }
      _methods->at_put(index, method);
    }

    if (_need_verify && length > 1) {
      // Check duplicated methods
      ResourceMark rm(THREAD);
      // Set containing name-signature pairs
      NameSigHashtable* names_and_sigs = new NameSigHashtable();
      for (int i = 0; i < length; i++) {
        const Method* const m = _methods->at(i);
        NameSigHash name_and_sig(m->name(), m->signature());
        // If no duplicates, add name/signature in hashtable names_and_sigs.
        if(!names_and_sigs->put(name_and_sig, 0)) {
          classfile_parse_error("Duplicate method name \"%s\" with signature \"%s\" in class file %s",
                                 name_and_sig._name->as_C_string(), name_and_sig._sig->as_klass_external_name(), THREAD);
          return;
        }
      }
    }
  }
}

static const intArray* sort_methods(Array<Method*>* methods) {
  const int length = methods->length();
  // If JVMTI original method ordering or sharing is enabled we have to
  // remember the original class file ordering.
  // We temporarily use the vtable_index field in the Method* to store the
  // class file index, so we can read in after calling qsort.
  // Put the method ordering in the shared archive.
  if (JvmtiExport::can_maintain_original_method_order() || CDSConfig::is_dumping_archive()) {
    for (int index = 0; index < length; index++) {
      Method* const m = methods->at(index);
      assert(!m->valid_vtable_index(), "vtable index should not be set");
      m->set_vtable_index(index);
    }
  }
  // Sort method array by ascending method name (for faster lookups & vtable construction)
  // Note that the ordering is not alphabetical, see Symbol::fast_compare
  Method::sort_methods(methods);

  intArray* method_ordering = nullptr;
  // If JVMTI original method ordering or sharing is enabled construct int
  // array remembering the original ordering
  if (JvmtiExport::can_maintain_original_method_order() || CDSConfig::is_dumping_archive()) {
    method_ordering = new intArray(length, length, -1);
    for (int index = 0; index < length; index++) {
      Method* const m = methods->at(index);
      const int old_index = m->vtable_index();
      assert(old_index >= 0 && old_index < length, "invalid method index");
      method_ordering->at_put(index, old_index);
      m->set_vtable_index(Method::invalid_vtable_index);
    }
  }
  return method_ordering;
}

// Parse generic_signature attribute for methods and fields
u2 ClassFileParser::parse_generic_signature_attribute(const ClassFileStream* const cfs,
                                                      TRAPS) {
  assert(cfs != nullptr, "invariant");

  cfs->guarantee_more(2, CHECK_0);  // generic_signature_index
  const u2 generic_signature_index = cfs->get_u2_fast();
  guarantee_property(
    valid_symbol_at(generic_signature_index),
    "Invalid Signature attribute at constant pool index %u in class file %s",
    generic_signature_index, CHECK_0);
  return generic_signature_index;
}

void ClassFileParser::parse_classfile_sourcefile_attribute(const ClassFileStream* const cfs,
                                                           TRAPS) {

  assert(cfs != nullptr, "invariant");

  cfs->guarantee_more(2, CHECK);  // sourcefile_index
  const u2 sourcefile_index = cfs->get_u2_fast();
  guarantee_property(
    valid_symbol_at(sourcefile_index),
    "Invalid SourceFile attribute at constant pool index %u in class file %s",
    sourcefile_index, CHECK);
  set_class_sourcefile_index(sourcefile_index);
}

void ClassFileParser::parse_classfile_source_debug_extension_attribute(const ClassFileStream* const cfs,
                                                                       int length,
                                                                       TRAPS) {
  assert(cfs != nullptr, "invariant");

  const u1* const sde_buffer = cfs->current();
  assert(sde_buffer != nullptr, "null sde buffer");

  // Don't bother storing it if there is no way to retrieve it
  if (JvmtiExport::can_get_source_debug_extension()) {
    assert((length+1) > length, "Overflow checking");
    u1* const sde = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, u1, length+1);
    for (int i = 0; i < length; i++) {
      sde[i] = sde_buffer[i];
    }
    sde[length] = '\0';
    set_class_sde_buffer((const char*)sde, length);
  }
  // Got utf8 string, set stream position forward
  cfs->skip_u1(length, CHECK);
}


// Inner classes can be static, private or protected (classic VM does this)
#define RECOGNIZED_INNER_CLASS_MODIFIERS ( JVM_RECOGNIZED_CLASS_MODIFIERS | \
                                           JVM_ACC_PRIVATE |                \
                                           JVM_ACC_PROTECTED |              \
                                           JVM_ACC_STATIC                   \
                                         )

// Find index of the InnerClasses entry for the specified inner_class_info_index.
// Return -1 if none is found.
static int inner_classes_find_index(const Array<u2>* inner_classes, int inner, const ConstantPool* cp, int length) {
  Symbol* cp_klass_name =  cp->klass_name_at(inner);
  for (int idx = 0; idx < length; idx += InstanceKlass::inner_class_next_offset) {
    int idx_inner = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset);
    if (cp->klass_name_at(idx_inner) == cp_klass_name) {
      return idx;
    }
  }
  return -1;
}

// Return the outer_class_info_index for the InnerClasses entry containing the
// specified inner_class_info_index.  Return -1 if no InnerClasses entry is found.
static int inner_classes_jump_to_outer(const Array<u2>* inner_classes, int inner, const ConstantPool* cp, int length) {
  if (inner == 0) return -1;
  int idx = inner_classes_find_index(inner_classes, inner, cp, length);
  if (idx == -1) return -1;
  int result = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset);
  return result;
}

// Return true if circularity is found, false if no circularity is found.
// Use Floyd's cycle finding algorithm.
static bool inner_classes_check_loop_through_outer(const Array<u2>* inner_classes, int idx, const ConstantPool* cp, int length) {
  int slow = inner_classes->at(idx + InstanceKlass::inner_class_inner_class_info_offset);
  int fast = inner_classes->at(idx + InstanceKlass::inner_class_outer_class_info_offset);

  while (fast != -1 && fast != 0) {
    if (slow != 0 && (cp->klass_name_at(slow) == cp->klass_name_at(fast))) {
      return true;  // found a circularity
    }
    fast = inner_classes_jump_to_outer(inner_classes, fast, cp, length);
    if (fast == -1) return false;
    fast = inner_classes_jump_to_outer(inner_classes, fast, cp, length);
    if (fast == -1) return false;
    slow = inner_classes_jump_to_outer(inner_classes, slow, cp, length);
    assert(slow != -1, "sanity check");
  }
  return false;
}

// Loop through each InnerClasses entry checking for circularities and duplications
// with other entries.  If duplicate entries are found then throw CFE.  Otherwise,
// return true if a circularity or entries with duplicate inner_class_info_indexes
// are found.
bool ClassFileParser::check_inner_classes_circularity(const ConstantPool* cp, int length, TRAPS) {
  // Loop through each InnerClasses entry.
  for (int idx = 0; idx < length; idx += InstanceKlass::inner_class_next_offset) {
    // Return true if there are circular entries.
    if (inner_classes_check_loop_through_outer(_inner_classes, idx, cp, length)) {
      return true;
    }
    // Check if there are duplicate entries or entries with the same inner_class_info_index.
    for (int y = idx + InstanceKlass::inner_class_next_offset; y < length;
         y += InstanceKlass::inner_class_next_offset) {

      // 4347400: make sure there's no duplicate entry in the classes array
      if (_major_version >= JAVA_1_5_VERSION) {
        guarantee_property((_inner_classes->at(idx) != _inner_classes->at(y) ||
                            _inner_classes->at(idx+1) != _inner_classes->at(y+1) ||
                            _inner_classes->at(idx+2) != _inner_classes->at(y+2) ||
                            _inner_classes->at(idx+3) != _inner_classes->at(y+3)),
                           "Duplicate entry in InnerClasses attribute in class file %s",
                           CHECK_(true));
      }
      // Return true if there are two entries with the same inner_class_info_index.
      if (_inner_classes->at(y) == _inner_classes->at(idx)) {
        return true;
      }
    }
  }
  return false;
}

// Return number of classes in the inner classes attribute table
u2 ClassFileParser::parse_classfile_inner_classes_attribute(const ClassFileStream* const cfs,
                                                            const ConstantPool* cp,
                                                            const u1* const inner_classes_attribute_start,
                                                            bool parsed_enclosingmethod_attribute,
                                                            u2 enclosing_method_class_index,
                                                            u2 enclosing_method_method_index,
                                                            TRAPS) {
  const u1* const current_mark = cfs->current();
  u2 length = 0;
  if (inner_classes_attribute_start != nullptr) {
    cfs->set_current(inner_classes_attribute_start);
    cfs->guarantee_more(2, CHECK_0);  // length
    length = cfs->get_u2_fast();
  }

  // 4-tuples of shorts of inner classes data and 2 shorts of enclosing
  // method data:
  //   [inner_class_info_index,
  //    outer_class_info_index,
  //    inner_name_index,
  //    inner_class_access_flags,
  //    ...
  //    enclosing_method_class_index,
  //    enclosing_method_method_index]
  const int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
  Array<u2>* inner_classes = MetadataFactory::new_array<u2>(_loader_data, size, CHECK_0);
  _inner_classes = inner_classes;

  int index = 0;
  cfs->guarantee_more(8 * length, CHECK_0);  // 4-tuples of u2
  for (int n = 0; n < length; n++) {
    // Inner class index
    const u2 inner_class_info_index = cfs->get_u2_fast();
    guarantee_property(
      valid_klass_reference_at(inner_class_info_index),
      "inner_class_info_index %u has bad constant type in class file %s",
      inner_class_info_index, CHECK_0);
    // Outer class index
    const u2 outer_class_info_index = cfs->get_u2_fast();
    guarantee_property(
      outer_class_info_index == 0 ||
        valid_klass_reference_at(outer_class_info_index),
      "outer_class_info_index %u has bad constant type in class file %s",
      outer_class_info_index, CHECK_0);

    if (outer_class_info_index != 0) {
      const Symbol* const outer_class_name = cp->klass_name_at(outer_class_info_index);
      char* bytes = (char*)outer_class_name->bytes();
      guarantee_property(bytes[0] != JVM_SIGNATURE_ARRAY,
                         "Outer class is an array class in class file %s", CHECK_0);
    }
    // Inner class name
    const u2 inner_name_index = cfs->get_u2_fast();
    guarantee_property(
      inner_name_index == 0 || valid_symbol_at(inner_name_index),
      "inner_name_index %u has bad constant type in class file %s",
      inner_name_index, CHECK_0);
    if (_need_verify) {
      guarantee_property(inner_class_info_index != outer_class_info_index,
                         "Class is both outer and inner class in class file %s", CHECK_0);
    }
    // Access flags
    u2 flags;
    // JVM_ACC_MODULE is defined in JDK-9 and later.
    if (_major_version >= JAVA_9_VERSION) {
      flags = cfs->get_u2_fast() & (RECOGNIZED_INNER_CLASS_MODIFIERS | JVM_ACC_MODULE);
    } else {
      flags = cfs->get_u2_fast() & RECOGNIZED_INNER_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_0);
    AccessFlags inner_access_flags(flags);

    inner_classes->at_put(index++, inner_class_info_index);
    inner_classes->at_put(index++, outer_class_info_index);
    inner_classes->at_put(index++, inner_name_index);
    inner_classes->at_put(index++, inner_access_flags.as_unsigned_short());
  }

  // Check for circular and duplicate entries.
  bool has_circularity = false;
  if (_need_verify) {
    has_circularity = check_inner_classes_circularity(cp, length * 4, CHECK_0);
    if (has_circularity) {
      // If circularity check failed then ignore InnerClasses attribute.
      MetadataFactory::free_array<u2>(_loader_data, _inner_classes);
      index = 0;
      if (parsed_enclosingmethod_attribute) {
        inner_classes = MetadataFactory::new_array<u2>(_loader_data, 2, CHECK_0);
        _inner_classes = inner_classes;
      } else {
        _inner_classes = Universe::the_empty_short_array();
      }
    }
  }
  // Set EnclosingMethod class and method indexes.
  if (parsed_enclosingmethod_attribute) {
    inner_classes->at_put(index++, enclosing_method_class_index);
    inner_classes->at_put(index++, enclosing_method_method_index);
  }
  assert(index == size || has_circularity, "wrong size");

  // Restore buffer's current position.
  cfs->set_current(current_mark);

  return length;
}

u2 ClassFileParser::parse_classfile_nest_members_attribute(const ClassFileStream* const cfs,
                                                           const u1* const nest_members_attribute_start,
                                                           TRAPS) {
  const u1* const current_mark = cfs->current();
  u2 length = 0;
  if (nest_members_attribute_start != nullptr) {
    cfs->set_current(nest_members_attribute_start);
    cfs->guarantee_more(2, CHECK_0);  // length
    length = cfs->get_u2_fast();
  }
  const int size = length;
  Array<u2>* const nest_members = MetadataFactory::new_array<u2>(_loader_data, size, CHECK_0);
  _nest_members = nest_members;

  int index = 0;
  cfs->guarantee_more(2 * length, CHECK_0);
  for (int n = 0; n < length; n++) {
    const u2 class_info_index = cfs->get_u2_fast();
    guarantee_property(
      valid_klass_reference_at(class_info_index),
      "Nest member class_info_index %u has bad constant type in class file %s",
      class_info_index, CHECK_0);
    nest_members->at_put(index++, class_info_index);
  }
  assert(index == size, "wrong size");

  // Restore buffer's current position.
  cfs->set_current(current_mark);

  return length;
}

u2 ClassFileParser::parse_classfile_permitted_subclasses_attribute(const ClassFileStream* const cfs,
                                                                   const u1* const permitted_subclasses_attribute_start,
                                                                   TRAPS) {
  const u1* const current_mark = cfs->current();
  u2 length = 0;
  if (permitted_subclasses_attribute_start != nullptr) {
    cfs->set_current(permitted_subclasses_attribute_start);
    cfs->guarantee_more(2, CHECK_0);  // length
    length = cfs->get_u2_fast();
  }
  const int size = length;
  Array<u2>* const permitted_subclasses = MetadataFactory::new_array<u2>(_loader_data, size, CHECK_0);
  _permitted_subclasses = permitted_subclasses;

  if (length > 0) {
    int index = 0;
    cfs->guarantee_more(2 * length, CHECK_0);
    for (int n = 0; n < length; n++) {
      const u2 class_info_index = cfs->get_u2_fast();
      guarantee_property(
        valid_klass_reference_at(class_info_index),
        "Permitted subclass class_info_index %u has bad constant type in class file %s",
        class_info_index, CHECK_0);
      permitted_subclasses->at_put(index++, class_info_index);
    }
    assert(index == size, "wrong size");
  }

  // Restore buffer's current position.
  cfs->set_current(current_mark);

  return length;
}

//  Record {
//    u2 attribute_name_index;
//    u4 attribute_length;
//    u2 components_count;
//    component_info components[components_count];
//  }
//  component_info {
//    u2 name_index;
//    u2 descriptor_index
//    u2 attributes_count;
//    attribute_info_attributes[attributes_count];
//  }
u4 ClassFileParser::parse_classfile_record_attribute(const ClassFileStream* const cfs,
                                                     const ConstantPool* cp,
                                                     const u1* const record_attribute_start,
                                                     TRAPS) {
  const u1* const current_mark = cfs->current();
  int components_count = 0;
  unsigned int calculate_attr_size = 0;
  if (record_attribute_start != nullptr) {
    cfs->set_current(record_attribute_start);
    cfs->guarantee_more(2, CHECK_0);  // num of components
    components_count = (int)cfs->get_u2_fast();
    calculate_attr_size = 2;
  }

  Array<RecordComponent*>* const record_components =
    MetadataFactory::new_array<RecordComponent*>(_loader_data, components_count, nullptr, CHECK_0);
  _record_components = record_components;

  for (int x = 0; x < components_count; x++) {
    cfs->guarantee_more(6, CHECK_0); // name_index, descriptor_index, attributes_count

    const u2 name_index = cfs->get_u2_fast();
    guarantee_property(valid_symbol_at(name_index),
      "Invalid constant pool index %u for name in Record attribute in class file %s",
      name_index, CHECK_0);
    const Symbol* const name = cp->symbol_at(name_index);
    verify_legal_field_name(name, CHECK_0);

    const u2 descriptor_index = cfs->get_u2_fast();
    guarantee_property(valid_symbol_at(descriptor_index),
      "Invalid constant pool index %u for descriptor in Record attribute in class file %s",
      descriptor_index, CHECK_0);
    const Symbol* const descr = cp->symbol_at(descriptor_index);
    verify_legal_field_signature(name, descr, CHECK_0);

    const u2 attributes_count = cfs->get_u2_fast();
    calculate_attr_size += 6;
    u2 generic_sig_index = 0;
    const u1* runtime_visible_annotations = nullptr;
    int runtime_visible_annotations_length = 0;
    bool runtime_invisible_annotations_exists = false;
    const u1* runtime_visible_type_annotations = nullptr;
    int runtime_visible_type_annotations_length = 0;
    bool runtime_invisible_type_annotations_exists = false;

    // Expected attributes for record components are Signature, Runtime(In)VisibleAnnotations,
    // and Runtime(In)VisibleTypeAnnotations.  Other attributes are ignored.
    for (int y = 0; y < attributes_count; y++) {
      cfs->guarantee_more(6, CHECK_0);  // attribute_name_index, attribute_length
      const u2 attribute_name_index = cfs->get_u2_fast();
      const u4 attribute_length = cfs->get_u4_fast();
      calculate_attr_size += 6;
      guarantee_property(
        valid_symbol_at(attribute_name_index),
        "Invalid Record attribute name index %u in class file %s",
        attribute_name_index, CHECK_0);

      const Symbol* const attribute_name = cp->symbol_at(attribute_name_index);
      if (attribute_name == vmSymbols::tag_signature()) {
        if (generic_sig_index != 0) {
          classfile_parse_error(
            "Multiple Signature attributes for Record component in class file %s",
            THREAD);
          return 0;
        }
        if (attribute_length != 2) {
          classfile_parse_error(
            "Invalid Signature attribute length %u in Record component in class file %s",
            attribute_length, THREAD);
          return 0;
        }
        generic_sig_index = parse_generic_signature_attribute(cfs, CHECK_0);

      } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
        if (runtime_visible_annotations != nullptr) {
          classfile_parse_error(
            "Multiple RuntimeVisibleAnnotations attributes for Record component in class file %s", THREAD);
          return 0;
        }
        runtime_visible_annotations_length = attribute_length;
        runtime_visible_annotations = cfs->current();

        assert(runtime_visible_annotations != nullptr, "null record component visible annotation");
        cfs->guarantee_more(runtime_visible_annotations_length, CHECK_0);
        cfs->skip_u1_fast(runtime_visible_annotations_length);

      } else if (attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
        if (runtime_invisible_annotations_exists) {
          classfile_parse_error(
            "Multiple RuntimeInvisibleAnnotations attributes for Record component in class file %s", THREAD);
          return 0;
        }
        runtime_invisible_annotations_exists = true;
        cfs->skip_u1(attribute_length, CHECK_0);

      } else if (attribute_name == vmSymbols::tag_runtime_visible_type_annotations()) {
        if (runtime_visible_type_annotations != nullptr) {
          classfile_parse_error(
            "Multiple RuntimeVisibleTypeAnnotations attributes for Record component in class file %s", THREAD);
          return 0;
        }
        runtime_visible_type_annotations_length = attribute_length;
        runtime_visible_type_annotations = cfs->current();

        assert(runtime_visible_type_annotations != nullptr, "null record component visible type annotation");
        cfs->guarantee_more(runtime_visible_type_annotations_length, CHECK_0);
        cfs->skip_u1_fast(runtime_visible_type_annotations_length);

      } else if (attribute_name == vmSymbols::tag_runtime_invisible_type_annotations()) {
        if (runtime_invisible_type_annotations_exists) {
          classfile_parse_error(
            "Multiple RuntimeInvisibleTypeAnnotations attributes for Record component in class file %s", THREAD);
          return 0;
        }
        runtime_invisible_type_annotations_exists = true;
        cfs->skip_u1(attribute_length, CHECK_0);

      } else {
        // Skip unknown attributes
        cfs->skip_u1(attribute_length, CHECK_0);
      }
      calculate_attr_size += attribute_length;
    } // End of attributes For loop

    AnnotationArray* annotations = allocate_annotations(runtime_visible_annotations,
                                                        runtime_visible_annotations_length,
                                                        CHECK_0);
    AnnotationArray* type_annotations = allocate_annotations(runtime_visible_type_annotations,
                                                             runtime_visible_type_annotations_length,
                                                             CHECK_0);

    RecordComponent* record_component =
      RecordComponent::allocate(_loader_data, name_index, descriptor_index, generic_sig_index,
                                annotations, type_annotations, CHECK_0);
    record_components->at_put(x, record_component);
  }  // End of component processing loop

  // Restore buffer's current position.
  cfs->set_current(current_mark);
  return calculate_attr_size;
}

void ClassFileParser::parse_classfile_synthetic_attribute() {
  set_class_synthetic_flag(true);
}

void ClassFileParser::parse_classfile_signature_attribute(const ClassFileStream* const cfs, TRAPS) {
  assert(cfs != nullptr, "invariant");

  const u2 signature_index = cfs->get_u2(CHECK);
  guarantee_property(
    valid_symbol_at(signature_index),
    "Invalid constant pool index %u in Signature attribute in class file %s",
    signature_index, CHECK);
  set_class_generic_signature_index(signature_index);
}

void ClassFileParser::parse_classfile_bootstrap_methods_attribute(const ClassFileStream* const cfs,
                                                                  ConstantPool* cp,
                                                                  u4 attribute_byte_length,
                                                                  TRAPS) {
  assert(cfs != nullptr, "invariant");
  assert(cp != nullptr, "invariant");

  const u1* const 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);

  const 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}}
  const unsigned int operand_count = (attribute_byte_length - (unsigned)sizeof(u2)) / (unsigned)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.
  const int index_size = (attribute_array_length * 2);

  Array<u2>* const 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;
  const 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
    const u2 bootstrap_method_index = cfs->get_u2_fast();
    const u2 argument_count = cfs->get_u2_fast();
    guarantee_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++) {
      const u2 argument_index = cfs->get_u2_fast();
      guarantee_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);
    }
  }
  guarantee_property(current_start + attribute_byte_length == cfs->current(),
                     "Bad length on BootstrapMethods in class file %s",
                     CHECK);
}

void ClassFileParser::parse_classfile_attributes(const ClassFileStream* const cfs,
                                                 ConstantPool* cp,
                 ClassFileParser::ClassAnnotationCollector* parsed_annotations,
                                                 TRAPS) {
  assert(cfs != nullptr, "invariant");
  assert(cp != nullptr, "invariant");
  assert(parsed_annotations != nullptr, "invariant");

  // Set inner classes attribute to default sentinel
  _inner_classes = Universe::the_empty_short_array();
  // Set nest members attribute to default sentinel
  _nest_members = Universe::the_empty_short_array();
  // Set _permitted_subclasses attribute to default sentinel
  _permitted_subclasses = Universe::the_empty_short_array();
  cfs->guarantee_more(2, CHECK);  // attributes_count
  u2 attributes_count = cfs->get_u2_fast();
  bool parsed_sourcefile_attribute = false;
  bool parsed_innerclasses_attribute = false;
  bool parsed_nest_members_attribute = false;
  bool parsed_permitted_subclasses_attribute = false;
  bool parsed_nest_host_attribute = false;
  bool parsed_record_attribute = false;
  bool parsed_enclosingmethod_attribute = false;
  bool parsed_bootstrap_methods_attribute = false;
  const u1* runtime_visible_annotations = nullptr;
  int runtime_visible_annotations_length = 0;
  const u1* runtime_visible_type_annotations = nullptr;
  int runtime_visible_type_annotations_length = 0;
  bool runtime_invisible_type_annotations_exists = false;
  bool runtime_invisible_annotations_exists = false;
  bool parsed_source_debug_ext_annotations_exist = false;
  const u1* inner_classes_attribute_start = nullptr;
  u4  inner_classes_attribute_length = 0;
  u2  enclosing_method_class_index = 0;
  u2  enclosing_method_method_index = 0;
  const u1* nest_members_attribute_start = nullptr;
  u4  nest_members_attribute_length = 0;
  const u1* record_attribute_start = nullptr;
  u4  record_attribute_length = 0;
  const u1* permitted_subclasses_attribute_start = nullptr;
  u4  permitted_subclasses_attribute_length = 0;

  // Iterate over attributes
  while (attributes_count--) {
    cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
    const u2 attribute_name_index = cfs->get_u2_fast();
    const u4 attribute_length = cfs->get_u4_fast();
    guarantee_property(
      valid_symbol_at(attribute_name_index),
      "Attribute name has bad constant pool index %u in class file %s",
      attribute_name_index, CHECK);
    const Symbol* const tag = cp->symbol_at(attribute_name_index);
    if (tag == vmSymbols::tag_source_file()) {
      // Check for SourceFile tag
      if (_need_verify) {
        guarantee_property(attribute_length == 2, "Wrong SourceFile attribute length in class file %s", CHECK);
      }
      if (parsed_sourcefile_attribute) {
        classfile_parse_error("Multiple SourceFile attributes in class file %s", THREAD);
        return;
      } else {
        parsed_sourcefile_attribute = true;
      }
      parse_classfile_sourcefile_attribute(cfs, CHECK);
    } else if (tag == vmSymbols::tag_source_debug_extension()) {
      // Check for SourceDebugExtension tag
      if (parsed_source_debug_ext_annotations_exist) {
        classfile_parse_error(
          "Multiple SourceDebugExtension attributes in class file %s", THREAD);
        return;
      }
      parsed_source_debug_ext_annotations_exist = true;
      parse_classfile_source_debug_extension_attribute(cfs, (int)attribute_length, CHECK);
    } else if (tag == vmSymbols::tag_inner_classes()) {
      // Check for InnerClasses tag
      if (parsed_innerclasses_attribute) {
        classfile_parse_error("Multiple InnerClasses attributes in class file %s", THREAD);
        return;
      } else {
        parsed_innerclasses_attribute = true;
      }
      inner_classes_attribute_start = cfs->current();
      inner_classes_attribute_length = attribute_length;
      cfs->skip_u1(inner_classes_attribute_length, CHECK);
    } else if (tag == vmSymbols::tag_synthetic()) {
      // Check for Synthetic tag
      // Shouldn't we check that the synthetic flags wasn't already set? - not required in spec
      if (attribute_length != 0) {
        classfile_parse_error(
          "Invalid Synthetic classfile attribute length %u in class file %s",
          attribute_length, THREAD);
        return;
      }
      parse_classfile_synthetic_attribute();
    } else if (tag == vmSymbols::tag_deprecated()) {
      // Check for Deprecated tag - 4276120
      if (attribute_length != 0) {
        classfile_parse_error(
          "Invalid Deprecated classfile attribute length %u in class file %s",
          attribute_length, THREAD);
        return;
      }
    } else if (_major_version >= JAVA_1_5_VERSION) {
      if (tag == vmSymbols::tag_signature()) {
        if (_generic_signature_index != 0) {
          classfile_parse_error(
            "Multiple Signature attributes in class file %s", THREAD);
          return;
        }
        if (attribute_length != 2) {
          classfile_parse_error(
            "Wrong Signature attribute length %u in class file %s",
            attribute_length, THREAD);
          return;
        }
        parse_classfile_signature_attribute(cfs, CHECK);
      } else if (tag == vmSymbols::tag_runtime_visible_annotations()) {
        if (runtime_visible_annotations != nullptr) {
          classfile_parse_error(
            "Multiple RuntimeVisibleAnnotations attributes in class file %s", THREAD);
          return;
        }
        runtime_visible_annotations_length = attribute_length;
        runtime_visible_annotations = cfs->current();
        assert(runtime_visible_annotations != nullptr, "null visible annotations");
        cfs->guarantee_more(runtime_visible_annotations_length, CHECK);
        parse_annotations(cp,
                          runtime_visible_annotations,
                          runtime_visible_annotations_length,
                          parsed_annotations,
                          _loader_data,
                          _can_access_vm_annotations);
        cfs->skip_u1_fast(runtime_visible_annotations_length);
      } else if (tag == vmSymbols::tag_runtime_invisible_annotations()) {
        if (runtime_invisible_annotations_exists) {
          classfile_parse_error(
            "Multiple RuntimeInvisibleAnnotations attributes in class file %s", THREAD);
          return;
        }
        runtime_invisible_annotations_exists = true;
        cfs->skip_u1(attribute_length, CHECK);
      } else if (tag == vmSymbols::tag_enclosing_method()) {
        if (parsed_enclosingmethod_attribute) {
          classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", THREAD);
          return;
        } else {
          parsed_enclosingmethod_attribute = true;
        }
        guarantee_property(attribute_length == 4,
          "Wrong EnclosingMethod attribute length %u in class file %s",
          attribute_length, CHECK);
        cfs->guarantee_more(4, CHECK);  // class_index, method_index
        enclosing_method_class_index  = cfs->get_u2_fast();
        enclosing_method_method_index = cfs->get_u2_fast();
        if (enclosing_method_class_index == 0) {
          classfile_parse_error("Invalid class index in EnclosingMethod attribute in class file %s", THREAD);
          return;
        }
        // Validate the constant pool indices and types
        guarantee_property(valid_klass_reference_at(enclosing_method_class_index),
          "Invalid or out-of-bounds class index in EnclosingMethod attribute in class file %s", CHECK);
        if (enclosing_method_method_index != 0 &&
            (!cp->is_within_bounds(enclosing_method_method_index) ||
             !cp->tag_at(enclosing_method_method_index).is_name_and_type())) {
          classfile_parse_error("Invalid or out-of-bounds method index in EnclosingMethod attribute in class file %s", THREAD);
          return;
        }
      } else if (tag == vmSymbols::tag_bootstrap_methods() &&
                 _major_version >= Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
        if (parsed_bootstrap_methods_attribute) {
          classfile_parse_error("Multiple BootstrapMethods attributes in class file %s", THREAD);
          return;
        }
        parsed_bootstrap_methods_attribute = true;
        parse_classfile_bootstrap_methods_attribute(cfs, cp, attribute_length, CHECK);
      } else if (tag == vmSymbols::tag_runtime_visible_type_annotations()) {
        if (runtime_visible_type_annotations != nullptr) {
          classfile_parse_error(
            "Multiple RuntimeVisibleTypeAnnotations attributes in class file %s", THREAD);
          return;
        }
        runtime_visible_type_annotations_length = attribute_length;
        runtime_visible_type_annotations = cfs->current();
        assert(runtime_visible_type_annotations != nullptr, "null visible type annotations");
        // No need for the VM to parse Type annotations
        cfs->skip_u1(runtime_visible_type_annotations_length, CHECK);
      } else if (tag == vmSymbols::tag_runtime_invisible_type_annotations()) {
        if (runtime_invisible_type_annotations_exists) {
          classfile_parse_error(
            "Multiple RuntimeInvisibleTypeAnnotations attributes in class file %s", THREAD);
          return;
        }
        runtime_invisible_type_annotations_exists = true;
        cfs->skip_u1(attribute_length, CHECK);
      } else if (_major_version >= JAVA_11_VERSION) {
        if (tag == vmSymbols::tag_nest_members()) {
          // Check for NestMembers tag
          if (parsed_nest_members_attribute) {
            classfile_parse_error("Multiple NestMembers attributes in class file %s", THREAD);
            return;
          } else {
            parsed_nest_members_attribute = true;
          }
          if (parsed_nest_host_attribute) {
            classfile_parse_error("Conflicting NestHost and NestMembers attributes in class file %s", THREAD);
            return;
          }
          nest_members_attribute_start = cfs->current();
          nest_members_attribute_length = attribute_length;
          cfs->skip_u1(nest_members_attribute_length, CHECK);
        } else if (tag == vmSymbols::tag_nest_host()) {
          if (parsed_nest_host_attribute) {
            classfile_parse_error("Multiple NestHost attributes in class file %s", THREAD);
            return;
          } else {
            parsed_nest_host_attribute = true;
          }
          if (parsed_nest_members_attribute) {
            classfile_parse_error("Conflicting NestMembers and NestHost attributes in class file %s", THREAD);
            return;
          }
          if (_need_verify) {
            guarantee_property(attribute_length == 2, "Wrong NestHost attribute length in class file %s", CHECK);
          }
          cfs->guarantee_more(2, CHECK);
          u2 class_info_index = cfs->get_u2_fast();
          guarantee_property(
                         valid_klass_reference_at(class_info_index),
                         "Nest-host class_info_index %u has bad constant type in class file %s",
                         class_info_index, CHECK);
          _nest_host = class_info_index;

        } else if (_major_version >= JAVA_16_VERSION) {
          if (tag == vmSymbols::tag_record()) {
            if (parsed_record_attribute) {
              classfile_parse_error("Multiple Record attributes in class file %s", THREAD);
              return;
            }
            parsed_record_attribute = true;
            record_attribute_start = cfs->current();
            record_attribute_length = attribute_length;
          } else if (_major_version >= JAVA_17_VERSION) {
            if (tag == vmSymbols::tag_permitted_subclasses()) {
              if (parsed_permitted_subclasses_attribute) {
                classfile_parse_error("Multiple PermittedSubclasses attributes in class file %s", CHECK);
                return;
              }
              // Classes marked ACC_FINAL cannot have a PermittedSubclasses attribute.
              if (_access_flags.is_final()) {
                classfile_parse_error("PermittedSubclasses attribute in final class file %s", CHECK);
                return;
              }
              parsed_permitted_subclasses_attribute = true;
              permitted_subclasses_attribute_start = cfs->current();
              permitted_subclasses_attribute_length = attribute_length;
            }
          }
          // Skip attribute_length for any attribute where major_verson >= JAVA_17_VERSION
          cfs->skip_u1(attribute_length, CHECK);
        } else {
          // Unknown attribute
          cfs->skip_u1(attribute_length, CHECK);
        }
      } else {
        // Unknown attribute
        cfs->skip_u1(attribute_length, CHECK);
      }
    } else {
      // Unknown attribute
      cfs->skip_u1(attribute_length, CHECK);
    }
  }
  _class_annotations = allocate_annotations(runtime_visible_annotations,
                                            runtime_visible_annotations_length,
                                            CHECK);
  _class_type_annotations = allocate_annotations(runtime_visible_type_annotations,
                                                 runtime_visible_type_annotations_length,
                                                 CHECK);

  if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
    const u2 num_of_classes = parse_classfile_inner_classes_attribute(
                            cfs,
                            cp,
                            inner_classes_attribute_start,
                            parsed_innerclasses_attribute,
                            enclosing_method_class_index,
                            enclosing_method_method_index,
                            CHECK);
    if (parsed_innerclasses_attribute && _need_verify && _major_version >= JAVA_1_5_VERSION) {
      guarantee_property(
        inner_classes_attribute_length == sizeof(num_of_classes) + 4 * sizeof(u2) * num_of_classes,
        "Wrong InnerClasses attribute length in class file %s", CHECK);
    }
  }

  if (parsed_nest_members_attribute) {
    const u2 num_of_classes = parse_classfile_nest_members_attribute(
                            cfs,
                            nest_members_attribute_start,
                            CHECK);
    if (_need_verify) {
      guarantee_property(
        nest_members_attribute_length == sizeof(num_of_classes) + sizeof(u2) * num_of_classes,
        "Wrong NestMembers attribute length in class file %s", CHECK);
    }
  }

  if (parsed_record_attribute) {
    const unsigned int calculated_attr_length = parse_classfile_record_attribute(
                            cfs,
                            cp,
                            record_attribute_start,
                            CHECK);
    if (_need_verify) {
      guarantee_property(record_attribute_length == calculated_attr_length,
                         "Record attribute has wrong length in class file %s",
                         CHECK);
    }
  }

  if (parsed_permitted_subclasses_attribute) {
    const u2 num_subclasses = parse_classfile_permitted_subclasses_attribute(
                            cfs,
                            permitted_subclasses_attribute_start,
                            CHECK);
    if (_need_verify) {
      guarantee_property(
        permitted_subclasses_attribute_length == sizeof(num_subclasses) + sizeof(u2) * num_subclasses,
        "Wrong PermittedSubclasses attribute length in class file %s", CHECK);
    }
  }

  if (_max_bootstrap_specifier_index >= 0) {
    guarantee_property(parsed_bootstrap_methods_attribute,
                       "Missing BootstrapMethods attribute in class file %s", CHECK);
  }
}

void ClassFileParser::apply_parsed_class_attributes(InstanceKlass* k) {
  assert(k != nullptr, "invariant");

  if (_synthetic_flag)
    k->set_is_synthetic();
  if (_sourcefile_index != 0) {
    k->set_source_file_name_index(_sourcefile_index);
  }
  if (_generic_signature_index != 0) {
    k->set_generic_signature_index(_generic_signature_index);
  }
  if (_sde_buffer != nullptr) {
    k->set_source_debug_extension(_sde_buffer, _sde_length);
  }
}

// Create the Annotations object that will
// hold the annotations array for the Klass.
void ClassFileParser::create_combined_annotations(TRAPS) {
    if (_class_annotations == nullptr &&
        _class_type_annotations == nullptr &&
        _fields_annotations == nullptr &&
        _fields_type_annotations == nullptr) {
      // Don't create the Annotations object unnecessarily.
      return;
    }

    Annotations* const annotations = Annotations::allocate(_loader_data, CHECK);
    annotations->set_class_annotations(_class_annotations);
    annotations->set_class_type_annotations(_class_type_annotations);
    annotations->set_fields_annotations(_fields_annotations);
    annotations->set_fields_type_annotations(_fields_type_annotations);

    // This is the Annotations object that will be
    // assigned to InstanceKlass being constructed.
    _combined_annotations = annotations;

    // The annotations arrays below has been transferred the
    // _combined_annotations so these fields can now be cleared.
    _class_annotations       = nullptr;
    _class_type_annotations  = nullptr;
    _fields_annotations      = nullptr;
    _fields_type_annotations = nullptr;
}

// Transfer ownership of metadata allocated to the InstanceKlass.
void ClassFileParser::apply_parsed_class_metadata(
                                            InstanceKlass* this_klass,
                                            int java_fields_count) {
  assert(this_klass != nullptr, "invariant");

  _cp->set_pool_holder(this_klass);
  this_klass->set_constants(_cp);
  this_klass->set_fieldinfo_stream(_fieldinfo_stream);
  this_klass->set_fieldinfo_search_table(_fieldinfo_search_table);
  this_klass->set_fields_status(_fields_status);
  this_klass->set_methods(_methods);
  this_klass->set_inner_classes(_inner_classes);
  this_klass->set_nest_members(_nest_members);
  this_klass->set_nest_host_index(_nest_host);
  this_klass->set_annotations(_combined_annotations);
  this_klass->set_permitted_subclasses(_permitted_subclasses);
  this_klass->set_record_components(_record_components);

  DEBUG_ONLY(FieldInfoStream::validate_search_table(_cp, _fieldinfo_stream, _fieldinfo_search_table));

  // Delay the setting of _local_interfaces and _transitive_interfaces until after
  // initialize_supers() in fill_instance_klass(). It is because the _local_interfaces could
  // be shared with _transitive_interfaces and _transitive_interfaces may be shared with
  // its _super. If an OOM occurs while loading the current klass, its _super field
  // may not have been set. When GC tries to free the klass, the _transitive_interfaces
  // may be deallocated mistakenly in InstanceKlass::deallocate_interfaces(). Subsequent
  // dereferences to the deallocated _transitive_interfaces will result in a crash.

  // Clear out these fields so they don't get deallocated by the destructor
  clear_class_metadata();
}

AnnotationArray* ClassFileParser::allocate_annotations(const u1* const anno,
                                                       int anno_length,
                                                       TRAPS) {
  AnnotationArray* annotations = nullptr;
  if (anno != nullptr) {
    annotations = MetadataFactory::new_array<u1>(_loader_data,
                                                 anno_length,
                                                 CHECK_(annotations));
    for (int i = 0; i < anno_length; i++) {
      annotations->at_put(i, anno[i]);
    }
  }
  return annotations;
}

const InstanceKlass* ClassFileParser::parse_super_class(ConstantPool* const cp,
                                                        const int super_class_index,
                                                        const bool need_verify,
                                                        TRAPS) {
  assert(cp != nullptr, "invariant");
  const InstanceKlass* super_klass = nullptr;

  if (super_class_index == 0) {
    guarantee_property(_class_name == vmSymbols::java_lang_Object(),
                       "Invalid superclass index %u in class file %s",
                       super_class_index,
                       CHECK_NULL);
  } else {
    guarantee_property(valid_klass_reference_at(super_class_index),
                       "Invalid superclass index %u in class file %s",
                       super_class_index,
                       CHECK_NULL);
    // The class name should be legal because it is checked when parsing constant pool.
    // However, make sure it is not an array type.
    bool is_array = false;
    if (cp->tag_at(super_class_index).is_klass()) {
      super_klass = InstanceKlass::cast(cp->resolved_klass_at(super_class_index));
      if (need_verify)
        is_array = super_klass->is_array_klass();
    } else if (need_verify) {
      is_array = (cp->klass_name_at(super_class_index)->char_at(0) == JVM_SIGNATURE_ARRAY);
    }
    if (need_verify) {
      guarantee_property(!is_array,
                        "Bad superclass name in class file %s", CHECK_NULL);
    }
  }
  return super_klass;
}

OopMapBlocksBuilder::OopMapBlocksBuilder(unsigned int max_blocks) {
  _max_nonstatic_oop_maps = max_blocks;
  _nonstatic_oop_map_count = 0;
  if (max_blocks == 0) {
    _nonstatic_oop_maps = nullptr;
  } else {
    _nonstatic_oop_maps =
        NEW_RESOURCE_ARRAY(OopMapBlock, _max_nonstatic_oop_maps);
    memset(_nonstatic_oop_maps, 0, sizeof(OopMapBlock) * max_blocks);
  }
}

OopMapBlock* OopMapBlocksBuilder::last_oop_map() const {
  assert(_nonstatic_oop_map_count > 0, "Has no oop maps");
  return _nonstatic_oop_maps + (_nonstatic_oop_map_count - 1);
}

// addition of super oop maps
void OopMapBlocksBuilder::initialize_inherited_blocks(OopMapBlock* blocks, unsigned int nof_blocks) {
  assert(nof_blocks && _nonstatic_oop_map_count == 0 &&
         nof_blocks <= _max_nonstatic_oop_maps, "invariant");

  memcpy(_nonstatic_oop_maps, blocks, sizeof(OopMapBlock) * nof_blocks);
  _nonstatic_oop_map_count += nof_blocks;
}

// collection of oops
void OopMapBlocksBuilder::add(int offset, int count) {
  if (_nonstatic_oop_map_count == 0) {
    _nonstatic_oop_map_count++;
  }
  OopMapBlock* nonstatic_oop_map = last_oop_map();
  if (nonstatic_oop_map->count() == 0) {  // Unused map, set it up
    nonstatic_oop_map->set_offset(offset);
    nonstatic_oop_map->set_count(count);
  } else if (nonstatic_oop_map->is_contiguous(offset)) { // contiguous, add
    nonstatic_oop_map->increment_count(count);
  } else { // Need a new one...
    _nonstatic_oop_map_count++;
    assert(_nonstatic_oop_map_count <= _max_nonstatic_oop_maps, "range check");
    nonstatic_oop_map = last_oop_map();
    nonstatic_oop_map->set_offset(offset);
    nonstatic_oop_map->set_count(count);
  }
}

// general purpose copy, e.g. into allocated instanceKlass
void OopMapBlocksBuilder::copy(OopMapBlock* dst) {
  if (_nonstatic_oop_map_count != 0) {
    memcpy(dst, _nonstatic_oop_maps, sizeof(OopMapBlock) * _nonstatic_oop_map_count);
  }
}

// Sort and compact adjacent blocks
void OopMapBlocksBuilder::compact() {
  if (_nonstatic_oop_map_count <= 1) {
    return;
  }
  /*
   * Since field layout sneaks in oops before values, we will be able to condense
   * blocks. There is potential to compact between super, own refs and values
   * containing refs.
   *
   * Currently compaction is slightly limited due to values being 8 byte aligned.
   * This may well change: FixMe if it doesn't, the code below is fairly general purpose
   * and maybe it doesn't need to be.
   */
  qsort(_nonstatic_oop_maps, _nonstatic_oop_map_count, sizeof(OopMapBlock),
        (_sort_Fn)OopMapBlock::compare_offset);
  if (_nonstatic_oop_map_count < 2) {
    return;
  }

  // Make a temp copy, and iterate through and copy back into the original
  ResourceMark rm;
  OopMapBlock* oop_maps_copy =
      NEW_RESOURCE_ARRAY(OopMapBlock, _nonstatic_oop_map_count);
  OopMapBlock* oop_maps_copy_end = oop_maps_copy + _nonstatic_oop_map_count;
  copy(oop_maps_copy);
  OopMapBlock* nonstatic_oop_map = _nonstatic_oop_maps;
  unsigned int new_count = 1;
  oop_maps_copy++;
  while(oop_maps_copy < oop_maps_copy_end) {
    assert(nonstatic_oop_map->offset() < oop_maps_copy->offset(), "invariant");
    if (nonstatic_oop_map->is_contiguous(oop_maps_copy->offset())) {
      nonstatic_oop_map->increment_count(oop_maps_copy->count());
    } else {
      nonstatic_oop_map++;
      new_count++;
      nonstatic_oop_map->set_offset(oop_maps_copy->offset());
      nonstatic_oop_map->set_count(oop_maps_copy->count());
    }
    oop_maps_copy++;
  }
  assert(new_count <= _nonstatic_oop_map_count, "end up with more maps after compact() ?");
  _nonstatic_oop_map_count = new_count;
}

void OopMapBlocksBuilder::print_on(outputStream* st) const {
  st->print_cr("  OopMapBlocks: %3d  /%3d", _nonstatic_oop_map_count, _max_nonstatic_oop_maps);
  if (_nonstatic_oop_map_count > 0) {
    OopMapBlock* map = _nonstatic_oop_maps;
    OopMapBlock* last_map = last_oop_map();
    assert(map <= last_map, "Last less than first");
    while (map <= last_map) {
      st->print_cr("    Offset: %3d  -%3d Count: %3d", map->offset(),
                   map->offset() + map->offset_span() - heapOopSize, map->count());
      map++;
    }
  }
}

void OopMapBlocksBuilder::print_value_on(outputStream* st) const {
  print_on(st);
}

void ClassFileParser::set_precomputed_flags(InstanceKlass* ik) {
  assert(ik != nullptr, "invariant");

  const InstanceKlass* const super = ik->java_super();

  // Check if this klass has an empty finalize method (i.e. one with return bytecode only),
  // in which case we don't have to register objects as finalizable
  if (!_has_empty_finalizer) {
    if (_has_finalizer ||
        (super != nullptr && super->has_finalizer())) {
      ik->set_has_finalizer();
    }
  }

#ifdef ASSERT
  bool f = false;
  const Method* const m = ik->lookup_method(vmSymbols::finalize_method_name(),
                                           vmSymbols::void_method_signature());
  if (InstanceKlass::is_finalization_enabled() &&
      (m != nullptr) && !m->is_empty_method()) {
      f = true;
  }

  // Spec doesn't prevent agent from redefinition of empty finalizer.
  // Despite the fact that it's generally bad idea and redefined finalizer
  // will not work as expected we shouldn't abort vm in this case
  if (!ik->has_redefined_this_or_super()) {
    assert(ik->has_finalizer() == f, "inconsistent has_finalizer");
  }
#endif

  // Check if this klass supports the java.lang.Cloneable interface
  if (vmClasses::Cloneable_klass_loaded()) {
    if (ik->is_subtype_of(vmClasses::Cloneable_klass())) {
      ik->set_is_cloneable();
    }
  }

  // If it cannot be fast-path allocated, set a bit in the layout helper.
  // See documentation of InstanceKlass::can_be_fastpath_allocated().
  assert(ik->size_helper() > 0, "layout_helper is initialized");
  if (ik->is_abstract() || ik->is_interface()
      || (ik->name() == vmSymbols::java_lang_Class() && ik->class_loader() == nullptr)
      || ik->size_helper() >= FastAllocateSizeLimit) {
    // Forbid fast-path allocation.
    const jint lh = Klass::instance_layout_helper(ik->size_helper(), true);
    ik->set_layout_helper(lh);
  }
}

// utility methods for appending an array with check for duplicates

static void append_interfaces(GrowableArray<InstanceKlass*>* result,
                              const Array<InstanceKlass*>* const ifs) {
  // iterate over new interfaces
  for (int i = 0; i < ifs->length(); i++) {
    InstanceKlass* const e = ifs->at(i);
    assert(e->is_klass() && e->is_interface(), "just checking");
    // add new interface
    result->append_if_missing(e);
  }
}

static Array<InstanceKlass*>* compute_transitive_interfaces(const InstanceKlass* super,
                                                            Array<InstanceKlass*>* local_ifs,
                                                            ClassLoaderData* loader_data,
                                                            TRAPS) {
  assert(local_ifs != nullptr, "invariant");
  assert(loader_data != nullptr, "invariant");

  // Compute maximum size for transitive interfaces
  int max_transitive_size = 0;
  int super_size = 0;
  // Add superclass transitive interfaces size
  if (super != nullptr) {
    super_size = super->transitive_interfaces()->length();
    max_transitive_size += super_size;
  }
  // Add local interfaces' super interfaces
  const int local_size = local_ifs->length();
  for (int i = 0; i < local_size; i++) {
    InstanceKlass* const l = local_ifs->at(i);
    max_transitive_size += l->transitive_interfaces()->length();
  }
  // Finally add local interfaces
  max_transitive_size += local_size;
  // Construct array
  if (max_transitive_size == 0) {
    // no interfaces, use canonicalized array
    return Universe::the_empty_instance_klass_array();
  } else if (max_transitive_size == super_size) {
    // no new local interfaces added, share superklass' transitive interface array
    return super->transitive_interfaces();
  } else if (max_transitive_size == local_size) {
    // only local interfaces added, share local interface array
    return local_ifs;
  } else {
    ResourceMark rm;
    GrowableArray<InstanceKlass*>* const result = new GrowableArray<InstanceKlass*>(max_transitive_size);

    // Copy down from superclass
    if (super != nullptr) {
      append_interfaces(result, super->transitive_interfaces());
    }

    // Copy down from local interfaces' superinterfaces
    for (int i = 0; i < local_size; i++) {
      InstanceKlass* const l = local_ifs->at(i);
      append_interfaces(result, l->transitive_interfaces());
    }
    // Finally add local interfaces
    append_interfaces(result, local_ifs);

    // length will be less than the max_transitive_size if duplicates were removed
    const int length = result->length();
    assert(length <= max_transitive_size, "just checking");
    Array<InstanceKlass*>* const new_result =
      MetadataFactory::new_array<InstanceKlass*>(loader_data, length, CHECK_NULL);
    for (int i = 0; i < length; i++) {
      InstanceKlass* const e = result->at(i);
      assert(e != nullptr, "just checking");
      new_result->at_put(i, e);
    }
    return new_result;
  }
}

void ClassFileParser::check_super_class_access(const InstanceKlass* this_klass, TRAPS) {
  assert(this_klass != nullptr, "invariant");
  const Klass* const super = this_klass->super();

  if (super != nullptr) {
    const InstanceKlass* super_ik = InstanceKlass::cast(super);

    if (super->is_final()) {
      classfile_icce_error("class %s cannot inherit from final class %s", super_ik, THREAD);
      return;
    }

    if (super_ik->is_sealed()) {
      stringStream ss;
      ResourceMark rm(THREAD);
      if (!super_ik->has_as_permitted_subclass(this_klass, ss)) {
        classfile_icce_error(ss.as_string(), THREAD);
        return;
      }
    }

    Reflection::VerifyClassAccessResults vca_result =
      Reflection::verify_class_access(this_klass, InstanceKlass::cast(super), false);
    if (vca_result != Reflection::ACCESS_OK) {
      ResourceMark rm(THREAD);
      char* msg = Reflection::verify_class_access_msg(this_klass,
                                                      InstanceKlass::cast(super),
                                                      vca_result);

      // Names are all known to be < 64k so we know this formatted message is not excessively large.
      if (msg == nullptr) {
        bool same_module = (this_klass->module() == super->module());
        Exceptions::fthrow(
          THREAD_AND_LOCATION,
          vmSymbols::java_lang_IllegalAccessError(),
          "class %s cannot access its %ssuperclass %s (%s%s%s)",
          this_klass->external_name(),
          super->is_abstract() ? "abstract " : "",
          super->external_name(),
          (same_module) ? this_klass->joint_in_module_of_loader(super) : this_klass->class_in_module_of_loader(),
          (same_module) ? "" : "; ",
          (same_module) ? "" : super->class_in_module_of_loader());
      } else {
        // Add additional message content.
        Exceptions::fthrow(
          THREAD_AND_LOCATION,
          vmSymbols::java_lang_IllegalAccessError(),
          "superclass access check failed: %s",
          msg);
      }
    }
  }
}


void ClassFileParser::check_super_interface_access(const InstanceKlass* this_klass, TRAPS) {
  assert(this_klass != nullptr, "invariant");
  const Array<InstanceKlass*>* const local_interfaces = this_klass->local_interfaces();
  const int lng = local_interfaces->length();
  for (int i = lng - 1; i >= 0; i--) {
    InstanceKlass* const k = local_interfaces->at(i);
    assert (k != nullptr && k->is_interface(), "invalid interface");

    if (k->is_sealed()) {
      stringStream ss;
      ResourceMark rm(THREAD);
      if (!k->has_as_permitted_subclass(this_klass, ss)) {
        classfile_icce_error(ss.as_string(), THREAD);
        return;
      }
    }

    Reflection::VerifyClassAccessResults vca_result =
      Reflection::verify_class_access(this_klass, k, false);
    if (vca_result != Reflection::ACCESS_OK) {
      ResourceMark rm(THREAD);
      char* msg = Reflection::verify_class_access_msg(this_klass,
                                                      k,
                                                      vca_result);

      // Names are all known to be < 64k so we know this formatted message is not excessively large.
      if (msg == nullptr) {
        bool same_module = (this_klass->module() == k->module());
        Exceptions::fthrow(
          THREAD_AND_LOCATION,
          vmSymbols::java_lang_IllegalAccessError(),
          "class %s cannot access its superinterface %s (%s%s%s)",
          this_klass->external_name(),
          k->external_name(),
          (same_module) ? this_klass->joint_in_module_of_loader(k) : this_klass->class_in_module_of_loader(),
          (same_module) ? "" : "; ",
          (same_module) ? "" : k->class_in_module_of_loader());
        return;
      } else {
        // Add additional message content.
        Exceptions::fthrow(
          THREAD_AND_LOCATION,
          vmSymbols::java_lang_IllegalAccessError(),
          "superinterface check failed: %s",
          msg);
        return;
      }
    }
  }
}


static void check_final_method_override(const InstanceKlass* this_klass, TRAPS) {
  assert(this_klass != nullptr, "invariant");
  const Array<Method*>* const methods = this_klass->methods();
  const int num_methods = methods->length();

  // go thru each method and check if it overrides a final method
  for (int index = 0; index < num_methods; index++) {
    const Method* const m = methods->at(index);

    // skip private, static, and <init> methods
    if ((!m->is_private() && !m->is_static()) &&
        (m->name() != vmSymbols::object_initializer_name())) {

      const Symbol* const name = m->name();
      const Symbol* const signature = m->signature();
      const InstanceKlass* k = this_klass->java_super();
      const Method* super_m = nullptr;
      while (k != nullptr) {
        // skip supers that don't have final methods.
        if (k->has_final_method()) {
          // lookup a matching method in the super class hierarchy
          super_m = InstanceKlass::cast(k)->lookup_method(name, signature);
          if (super_m == nullptr) {
            break; // didn't find any match; get out
          }

          if (super_m->is_final() && !super_m->is_static() &&
              !super_m->access_flags().is_private()) {
            // matching method in super is final, and not static or private
            bool can_access = Reflection::verify_member_access(this_klass,
                                                               super_m->method_holder(),
                                                               super_m->method_holder(),
                                                               super_m->access_flags(),
                                                              false, false, CHECK);
            if (can_access) {
              // this class can access super final method and therefore override
              ResourceMark rm(THREAD);
              THROW_MSG(vmSymbols::java_lang_IncompatibleClassChangeError(),
                        err_msg("class %s overrides final method %s.%s%s",
                                this_klass->external_name(),
                                super_m->method_holder()->external_name(),
                                name->as_C_string(),
                                signature->as_C_string()));
            }
          }

          // continue to look from super_m's holder's super.
          k = super_m->method_holder()->java_super();
          continue;
        }

        k = k->java_super();
      }
    }
  }
}


// assumes that this_klass is an interface
static void check_illegal_static_method(const InstanceKlass* this_klass, TRAPS) {
  assert(this_klass != nullptr, "invariant");
  assert(this_klass->is_interface(), "not an interface");
  const Array<Method*>* methods = this_klass->methods();
  const int num_methods = methods->length();

  for (int index = 0; index < num_methods; index++) {
    const Method* const m = methods->at(index);
    // if m is static and not the init method, throw a verify error
    if ((m->is_static()) && (m->name() != vmSymbols::class_initializer_name())) {
      ResourceMark rm(THREAD);

      // Names are all known to be < 64k so we know this formatted message is not excessively large.
      Exceptions::fthrow(
        THREAD_AND_LOCATION,
        vmSymbols::java_lang_VerifyError(),
        "Illegal static method %s in interface %s",
        m->name()->as_C_string(),
        this_klass->external_name()
      );
      return;
    }
  }
}

// utility methods for format checking

void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) const {
  const bool is_module = (flags & JVM_ACC_MODULE) != 0;
  assert(_major_version >= JAVA_9_VERSION || !is_module, "JVM_ACC_MODULE should not be set");
  if (is_module) {
    ResourceMark rm(THREAD);
    // Names are all known to be < 64k so we know this formatted message is not excessively large.
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_NoClassDefFoundError(),
      "%s is not a class because access_flag ACC_MODULE is set",
      _class_name->as_C_string());
    return;
  }

  if (!_need_verify) { return; }

  const bool is_interface  = (flags & JVM_ACC_INTERFACE)  != 0;
  const bool is_abstract   = (flags & JVM_ACC_ABSTRACT)   != 0;
  const bool is_final      = (flags & JVM_ACC_FINAL)      != 0;
  const bool is_super      = (flags & JVM_ACC_SUPER)      != 0;
  const bool is_enum       = (flags & JVM_ACC_ENUM)       != 0;
  const bool is_annotation = (flags & JVM_ACC_ANNOTATION) != 0;
  const bool major_gte_1_5 = _major_version >= JAVA_1_5_VERSION;

  if ((is_abstract && is_final) ||
      (is_interface && !is_abstract) ||
      (is_interface && major_gte_1_5 && (is_super || is_enum)) ||
      (!is_interface && major_gte_1_5 && is_annotation)) {
    ResourceMark rm(THREAD);
    // Names are all known to be < 64k so we know this formatted message is not excessively large.
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Illegal class modifiers in class %s: 0x%X",
      _class_name->as_C_string(), flags
    );
    return;
  }
}

static bool has_illegal_visibility(jint flags) {
  const bool is_public    = (flags & JVM_ACC_PUBLIC)    != 0;
  const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
  const bool is_private   = (flags & JVM_ACC_PRIVATE)   != 0;

  return ((is_public && is_protected) ||
          (is_public && is_private) ||
          (is_protected && is_private));
}

// A legal major_version.minor_version must be one of the following:
//
//  Major_version >= 45 and major_version < 56, any minor_version.
//  Major_version >= 56 and major_version <= JVM_CLASSFILE_MAJOR_VERSION and minor_version = 0.
//  Major_version = JVM_CLASSFILE_MAJOR_VERSION and minor_version = 65535 and --enable-preview is present.
//
void ClassFileParser::verify_class_version(u2 major, u2 minor, Symbol* class_name, TRAPS){
  ResourceMark rm(THREAD);
  const u2 max_version = JVM_CLASSFILE_MAJOR_VERSION;
  if (major < JAVA_MIN_SUPPORTED_VERSION) {
    classfile_ucve_error("%s (class file version %u.%u) was compiled with an invalid major version",
                         class_name, major, minor, THREAD);
    return;
  }

  if (major > max_version) {
    // Names are all known to be < 64k so we know this formatted message is not excessively large.
    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.0",
      class_name->as_C_string(), major, minor, JVM_CLASSFILE_MAJOR_VERSION);
    return;
  }

  if (major < JAVA_12_VERSION || minor == 0) {
    return;
  }

  if (minor == JAVA_PREVIEW_MINOR_VERSION) {
    if (major != max_version) {
      // Names are all known to be < 64k so we know this formatted message is not excessively large.
      Exceptions::fthrow(
        THREAD_AND_LOCATION,
        vmSymbols::java_lang_UnsupportedClassVersionError(),
        "%s (class file version %u.%u) was compiled with preview features that are unsupported. "
        "This version of the Java Runtime only recognizes preview features for class file version %u.%u",
        class_name->as_C_string(), major, minor, JVM_CLASSFILE_MAJOR_VERSION, JAVA_PREVIEW_MINOR_VERSION);
      return;
    }

    if (!Arguments::enable_preview()) {
      classfile_ucve_error("Preview features are not enabled for %s (class file version %u.%u). Try running with '--enable-preview'",
                           class_name, major, minor, THREAD);
      return;
    }

  } else { // minor != JAVA_PREVIEW_MINOR_VERSION
    classfile_ucve_error("%s (class file version %u.%u) was compiled with an invalid non-zero minor version",
                         class_name, major, minor, THREAD);
  }
}

void ClassFileParser::verify_legal_field_modifiers(jint flags,
                                                   bool is_interface,
                                                   TRAPS) const {
  if (!_need_verify) { return; }

  const bool is_public    = (flags & JVM_ACC_PUBLIC)    != 0;
  const bool is_protected = (flags & JVM_ACC_PROTECTED) != 0;
  const bool is_private   = (flags & JVM_ACC_PRIVATE)   != 0;
  const bool is_static    = (flags & JVM_ACC_STATIC)    != 0;
  const bool is_final     = (flags & JVM_ACC_FINAL)     != 0;
  const bool is_volatile  = (flags & JVM_ACC_VOLATILE)  != 0;
  const bool is_transient = (flags & JVM_ACC_TRANSIENT) != 0;
  const bool is_enum      = (flags & JVM_ACC_ENUM)      != 0;
  const bool major_gte_1_5 = _major_version >= JAVA_1_5_VERSION;

  bool is_illegal = false;

  if (is_interface) {
    if (!is_public || !is_static || !is_final || is_private ||
        is_protected || is_volatile || is_transient ||
        (major_gte_1_5 && is_enum)) {
      is_illegal = true;
    }
  } else { // not interface
    if (has_illegal_visibility(flags) || (is_final && is_volatile)) {
      is_illegal = true;
    }
  }

  if (is_illegal) {
    ResourceMark rm(THREAD);
    // Names are all known to be < 64k so we know this formatted message is not excessively large.
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Illegal field modifiers in class %s: 0x%X",
      _class_name->as_C_string(), flags);
    return;
  }
}

void ClassFileParser::verify_legal_method_modifiers(jint flags,
                                                    bool is_interface,
                                                    const Symbol* name,
                                                    TRAPS) const {
  if (!_need_verify) { return; }

  const bool is_public       = (flags & JVM_ACC_PUBLIC)       != 0;
  const bool is_private      = (flags & JVM_ACC_PRIVATE)      != 0;
  const bool is_static       = (flags & JVM_ACC_STATIC)       != 0;
  const bool is_final        = (flags & JVM_ACC_FINAL)        != 0;
  const bool is_native       = (flags & JVM_ACC_NATIVE)       != 0;
  const bool is_abstract     = (flags & JVM_ACC_ABSTRACT)     != 0;
  const bool is_bridge       = (flags & JVM_ACC_BRIDGE)       != 0;
  const bool is_strict       = (flags & JVM_ACC_STRICT)       != 0;
  const bool is_synchronized = (flags & JVM_ACC_SYNCHRONIZED) != 0;
  const bool is_protected    = (flags & JVM_ACC_PROTECTED)    != 0;
  const bool major_gte_1_5   = _major_version >= JAVA_1_5_VERSION;
  const bool major_gte_8     = _major_version >= JAVA_8_VERSION;
  const bool major_gte_17    = _major_version >= JAVA_17_VERSION;
  const bool is_initializer  = (name == vmSymbols::object_initializer_name());

  bool is_illegal = false;

  if (is_interface) {
    if (major_gte_8) {
      // Class file version is JAVA_8_VERSION or later Methods of
      // interfaces may set any of the flags except ACC_PROTECTED,
      // ACC_FINAL, ACC_NATIVE, and ACC_SYNCHRONIZED; they must
      // have exactly one of the ACC_PUBLIC or ACC_PRIVATE flags set.
      if ((is_public == is_private) || /* Only one of private and public should be true - XNOR */
          (is_native || is_protected || is_final || is_synchronized) ||
          // If a specific method of a class or interface has its
          // ACC_ABSTRACT flag set, it must not have any of its
          // ACC_FINAL, ACC_NATIVE, ACC_PRIVATE, ACC_STATIC,
          // ACC_STRICT, or ACC_SYNCHRONIZED flags set.  No need to
          // check for ACC_FINAL, ACC_NATIVE or ACC_SYNCHRONIZED as
          // those flags are illegal irrespective of ACC_ABSTRACT being set or not.
          (is_abstract && (is_private || is_static || (!major_gte_17 && is_strict)))) {
        is_illegal = true;
      }
    } else if (major_gte_1_5) {
      // Class file version in the interval [JAVA_1_5_VERSION, JAVA_8_VERSION)
      if (!is_public || is_private || is_protected || is_static || is_final ||
          is_synchronized || is_native || !is_abstract || is_strict) {
        is_illegal = true;
      }
    } else {
      // Class file version is pre-JAVA_1_5_VERSION
      if (!is_public || is_static || is_final || is_native || !is_abstract) {
        is_illegal = true;
      }
    }
  } else { // not interface
    if (has_illegal_visibility(flags)) {
      is_illegal = true;
    } else {
      if (is_initializer) {
        if (is_static || is_final || is_synchronized || is_native ||
            is_abstract || (major_gte_1_5 && is_bridge)) {
          is_illegal = true;
        }
      } else { // not initializer
        if (is_abstract) {
          if ((is_final || is_native || is_private || is_static ||
              (major_gte_1_5 && (is_synchronized || (!major_gte_17 && is_strict))))) {
            is_illegal = true;
          }
        }
      }
    }
  }

  if (is_illegal) {
    ResourceMark rm(THREAD);
    // Names are all known to be < 64k so we know this formatted message is not excessively large.
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Method %s in class %s has illegal modifiers: 0x%X",
      name->as_C_string(), _class_name->as_C_string(), flags);
    return;
  }
}

void ClassFileParser::verify_legal_utf8(const unsigned char* buffer,
                                        int length,
                                        TRAPS) const {
  assert(_need_verify, "only called when _need_verify is true");
  // Note: 0 <= length < 64K, as it comes from a u2 entry in the CP.
  if (!UTF8::is_legal_utf8(buffer, static_cast<size_t>(length), _major_version <= 47)) {
    classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", THREAD);
  }
}

// Unqualified names may not contain the characters '.', ';', '[', or '/'.
// In class names, '/' separates unqualified names.  This is verified in this function also.
// Method names also may not contain the characters '<' or '>', unless <init>
// or <clinit>.  Note that method names may not be <init> or <clinit> in this
// method.  Because these names have been checked as special cases before
// calling this method in verify_legal_method_name.
//
// This method is also called from the modular system APIs in modules.cpp
// to verify the validity of module and package names.
bool ClassFileParser::verify_unqualified_name(const char* name,
                                              unsigned int length,
                                              int type) {
  if (length == 0) return false;  // Must have at least one char.
  for (const char* p = name; p != name + length; p++) {
    switch(*p) {
      case JVM_SIGNATURE_DOT:
      case JVM_SIGNATURE_ENDCLASS:
      case JVM_SIGNATURE_ARRAY:
        // do not permit '.', ';', or '['
        return false;
      case JVM_SIGNATURE_SLASH:
        // check for '//' or leading or trailing '/' which are not legal
        // unqualified name must not be empty
        if (type == ClassFileParser::LegalClass) {
          if (p == name || p+1 >= name+length ||
              *(p+1) == JVM_SIGNATURE_SLASH) {
            return false;
          }
        } else {
          return false;   // do not permit '/' unless it's class name
        }
        break;
      case JVM_SIGNATURE_SPECIAL:
      case JVM_SIGNATURE_ENDSPECIAL:
        // do not permit '<' or '>' in method names
        if (type == ClassFileParser::LegalMethod) {
          return false;
        }
    }
  }
  return true;
}

// Take pointer to a UTF8 byte string (not NUL-terminated).
// Skip over the longest part of the string that could
// be taken as a fieldname. Allow non-trailing '/'s if slash_ok is true.
// Return a pointer to just past the fieldname.
// Return null if no fieldname at all was found, or in the case of slash_ok
// being true, we saw consecutive slashes (meaning we were looking for a
// qualified path but found something that was badly-formed).
static const char* skip_over_field_name(const char* const name,
                                        bool slash_ok,
                                        unsigned int length) {
  const char* p;
  jboolean last_is_slash = false;
  jboolean not_first_ch = false;

  for (p = name; p != name + length; not_first_ch = true) {
    const char* old_p = p;
    jchar ch = *p;
    if (ch < 128) {
      p++;
      // quick check for ascii
      if ((ch >= 'a' && ch <= 'z') ||
        (ch >= 'A' && ch <= 'Z') ||
        (ch == '_' || ch == '$') ||
        (not_first_ch && ch >= '0' && ch <= '9')) {
        last_is_slash = false;
        continue;
      }
      if (slash_ok && ch == JVM_SIGNATURE_SLASH) {
        if (last_is_slash) {
          return nullptr;  // Don't permit consecutive slashes
        }
        last_is_slash = true;
        continue;
      }
    }
    else {
      jint unicode_ch;
      char* tmp_p = UTF8::next_character(p, &unicode_ch);
      p = tmp_p;
      last_is_slash = false;
      // Check if ch is Java identifier start or is Java identifier part
      // 4672820: call java.lang.Character methods directly without generating separate tables.
      EXCEPTION_MARK;
      // return value
      JavaValue result(T_BOOLEAN);
      // Set up the arguments to isJavaIdentifierStart or isJavaIdentifierPart
      JavaCallArguments args;
      args.push_int(unicode_ch);

      if (not_first_ch) {
        // public static boolean isJavaIdentifierPart(char ch);
        JavaCalls::call_static(&result,
          vmClasses::Character_klass(),
          vmSymbols::isJavaIdentifierPart_name(),
          vmSymbols::int_bool_signature(),
          &args,
          THREAD);
      } else {
        // public static boolean isJavaIdentifierStart(char ch);
        JavaCalls::call_static(&result,
          vmClasses::Character_klass(),
          vmSymbols::isJavaIdentifierStart_name(),
          vmSymbols::int_bool_signature(),
          &args,
          THREAD);
      }
      if (HAS_PENDING_EXCEPTION) {
        CLEAR_PENDING_EXCEPTION;
        return nullptr;
      }
      if(result.get_jboolean()) {
        continue;
      }
    }
    return (not_first_ch) ? old_p : nullptr;
  }
  return (not_first_ch && !last_is_slash) ? p : nullptr;
}

// Take pointer to a UTF8 byte string (not NUL-terminated).
// Skip over the longest part of the string that could
// be taken as a field signature. Allow "void" if void_ok.
// Return a pointer to just past the signature.
// Return null if no legal signature is found.
const char* ClassFileParser::skip_over_field_signature(const char* signature,
                                                       bool void_ok,
                                                       unsigned int length,
                                                       TRAPS) const {
  unsigned int array_dim = 0;
  while (length > 0) {
    switch (signature[0]) {
    case JVM_SIGNATURE_VOID: if (!void_ok) { return nullptr; }
    case JVM_SIGNATURE_BOOLEAN:
    case JVM_SIGNATURE_BYTE:
    case JVM_SIGNATURE_CHAR:
    case JVM_SIGNATURE_SHORT:
    case JVM_SIGNATURE_INT:
    case JVM_SIGNATURE_FLOAT:
    case JVM_SIGNATURE_LONG:
    case JVM_SIGNATURE_DOUBLE:
      return signature + 1;
    case JVM_SIGNATURE_CLASS: {
      if (_major_version < JAVA_1_5_VERSION) {
        // Skip over the class name if one is there
        const char* const p = skip_over_field_name(signature + 1, true, --length);

        // The next character better be a semicolon
        if (p && (p - signature) > 1 && p[0] == JVM_SIGNATURE_ENDCLASS) {
          return p + 1;
        }
      }
      else {
        // Skip leading 'L' and ignore first appearance of ';'
        signature++;
        const char* c = (const char*) memchr(signature, JVM_SIGNATURE_ENDCLASS, length - 1);
        // Format check signature
        if (c != nullptr) {
          int newlen = pointer_delta_as_int(c, (char*) signature);
          bool legal = verify_unqualified_name(signature, newlen, LegalClass);
          if (!legal) {
            classfile_parse_error("Class name is empty or contains illegal character "
                                  "in descriptor in class file %s",
                                  THREAD);
            return nullptr;
          }
          return signature + newlen + 1;
        }
      }
      return nullptr;
    }
    case JVM_SIGNATURE_ARRAY:
      array_dim++;
      if (array_dim > 255) {
        // 4277370: array descriptor is valid only if it represents 255 or fewer dimensions.
        classfile_parse_error("Array type descriptor has more than 255 dimensions in class file %s", THREAD);
        return nullptr;
      }
      // The rest of what's there better be a legal signature
      signature++;
      length--;
      void_ok = false;
      break;
    default:
      return nullptr;
    }
  }
  return nullptr;
}

// Checks if name is a legal class name.
void ClassFileParser::verify_legal_class_name(const Symbol* name, TRAPS) const {
  if (!_need_verify) { return; }

  assert(name->refcount() > 0, "symbol must be kept alive");
  char* bytes = (char*)name->bytes();
  unsigned int length = name->utf8_length();
  bool legal = false;

  if (length > 0) {
    const char* p;
    if (bytes[0] == JVM_SIGNATURE_ARRAY) {
      p = skip_over_field_signature(bytes, false, length, CHECK);
      legal = (p != nullptr) && ((p - bytes) == (int)length);
    } else if (_major_version < JAVA_1_5_VERSION) {
      if (bytes[0] != JVM_SIGNATURE_SPECIAL) {
        p = skip_over_field_name(bytes, true, length);
        legal = (p != nullptr) && ((p - bytes) == (int)length);
      }
    } else {
      // 4900761: relax the constraints based on JSR202 spec
      // Class names may be drawn from the entire Unicode character set.
      // Identifiers between '/' must be unqualified names.
      // The utf8 string has been verified when parsing cpool entries.
      legal = verify_unqualified_name(bytes, length, LegalClass);
    }
  }
  if (!legal) {
    ResourceMark rm(THREAD);
    assert(_class_name != nullptr, "invariant");
    // Names are all known to be < 64k so we know this formatted message is not excessively large.
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Illegal class name \"%.*s\" in class file %s", length, bytes,
      _class_name->as_C_string()
    );
    return;
  }
}

// Checks if name is a legal field name.
void ClassFileParser::verify_legal_field_name(const Symbol* name, TRAPS) const {
  if (!_need_verify) { return; }

  char* bytes = (char*)name->bytes();
  unsigned int length = name->utf8_length();
  bool legal = false;

  if (length > 0) {
    if (_major_version < JAVA_1_5_VERSION) {
      if (bytes[0] != JVM_SIGNATURE_SPECIAL) {
        const char* p = skip_over_field_name(bytes, false, length);
        legal = (p != nullptr) && ((p - bytes) == (int)length);
      }
    } else {
      // 4881221: relax the constraints based on JSR202 spec
      legal = verify_unqualified_name(bytes, length, LegalField);
    }
  }

  if (!legal) {
    ResourceMark rm(THREAD);
    assert(_class_name != nullptr, "invariant");
    // Names are all known to be < 64k so we know this formatted message is not excessively large.
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Illegal field name \"%.*s\" in class %s", length, bytes,
      _class_name->as_C_string()
    );
    return;
  }
}

// Checks if name is a legal method name.
void ClassFileParser::verify_legal_method_name(const Symbol* name, TRAPS) const {
  if (!_need_verify) { return; }

  assert(name != nullptr, "method name is null");
  char* bytes = (char*)name->bytes();
  unsigned int length = name->utf8_length();
  bool legal = false;

  if (length > 0) {
    if (bytes[0] == JVM_SIGNATURE_SPECIAL) {
      if (name == vmSymbols::object_initializer_name() || name == vmSymbols::class_initializer_name()) {
        legal = true;
      }
    } else if (_major_version < JAVA_1_5_VERSION) {
      const char* p;
      p = skip_over_field_name(bytes, false, length);
      legal = (p != nullptr) && ((p - bytes) == (int)length);
    } else {
      // 4881221: relax the constraints based on JSR202 spec
      legal = verify_unqualified_name(bytes, length, LegalMethod);
    }
  }

  if (!legal) {
    ResourceMark rm(THREAD);
    assert(_class_name != nullptr, "invariant");
    // Names are all known to be < 64k so we know this formatted message is not excessively large.
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Illegal method name \"%.*s\" in class %s", length, bytes,
      _class_name->as_C_string()
    );
    return;
  }
}


// Checks if signature is a legal field signature.
void ClassFileParser::verify_legal_field_signature(const Symbol* name,
                                                   const Symbol* signature,
                                                   TRAPS) const {
  if (!_need_verify) { return; }

  const char* const bytes = (const char*)signature->bytes();
  const unsigned int length = signature->utf8_length();
  const char* const p = skip_over_field_signature(bytes, false, length, CHECK);

  if (p == nullptr || (p - bytes) != (int)length) {
    throwIllegalSignature("Field", name, signature, CHECK);
  }
}

// Check that the signature is compatible with the method name.  For example,
// check that <init> has a void signature.
void ClassFileParser::verify_legal_name_with_signature(const Symbol* name,
                                                       const Symbol* signature,
                                                       TRAPS) const {
  if (!_need_verify) {
    return;
  }

  // Class initializers cannot have args for class format version >= 51.
  if (name == vmSymbols::class_initializer_name() &&
      signature != vmSymbols::void_method_signature() &&
      _major_version >= JAVA_7_VERSION) {
    throwIllegalSignature("Method", name, signature, THREAD);
    return;
  }

  int sig_length = signature->utf8_length();
  if (name->utf8_length() > 0 &&
      name->char_at(0) == JVM_SIGNATURE_SPECIAL &&
      sig_length > 0 &&
      signature->char_at(sig_length - 1) != JVM_SIGNATURE_VOID) {
    throwIllegalSignature("Method", name, signature, THREAD);
  }
}

// Checks if signature is a legal method signature.
// Returns number of parameters
int ClassFileParser::verify_legal_method_signature(const Symbol* name,
                                                   const Symbol* signature,
                                                   TRAPS) const {
  if (!_need_verify) {
    // make sure caller's args_size will be less than 0 even for non-static
    // method so it will be recomputed in compute_size_of_parameters().
    return -2;
  }

  unsigned int args_size = 0;
  const char* p = (const char*)signature->bytes();
  unsigned int length = signature->utf8_length();
  const char* nextp;

  // The first character must be a '('
  if ((length > 0) && (*p++ == JVM_SIGNATURE_FUNC)) {
    length--;
    // Skip over legal field signatures
    nextp = skip_over_field_signature(p, false, length, CHECK_0);
    while ((length > 0) && (nextp != nullptr)) {
      args_size++;
      if (p[0] == 'J' || p[0] == 'D') {
        args_size++;
      }
      length -= pointer_delta_as_int(nextp, p);
      p = nextp;
      nextp = skip_over_field_signature(p, false, length, CHECK_0);
    }
    // The first non-signature thing better be a ')'
    if ((length > 0) && (*p++ == JVM_SIGNATURE_ENDFUNC)) {
      length--;
      // Now we better just have a return value
      nextp = skip_over_field_signature(p, true, length, CHECK_0);
      if (nextp && ((int)length == (nextp - p))) {
        return args_size;
      }
    }
  }
  // Report error
  throwIllegalSignature("Method", name, signature, THREAD);
  return 0;
}

int ClassFileParser::static_field_size() const {
  assert(_field_info != nullptr, "invariant");
  return _field_info->_static_field_size;
}

int ClassFileParser::total_oop_map_count() const {
  assert(_field_info != nullptr, "invariant");
  return _field_info->oop_map_blocks->_nonstatic_oop_map_count;
}

jint ClassFileParser::layout_size() const {
  assert(_field_info != nullptr, "invariant");
  return _field_info->_instance_size;
}

static void check_methods_for_intrinsics(const InstanceKlass* ik,
                                         const Array<Method*>* methods) {
  assert(ik != nullptr, "invariant");
  assert(methods != nullptr, "invariant");

  // 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.)
  const vmSymbolID klass_id = Method::klass_id_for_intrinsics(ik);

  if (klass_id != vmSymbolID::NO_SID) {
    for (int j = 0; j < methods->length(); ++j) {
      Method* method = methods->at(j);
      method->init_intrinsic_id(klass_id);

      if (CheckIntrinsics) {
        // Check if an intrinsic is defined for method 'method',
        // but the method is not annotated with @IntrinsicCandidate.
        if (method->intrinsic_id() != vmIntrinsics::_none &&
            !method->intrinsic_candidate()) {
              tty->print("Compiler intrinsic is defined for method [%s], "
              "but the method is not annotated with @IntrinsicCandidate.%s",
              method->name_and_sig_as_C_string(),
              NOT_DEBUG(" Method will not be inlined.") DEBUG_ONLY(" Exiting.")
            );
          tty->cr();
          DEBUG_ONLY(vm_exit(1));
        }
        // Check is the method 'method' is annotated with @IntrinsicCandidate,
        // but there is no intrinsic available for it.
        if (method->intrinsic_candidate() &&
          method->intrinsic_id() == vmIntrinsics::_none) {
            tty->print("Method [%s] is annotated with @IntrinsicCandidate, "
              "but no compiler intrinsic is defined for the method.%s",
              method->name_and_sig_as_C_string(),
              NOT_DEBUG("") DEBUG_ONLY(" Exiting.")
            );
          tty->cr();
          DEBUG_ONLY(vm_exit(1));
        }
      }
    } // end for

#ifdef ASSERT
    if (CheckIntrinsics) {
      // Check for orphan methods in the current class. A method m
      // of a class C is orphan if an intrinsic is defined for method m,
      // but class C does not declare m.
      // The check is potentially expensive, therefore it is available
      // only in debug builds.

      for (auto id : EnumRange<vmIntrinsicID>{}) {
        if (vmIntrinsics::_compiledLambdaForm == id) {
          // The _compiledLamdbdaForm intrinsic is a special marker for bytecode
          // generated for the JVM from a LambdaForm and therefore no method
          // is defined for it.
          continue;
        }
        if (vmIntrinsics::_blackhole == id) {
          // The _blackhole intrinsic is a special marker. No explicit method
          // is defined for it.
          continue;
        }

        if (vmIntrinsics::class_for(id) == klass_id) {
          // Check if the current class contains a method with the same
          // name, flags, signature.
          bool match = false;
          for (int j = 0; j < methods->length(); ++j) {
            const Method* method = methods->at(j);
            if (method->intrinsic_id() == id) {
              match = true;
              break;
            }
          }

          if (!match) {
            char buf[1000];
            tty->print("Compiler intrinsic is defined for method [%s], "
                       "but the method is not available in class [%s].%s",
                        vmIntrinsics::short_name_as_C_string(id, buf, sizeof(buf)),
                        ik->name()->as_C_string(),
                        NOT_DEBUG("") DEBUG_ONLY(" Exiting.")
            );
            tty->cr();
            DEBUG_ONLY(vm_exit(1));
          }
        }
      } // end for
    } // CheckIntrinsics
#endif // ASSERT
  }
}

InstanceKlass* ClassFileParser::create_instance_klass(bool changed_by_loadhook,
                                                      const ClassInstanceInfo& cl_inst_info,
                                                      TRAPS) {
  if (_klass != nullptr) {
    return _klass;
  }

  InstanceKlass* const ik =
    InstanceKlass::allocate_instance_klass(*this, CHECK_NULL);

  if (is_hidden()) {
    mangle_hidden_class_name(ik);
  }

  fill_instance_klass(ik, changed_by_loadhook, cl_inst_info, CHECK_NULL);

  assert(_klass == ik, "invariant");

  return ik;
}

void ClassFileParser::fill_instance_klass(InstanceKlass* ik,
                                          bool changed_by_loadhook,
                                          const ClassInstanceInfo& cl_inst_info,
                                          TRAPS) {
  assert(ik != nullptr, "invariant");

  // Set name and CLD before adding to CLD
  ik->set_class_loader_data(_loader_data);
  ik->set_class_loader_type();
  ik->set_name(_class_name);

  // Add all classes to our internal class loader list here,
  // including classes in the bootstrap (null) class loader.
  const bool publicize = !is_internal();

  _loader_data->add_class(ik, publicize);

  set_klass_to_deallocate(ik);

  assert(_field_info != nullptr, "invariant");
  assert(ik->static_field_size() == _field_info->_static_field_size, "sanity");
  assert(ik->nonstatic_oop_map_count() == _field_info->oop_map_blocks->_nonstatic_oop_map_count,
         "sanity");

  assert(ik->is_instance_klass(), "sanity");
  assert(ik->size_helper() == _field_info->_instance_size, "sanity");

  // Fill in information already parsed
  ik->set_should_verify_class(_need_verify);

  // Not yet: supers are done below to support the new subtype-checking fields
  ik->set_nonstatic_field_size(_field_info->_nonstatic_field_size);
  ik->set_has_nonstatic_fields(_field_info->_has_nonstatic_fields);
  ik->set_static_oop_field_count(_static_oop_count);

  // this transfers ownership of a lot of arrays from
  // the parser onto the InstanceKlass*
  apply_parsed_class_metadata(ik, _java_fields_count);

  // can only set dynamic nest-host after static nest information is set
  if (cl_inst_info.dynamic_nest_host() != nullptr) {
    ik->set_nest_host(cl_inst_info.dynamic_nest_host());
  }

  // note that is not safe to use the fields in the parser from this point on
  assert(nullptr == _cp, "invariant");
  assert(nullptr == _fieldinfo_stream, "invariant");
  assert(nullptr == _fieldinfo_search_table, "invariant");
  assert(nullptr == _fields_status, "invariant");
  assert(nullptr == _methods, "invariant");
  assert(nullptr == _inner_classes, "invariant");
  assert(nullptr == _nest_members, "invariant");
  assert(nullptr == _combined_annotations, "invariant");
  assert(nullptr == _record_components, "invariant");
  assert(nullptr == _permitted_subclasses, "invariant");

  if (_has_localvariable_table) {
    ik->set_has_localvariable_table(true);
  }

  if (_has_final_method) {
    ik->set_has_final_method();
  }

  ik->copy_method_ordering(_method_ordering, CHECK);
  // 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.
  ik->set_initial_method_idnum(checked_cast<u2>(ik->methods()->length()));

  ik->set_this_class_index(_this_class_index);

  if (_is_hidden) {
    // _this_class_index is a CONSTANT_Class entry that refers to this
    // hidden class itself. If this class needs to refer to its own methods
    // or fields, it would use a CONSTANT_MethodRef, etc, which would reference
    // _this_class_index. However, because this class is hidden (it's
    // not stored in SystemDictionary), _this_class_index cannot be resolved
    // with ConstantPool::klass_at_impl, which does a SystemDictionary lookup.
    // Therefore, we must eagerly resolve _this_class_index now.
    ik->constants()->klass_at_put(_this_class_index, ik);
  }

  ik->set_minor_version(_minor_version);
  ik->set_major_version(_major_version);
  ik->set_has_nonstatic_concrete_methods(_has_nonstatic_concrete_methods);
  ik->set_declares_nonstatic_concrete_methods(_declares_nonstatic_concrete_methods);

  assert(!_is_hidden || ik->is_hidden(), "must be set already");

  // Set PackageEntry for this_klass
  oop cl = ik->class_loader();
  Handle clh = Handle(THREAD, cl);
  ClassLoaderData* cld = ClassLoaderData::class_loader_data_or_null(clh());
  ik->set_package(cld, nullptr, CHECK);

  const Array<Method*>* const methods = ik->methods();
  assert(methods != nullptr, "invariant");
  const int methods_len = methods->length();

  check_methods_for_intrinsics(ik, methods);

  // Fill in field values obtained by parse_classfile_attributes
  if (_parsed_annotations->has_any_annotations()) {
    _parsed_annotations->apply_to(ik);
  }

  apply_parsed_class_attributes(ik);

  // Miranda methods
  if ((_num_miranda_methods > 0) ||
      // if this class introduced new miranda methods or
      (_super_klass != nullptr && _super_klass->has_miranda_methods())
        // super class exists and this class inherited miranda methods
     ) {
       ik->set_has_miranda_methods(); // then set a flag
  }

  // Fill in information needed to compute superclasses.
  ik->initialize_supers(const_cast<InstanceKlass*>(_super_klass), _transitive_interfaces, CHECK);
  ik->set_transitive_interfaces(_transitive_interfaces);
  ik->set_local_interfaces(_local_interfaces);
  _transitive_interfaces = nullptr;
  _local_interfaces = nullptr;

  // Initialize itable offset tables
  klassItable::setup_itable_offset_table(ik);

  // Compute transitive closure of interfaces this class implements
  // Do final class setup
  OopMapBlocksBuilder* oop_map_blocks = _field_info->oop_map_blocks;
  if (oop_map_blocks->_nonstatic_oop_map_count > 0) {
    oop_map_blocks->copy(ik->start_of_nonstatic_oop_maps());
  }

  if (_has_contended_fields || _parsed_annotations->is_contended() ||
      ( _super_klass != nullptr && _super_klass->has_contended_annotations())) {
    ik->set_has_contended_annotations(true);
  }

  // Fill in has_finalizer and layout_helper
  set_precomputed_flags(ik);

  // check if this class can access its super class
  check_super_class_access(ik, CHECK);

  // check if this class can access its superinterfaces
  check_super_interface_access(ik, CHECK);

  // check if this class overrides any final method
  check_final_method_override(ik, CHECK);

  // reject static interface methods prior to Java 8
  if (ik->is_interface() && _major_version < JAVA_8_VERSION) {
    check_illegal_static_method(ik, CHECK);
  }

  // Obtain this_klass' module entry
  ModuleEntry* module_entry = ik->module();
  assert(module_entry != nullptr, "module_entry should always be set");

  // Obtain java.lang.Module
  Handle module_handle(THREAD, module_entry->module());

  // Allocate mirror and initialize static fields
  java_lang_Class::create_mirror(ik,
                                 Handle(THREAD, _loader_data->class_loader()),
                                 module_handle,
                                 _protection_domain,
                                 cl_inst_info.class_data(),
                                 CHECK);

  assert(_all_mirandas != nullptr, "invariant");

  // Generate any default methods - default methods are public interface methods
  // that have a default implementation.  This is new with Java 8.
  if (_has_nonstatic_concrete_methods) {
    DefaultMethods::generate_default_methods(ik,
                                             _all_mirandas,
                                             CHECK);
  }

  // Add read edges to the unnamed modules of the bootstrap and app class loaders.
  if (changed_by_loadhook && !module_handle.is_null() && module_entry->is_named() &&
      !module_entry->has_default_read_edges()) {
    if (!module_entry->set_has_default_read_edges()) {
      // We won a potential race
      JvmtiExport::add_default_read_edges(module_handle, THREAD);
    }
  }

  ClassLoadingService::notify_class_loaded(ik, false /* not shared class */);

  if (!is_internal()) {
    ik->print_class_load_logging(_loader_data, module_entry, _stream);

    if (ik->minor_version() == JAVA_PREVIEW_MINOR_VERSION &&
        ik->major_version() == JVM_CLASSFILE_MAJOR_VERSION &&
        log_is_enabled(Info, class, preview)) {
      ResourceMark rm;
      log_info(class, preview)("Loading class %s that depends on preview features (class file version %d.65535)",
                               ik->external_name(), JVM_CLASSFILE_MAJOR_VERSION);
    }

    if (log_is_enabled(Debug, class, resolve))  {
      ResourceMark rm;
      // print out the superclass.
      const char * from = ik->external_name();
      if (ik->java_super() != nullptr) {
        log_debug(class, resolve)("%s %s (super)",
                   from,
                   ik->java_super()->external_name());
      }
      // print out each of the interface classes referred to by this class.
      const Array<InstanceKlass*>* const local_interfaces = ik->local_interfaces();
      if (local_interfaces != nullptr) {
        const int length = local_interfaces->length();
        for (int i = 0; i < length; i++) {
          const InstanceKlass* const k = local_interfaces->at(i);
          const char * to = k->external_name();
          log_debug(class, resolve)("%s %s (interface)", from, to);
        }
      }
    }
  }

  JFR_ONLY(INIT_ID(ik);)

  // If we reach here, all is well.
  // Now remove the InstanceKlass* from the _klass_to_deallocate field
  // in order for it to not be destroyed in the ClassFileParser destructor.
  set_klass_to_deallocate(nullptr);

  // it's official
  set_klass(ik);

  DEBUG_ONLY(ik->verify();)
}

void ClassFileParser::update_class_name(Symbol* new_class_name) {
  // Decrement the refcount in the old name, since we're clobbering it.
  _class_name->decrement_refcount();

  _class_name = new_class_name;
  // Increment the refcount of the new name.
  // Now the ClassFileParser owns this name and will decrement in
  // the destructor.
  _class_name->increment_refcount();
}

ClassFileParser::ClassFileParser(ClassFileStream* stream,
                                 Symbol* name,
                                 ClassLoaderData* loader_data,
                                 const ClassLoadInfo* cl_info,
                                 Publicity pub_level,
                                 TRAPS) :
  _stream(stream),
  _class_name(nullptr),
  _loader_data(loader_data),
  _is_hidden(cl_info->is_hidden()),
  _can_access_vm_annotations(cl_info->can_access_vm_annotations()),
  _orig_cp_size(0),
  _static_oop_count(0),
  _super_klass(),
  _cp(nullptr),
  _fieldinfo_stream(nullptr),
  _fieldinfo_search_table(nullptr),
  _fields_status(nullptr),
  _methods(nullptr),
  _inner_classes(nullptr),
  _nest_members(nullptr),
  _nest_host(0),
  _permitted_subclasses(nullptr),
  _record_components(nullptr),
  _local_interfaces(nullptr),
  _transitive_interfaces(nullptr),
  _combined_annotations(nullptr),
  _class_annotations(nullptr),
  _class_type_annotations(nullptr),
  _fields_annotations(nullptr),
  _fields_type_annotations(nullptr),
  _klass(nullptr),
  _klass_to_deallocate(nullptr),
  _parsed_annotations(nullptr),
  _field_info(nullptr),
  _temp_field_info(nullptr),
  _method_ordering(nullptr),
  _all_mirandas(nullptr),
  _vtable_size(0),
  _itable_size(0),
  _num_miranda_methods(0),
  _protection_domain(cl_info->protection_domain()),
  _access_flags(),
  _pub_level(pub_level),
  _bad_constant_seen(0),
  _synthetic_flag(false),
  _sde_length(false),
  _sde_buffer(nullptr),
  _sourcefile_index(0),
  _generic_signature_index(0),
  _major_version(0),
  _minor_version(0),
  _this_class_index(0),
  _super_class_index(0),
  _itfs_len(0),
  _java_fields_count(0),
  _need_verify(false),
  _has_nonstatic_concrete_methods(false),
  _declares_nonstatic_concrete_methods(false),
  _has_localvariable_table(false),
  _has_final_method(false),
  _has_contended_fields(false),
  _has_finalizer(false),
  _has_empty_finalizer(false),
  _max_bootstrap_specifier_index(-1) {

  _class_name = name != nullptr ? name : vmSymbols::unknown_class_name();
  _class_name->increment_refcount();

  assert(_loader_data != nullptr, "invariant");
  assert(stream != nullptr, "invariant");
  assert(_stream != nullptr, "invariant");
  assert(_stream->buffer() == _stream->current(), "invariant");
  assert(_class_name != nullptr, "invariant");
  assert(0 == _access_flags.as_unsigned_short(), "invariant");

  // Figure out whether we can skip format checking (matching classic VM behavior)
  // Always verify CFLH bytes from the user agents.
  _need_verify = stream->from_class_file_load_hook() ? true : Verifier::should_verify_for(_loader_data->class_loader());

  // synch back verification state to stream to check for truncation.
  stream->set_need_verify(_need_verify);

  parse_stream(stream, CHECK);

  post_process_parsed_stream(stream, _cp, CHECK);
}

void ClassFileParser::clear_class_metadata() {
  // metadata created before the instance klass is created.  Must be
  // deallocated if classfile parsing returns an error.
  _cp = nullptr;
  _fieldinfo_stream = nullptr;
  _fieldinfo_search_table = nullptr;
  _fields_status = nullptr;
  _methods = nullptr;
  _inner_classes = nullptr;
  _nest_members = nullptr;
  _permitted_subclasses = nullptr;
  _combined_annotations = nullptr;
  _class_annotations = _class_type_annotations = nullptr;
  _fields_annotations = _fields_type_annotations = nullptr;
  _record_components = nullptr;
}

// Destructor to clean up
ClassFileParser::~ClassFileParser() {
  _class_name->decrement_refcount();

  if (_cp != nullptr) {
    MetadataFactory::free_metadata(_loader_data, _cp);
  }

  if (_fieldinfo_stream != nullptr) {
    MetadataFactory::free_array<u1>(_loader_data, _fieldinfo_stream);
  }
  MetadataFactory::free_array<u1>(_loader_data, _fieldinfo_search_table);

  if (_fields_status != nullptr) {
    MetadataFactory::free_array<FieldStatus>(_loader_data, _fields_status);
  }

  if (_methods != nullptr) {
    // Free methods
    InstanceKlass::deallocate_methods(_loader_data, _methods);
  }

  // beware of the Universe::empty_blah_array!!
  if (_inner_classes != nullptr && _inner_classes != Universe::the_empty_short_array()) {
    MetadataFactory::free_array<u2>(_loader_data, _inner_classes);
  }

  if (_nest_members != nullptr && _nest_members != Universe::the_empty_short_array()) {
    MetadataFactory::free_array<u2>(_loader_data, _nest_members);
  }

  if (_record_components != nullptr) {
    InstanceKlass::deallocate_record_components(_loader_data, _record_components);
  }

  if (_permitted_subclasses != nullptr && _permitted_subclasses != Universe::the_empty_short_array()) {
    MetadataFactory::free_array<u2>(_loader_data, _permitted_subclasses);
  }

  // Free interfaces
  InstanceKlass::deallocate_interfaces(_loader_data, _super_klass,
                                       _local_interfaces, _transitive_interfaces);

  if (_combined_annotations != nullptr) {
    // After all annotations arrays have been created, they are installed into the
    // Annotations object that will be assigned to the InstanceKlass being created.

    // Deallocate the Annotations object and the installed annotations arrays.
    _combined_annotations->deallocate_contents(_loader_data);

    // If the _combined_annotations pointer is non-null,
    // then the other annotations fields should have been cleared.
    assert(_class_annotations       == nullptr, "Should have been cleared");
    assert(_class_type_annotations  == nullptr, "Should have been cleared");
    assert(_fields_annotations      == nullptr, "Should have been cleared");
    assert(_fields_type_annotations == nullptr, "Should have been cleared");
  } else {
    // If the annotations arrays were not installed into the Annotations object,
    // then they have to be deallocated explicitly.
    MetadataFactory::free_array<u1>(_loader_data, _class_annotations);
    MetadataFactory::free_array<u1>(_loader_data, _class_type_annotations);
    Annotations::free_contents(_loader_data, _fields_annotations);
    Annotations::free_contents(_loader_data, _fields_type_annotations);
  }

  clear_class_metadata();
  _transitive_interfaces = nullptr;
  _local_interfaces = nullptr;

  // deallocate the klass if already created.  Don't directly deallocate, but add
  // to the deallocate list so that the klass is removed from the CLD::_klasses list
  // at a safepoint.
  if (_klass_to_deallocate != nullptr) {
    _loader_data->add_to_deallocate_list(_klass_to_deallocate);
  }
}

void ClassFileParser::parse_stream(const ClassFileStream* const stream,
                                   TRAPS) {

  assert(stream != nullptr, "invariant");
  assert(_class_name != nullptr, "invariant");

  // BEGIN STREAM PARSING
  stream->guarantee_more(8, CHECK);  // magic, major, minor
  // Magic value
  const u4 magic = stream->get_u4_fast();
  guarantee_property(magic == JAVA_CLASSFILE_MAGIC,
                     "Incompatible magic value %u in class file %s",
                     magic, CHECK);

  // Version numbers
  _minor_version = stream->get_u2_fast();
  _major_version = stream->get_u2_fast();

  // Check version numbers - we check this even with verifier off
  verify_class_version(_major_version, _minor_version, _class_name, CHECK);

  stream->guarantee_more(3, CHECK); // length, first cp tag
  u2 cp_size = stream->get_u2_fast();

  guarantee_property(
    cp_size >= 1, "Illegal constant pool size %u in class file %s",
    cp_size, CHECK);

  _orig_cp_size = cp_size;
  if (is_hidden()) { // Add a slot for hidden class name.
    cp_size++;
  }

  _cp = ConstantPool::allocate(_loader_data,
                               cp_size,
                               CHECK);

  ConstantPool* const cp = _cp;

  parse_constant_pool(stream, cp, _orig_cp_size, CHECK);

  assert(cp_size == (u2)cp->length(), "invariant");

  // ACCESS FLAGS
  stream->guarantee_more(8, CHECK);  // flags, this_class, super_class, infs_len

  // Access flags
  u2 flags;
  // JVM_ACC_MODULE is defined in JDK-9 and later.
  if (_major_version >= JAVA_9_VERSION) {
    flags = stream->get_u2_fast() & (JVM_RECOGNIZED_CLASS_MODIFIERS | JVM_ACC_MODULE);
  } else {
    flags = stream->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);

  short bad_constant = class_bad_constant_seen();
  if (bad_constant != 0) {
    // Do not throw CFE until after the access_flags are checked because if
    // ACC_MODULE is set in the access flags, then NCDFE must be thrown, not CFE.
    classfile_parse_error("Unknown constant tag %u in class file %s", bad_constant, THREAD);
    return;
  }

  _access_flags.set_flags(flags);

  // This class and superclass
  _this_class_index = stream->get_u2_fast();
  guarantee_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);

  Symbol* const class_name_in_cp = cp->klass_name_at(_this_class_index);
  assert(class_name_in_cp != nullptr, "class_name can't be null");

  // 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_in_cp->char_at(0) != JVM_SIGNATURE_ARRAY,
                       "Bad class name in class file %s",
                       CHECK);
  }

#ifdef ASSERT
  // Basic sanity checks
  if (_is_hidden) {
    assert(_class_name != vmSymbols::unknown_class_name(), "hidden classes should have a special name");
  }
#endif

  // Update the _class_name as needed depending on whether this is a named, un-named, or hidden class.

  if (_is_hidden) {
    assert(_class_name != nullptr, "Unexpected null _class_name");
#ifdef ASSERT
    if (_need_verify) {
      verify_legal_class_name(_class_name, CHECK);
    }
#endif

  } else {
    // Check if name in class file matches given name
    if (_class_name != class_name_in_cp) {
      if (_class_name != vmSymbols::unknown_class_name()) {
        ResourceMark rm(THREAD);
        // Names are all known to be < 64k so we know this formatted message is not excessively large.
        Exceptions::fthrow(THREAD_AND_LOCATION,
                           vmSymbols::java_lang_NoClassDefFoundError(),
                           "%s (wrong name: %s)",
                           _class_name->as_C_string(),
                           class_name_in_cp->as_C_string()
                           );
        return;
      } else {
        // The class name was not known by the caller so we set it from
        // the value in the CP.
        update_class_name(class_name_in_cp);
      }
      // else nothing to do: the expected class name matches what is in the CP
    }
  }

  // Verification prevents us from creating names with dots in them, this
  // asserts that that's the case.
  assert(is_internal_format(_class_name), "external class name format used internally");

  if (!is_internal()) {
    LogTarget(Debug, class, preorder) lt;
    if (lt.is_enabled()){
      ResourceMark rm(THREAD);
      LogStream ls(lt);
      ls.print("%s", _class_name->as_klass_external_name());
      if (stream->source() != nullptr) {
        ls.print(" source: %s", stream->source());
      }
      ls.cr();
    }
  }

  // SUPERKLASS
  _super_class_index = stream->get_u2_fast();
  _super_klass = parse_super_class(cp,
                                   _super_class_index,
                                   _need_verify,
                                   CHECK);

  // Interfaces
  _itfs_len = stream->get_u2_fast();
  parse_interfaces(stream,
                   _itfs_len,
                   cp,
                   &_has_nonstatic_concrete_methods,
                   CHECK);

  assert(_local_interfaces != nullptr, "invariant");

  // Fields (offsets are filled in later)
  parse_fields(stream,
               _access_flags.is_interface(),
               cp,
               cp_size,
               &_java_fields_count,
               CHECK);

  assert(_temp_field_info != nullptr, "invariant");

  // Methods
  parse_methods(stream,
                _access_flags.is_interface(),
                &_has_localvariable_table,
                &_has_final_method,
                &_declares_nonstatic_concrete_methods,
                CHECK);

  assert(_methods != nullptr, "invariant");

  if (_declares_nonstatic_concrete_methods) {
    _has_nonstatic_concrete_methods = true;
  }

  // Additional attributes/annotations
  _parsed_annotations = new ClassAnnotationCollector();
  parse_classfile_attributes(stream, cp, _parsed_annotations, CHECK);

  assert(_inner_classes != nullptr, "invariant");

  // Finalize the Annotations metadata object,
  // now that all annotation arrays have been created.
  create_combined_annotations(CHECK);

  // Make sure this is the end of class file stream
  guarantee_property(stream->at_eos(),
                     "Extra bytes at the end of class file %s",
                     CHECK);

  // all bytes in stream read and parsed
}

void ClassFileParser::mangle_hidden_class_name(InstanceKlass* const ik) {
  ResourceMark rm;
  // Construct hidden name from _class_name, "+", and &ik. Note that we can't
  // use a '/' because that confuses finding the class's package.  Also, can't
  // use an illegal char such as ';' because that causes serialization issues
  // and issues with hidden classes that create their own hidden classes.
  char addr_buf[20];
  if (CDSConfig::is_dumping_static_archive()) {
    // We want stable names for the archived hidden classes (only for static
    // archive for now). Spaces under default_SharedBaseAddress() will be
    // occupied by the archive at run time, so we know that no dynamically
    // loaded InstanceKlass will be placed under there.
    static volatile size_t counter = 0;
    Atomic::cmpxchg(&counter, (size_t)0, Arguments::default_SharedBaseAddress()); // initialize it
    size_t new_id = Atomic::add(&counter, (size_t)1);
    jio_snprintf(addr_buf, 20, "0x%zx", new_id);
  } else {
    jio_snprintf(addr_buf, 20, INTPTR_FORMAT, p2i(ik));
  }
  size_t new_name_len = _class_name->utf8_length() + 2 + strlen(addr_buf);
  char* new_name = NEW_RESOURCE_ARRAY(char, new_name_len);
  jio_snprintf(new_name, new_name_len, "%s+%s",
               _class_name->as_C_string(), addr_buf);
  update_class_name(SymbolTable::new_symbol(new_name));

  // Add a Utf8 entry containing the hidden name.
  assert(_class_name != nullptr, "Unexpected null _class_name");
  int hidden_index = _orig_cp_size; // this is an extra slot we added
  _cp->symbol_at_put(hidden_index, _class_name);

  // Update this_class_index's slot in the constant pool with the new Utf8 entry.
  // We have to update the resolved_klass_index and the name_index together
  // so extract the existing resolved_klass_index first.
  CPKlassSlot cp_klass_slot = _cp->klass_slot_at(_this_class_index);
  int resolved_klass_index = cp_klass_slot.resolved_klass_index();
  _cp->unresolved_klass_at_put(_this_class_index, hidden_index, resolved_klass_index);
  assert(_cp->klass_slot_at(_this_class_index).name_index() == _orig_cp_size,
         "Bad name_index");
}

void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const stream,
                                                 ConstantPool* cp,
                                                 TRAPS) {
  assert(stream != nullptr, "invariant");
  assert(stream->at_eos(), "invariant");
  assert(cp != nullptr, "invariant");
  assert(_loader_data != nullptr, "invariant");

  if (_class_name == vmSymbols::java_lang_Object()) {
    guarantee_property(_local_interfaces == Universe::the_empty_instance_klass_array(),
                       "java.lang.Object cannot implement an interface in class file %s",
                       CHECK);
  }
  // We check super class after class file is parsed and format is checked
  if (_super_class_index > 0 && nullptr == _super_klass) {
    Symbol* const super_class_name = 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(super_class_name == vmSymbols::java_lang_Object(),
        "Interfaces must have java.lang.Object as superclass in class file %s",
        CHECK);
    }
    Handle loader(THREAD, _loader_data->class_loader());
    if (loader.is_null() && super_class_name == vmSymbols::java_lang_Object()) {
      _super_klass = vmClasses::Object_klass();
    } else {
      _super_klass = (const InstanceKlass*)
                       SystemDictionary::resolve_super_or_fail(_class_name,
                                                               super_class_name,
                                                               loader,
                                                               true,
                                                               CHECK);
    }
  }

  if (_super_klass != nullptr) {
    if (_super_klass->has_nonstatic_concrete_methods()) {
      _has_nonstatic_concrete_methods = true;
    }

    if (_super_klass->is_interface()) {
      classfile_icce_error("class %s has interface %s as super class", _super_klass, THREAD);
      return;
    }
  }

  // Compute the transitive list of all unique interfaces implemented by this class
  _transitive_interfaces =
    compute_transitive_interfaces(_super_klass,
                                  _local_interfaces,
                                  _loader_data,
                                  CHECK);

  assert(_transitive_interfaces != nullptr, "invariant");

  // sort methods
  _method_ordering = sort_methods(_methods);

  _all_mirandas = new GrowableArray<Method*>(20);

  Handle loader(THREAD, _loader_data->class_loader());
  klassVtable::compute_vtable_size_and_num_mirandas(&_vtable_size,
                                                    &_num_miranda_methods,
                                                    _all_mirandas,
                                                    _super_klass,
                                                    _methods,
                                                    _access_flags,
                                                    _major_version,
                                                    loader,
                                                    _class_name,
                                                    _local_interfaces);

  // Size of Java itable (in words)
  _itable_size = _access_flags.is_interface() ? 0 :
    klassItable::compute_itable_size(_transitive_interfaces);

  assert(_parsed_annotations != nullptr, "invariant");

  _field_info = new FieldLayoutInfo();
  FieldLayoutBuilder lb(class_name(), super_klass(), _cp, /*_fields*/ _temp_field_info,
                        _parsed_annotations->is_contended(), _field_info);
  lb.build_layout();

  int injected_fields_count = _temp_field_info->length() - _java_fields_count;
  _fieldinfo_stream =
    FieldInfoStream::create_FieldInfoStream(_temp_field_info, _java_fields_count,
                                            injected_fields_count, loader_data(), CHECK);
  _fieldinfo_search_table = FieldInfoStream::create_search_table(_cp, _fieldinfo_stream, _loader_data, CHECK);
  _fields_status =
    MetadataFactory::new_array<FieldStatus>(_loader_data, _temp_field_info->length(),
                                            FieldStatus(0), CHECK);
}

void ClassFileParser::set_klass(InstanceKlass* klass) {

#ifdef ASSERT
  if (klass != nullptr) {
    assert(nullptr == _klass, "leaking?");
  }
#endif

  _klass = klass;
}

void ClassFileParser::set_klass_to_deallocate(InstanceKlass* klass) {

#ifdef ASSERT
  if (klass != nullptr) {
    assert(nullptr == _klass_to_deallocate, "leaking?");
  }
#endif

  _klass_to_deallocate = klass;
}

// Caller responsible for ResourceMark
// clone stream with rewound position
const ClassFileStream* ClassFileParser::clone_stream() const {
  assert(_stream != nullptr, "invariant");

  return _stream->clone();
}

ReferenceType ClassFileParser::super_reference_type() const {
  return _super_klass == nullptr ? REF_NONE : _super_klass->reference_type();
}

bool ClassFileParser::is_instance_ref_klass() const {
  // Only the subclasses of j.l.r.Reference are InstanceRefKlass.
  // j.l.r.Reference itself is InstanceKlass because InstanceRefKlass denotes a
  // klass requiring special treatment in ref-processing. The abstract
  // j.l.r.Reference cannot be instantiated so doesn't partake in
  // ref-processing.
  return is_java_lang_ref_Reference_subclass();
}

bool ClassFileParser::is_java_lang_ref_Reference_subclass() const {
  if (_super_klass == nullptr) {
    return false;
  }

  if (_super_klass->name() == vmSymbols::java_lang_ref_Reference()) {
    // Direct subclass of j.l.r.Reference: Soft|Weak|Final|Phantom
    return true;
  }

  return _super_klass->reference_type() != REF_NONE;
}

// ----------------------------------------------------------------------------
// debugging

#ifdef ASSERT

// return true if class_name contains no '.' (internal format is '/')
bool ClassFileParser::is_internal_format(Symbol* class_name) {
  if (class_name != nullptr) {
    ResourceMark rm;
    char* name = class_name->as_C_string();
    return strchr(name, JVM_SIGNATURE_DOT) == nullptr;
  } else {
    return true;
  }
}

#endif
