/*
 * Copyright (c) 1997, 2011, 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 "precompiled.hpp"
#include "classfile/classFileParser.hpp"
#include "classfile/classLoader.hpp"
#include "classfile/javaClasses.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/systemDictionary.hpp"
#include "classfile/verificationType.hpp"
#include "classfile/verifier.hpp"
#include "classfile/vmSymbols.hpp"
#include "memory/allocation.hpp"
#include "memory/gcLocker.hpp"
#include "memory/oopFactory.hpp"
#include "memory/universe.inline.hpp"
#include "oops/constantPoolOop.hpp"
#include "oops/fieldStreams.hpp"
#include "oops/instanceKlass.hpp"
#include "oops/instanceMirrorKlass.hpp"
#include "oops/klass.inline.hpp"
#include "oops/klassOop.hpp"
#include "oops/klassVtable.hpp"
#include "oops/methodOop.hpp"
#include "oops/symbol.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/jvmtiThreadState.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/perfData.hpp"
#include "runtime/reflection.hpp"
#include "runtime/signature.hpp"
#include "runtime/timer.hpp"
#include "services/classLoadingService.hpp"
#include "services/threadService.hpp"

// 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_MAX_SUPPORTED_VERSION        51
#define JAVA_MAX_SUPPORTED_MINOR_VERSION  0

// 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 check NameAndType_info signatures more aggressively
#define JAVA_7_VERSION                    51


void ClassFileParser::parse_constant_pool_entries(constantPoolHandle cp, int length, TRAPS) {
  // 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().
  ClassFileStream* cfs0 = stream();
  ClassFileStream cfs1 = *cfs0;
  ClassFileStream* cfs = &cfs1;
#ifdef ASSERT
  assert(cfs->allocated_on_stack(),"should be local");
  u1* old_current = cfs0->current();
#endif

  // 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.
    u1 tag = cfs->get_u1_fast();
    switch (tag) {
      case JVM_CONSTANT_Class :
        {
          cfs->guarantee_more(3, CHECK);  // name_index, tag/access_flags
          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
          u2 class_index = cfs->get_u2_fast();
          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
          u2 class_index = cfs->get_u2_fast();
          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
          u2 class_index = cfs->get_u2_fast();
          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
          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, CHECK);
        }
        if (!EnableInvokeDynamic) {
          classfile_parse_error(
            "This JVM does not support constant tag %u in class file %s",
            tag, CHECK);
        }
        if (tag == JVM_CONSTANT_MethodHandle) {
          cfs->guarantee_more(4, CHECK);  // ref_kind, method_index, tag/access_flags
          u1 ref_kind = cfs->get_u1_fast();
          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
          u2 signature_index = cfs->get_u2_fast();
          cp->method_type_index_at_put(index, signature_index);
        } else {
          ShouldNotReachHere();
        }
        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, CHECK);
          }
          if (!EnableInvokeDynamic) {
            classfile_parse_error(
              "This JVM does not support constant tag %u in class file %s",
              tag, CHECK);
          }
          cfs->guarantee_more(5, CHECK);  // bsm_index, nt, tag/access_flags
          u2 bootstrap_specifier_index = cfs->get_u2_fast();
          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
          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
          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
          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
          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
          u2 name_index = cfs->get_u2_fast();
          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();
          u1* utf8_buffer = cfs->get_u1_buffer();
          assert(utf8_buffer != NULL, "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((unsigned char*)utf8_buffer, utf8_length, CHECK);
          }

          if (EnableInvokeDynamic && has_cp_patch_at(index)) {
            Handle patch = clear_cp_patch_at(index);
            guarantee_property(java_lang_String::is_instance(patch()),
                               "Illegal utf8 patch at %d in class file %s",
                               index, CHECK);
            char* str = java_lang_String::as_utf8_string(patch());
            // (could use java_lang_String::as_symbol instead, but might as well batch them)
            utf8_buffer = (u1*) str;
            utf8_length = (int) strlen(str);
          }

          unsigned int hash;
          Symbol* result = SymbolTable::lookup_only((char*)utf8_buffer, utf8_length, hash);
          if (result == NULL) {
            names[names_count] = (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(cp, names_count, names, lengths, indices, hashValues, CHECK);
              names_count = 0;
            }
          } else {
            cp->symbol_at_put(index, result);
          }
        }
        break;
      default:
        classfile_parse_error(
          "Unknown constant tag %u in class file %s", tag, CHECK);
        break;
    }
  }

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

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

// This class unreferences constant pool symbols if an error has occurred
// while parsing the class before it is assigned into the class.
// If it gets an error after that it is unloaded and the constant pool will
// be cleaned up then.
class ConstantPoolCleaner : public StackObj {
  constantPoolHandle _cphandle;
  bool               _in_error;
 public:
  ConstantPoolCleaner(constantPoolHandle cp) : _cphandle(cp), _in_error(true) {}
  ~ConstantPoolCleaner() {
    if (_in_error && _cphandle.not_null()) {
      _cphandle->unreference_symbols();
    }
  }
  void set_in_error(bool clean) { _in_error = clean; }
};

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

constantPoolHandle ClassFileParser::parse_constant_pool(TRAPS) {
  ClassFileStream* cfs = stream();
  constantPoolHandle nullHandle;

  cfs->guarantee_more(3, CHECK_(nullHandle)); // length, first cp tag
  u2 length = cfs->get_u2_fast();
  guarantee_property(
    length >= 1, "Illegal constant pool size %u in class file %s",
    length, CHECK_(nullHandle));
  constantPoolOop constant_pool =
                      oopFactory::new_constantPool(length,
                                                   oopDesc::IsSafeConc,
                                                   CHECK_(nullHandle));
  constantPoolHandle cp (THREAD, constant_pool);

  cp->set_partially_loaded();    // Enables heap verify to work on partial constantPoolOops
  ConstantPoolCleaner cp_in_error(cp); // set constant pool to be cleaned up.

  // parsing constant pool entries
  parse_constant_pool_entries(cp, length, CHECK_(nullHandle));

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

  // first verification pass - validate cross references and fixup class and string constants
  for (index = 1; index < length; index++) {          // Index 0 is unused
    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;
        int klass_ref_index = cp->klass_ref_index_at(index);
        int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
        check_property(valid_cp_range(klass_ref_index, length) &&
                       is_klass_reference(cp, klass_ref_index),
                       "Invalid constant pool index %u in class file %s",
                       klass_ref_index,
                       CHECK_(nullHandle));
        check_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_(nullHandle));
        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++;
        check_property(
          (index < length && cp->tag_at(index).is_invalid()),
          "Improper constant pool long/double index %u in class file %s",
          index, CHECK_(nullHandle));
        break;
      case JVM_CONSTANT_NameAndType : {
        if (!_need_verify) break;
        int name_ref_index = cp->name_ref_index_at(index);
        int signature_ref_index = cp->signature_ref_index_at(index);
        check_property(
          valid_cp_range(name_ref_index, length) &&
            cp->tag_at(name_ref_index).is_utf8(),
          "Invalid constant pool index %u in class file %s",
          name_ref_index, CHECK_(nullHandle));
        check_property(
          valid_cp_range(signature_ref_index, length) &&
            cp->tag_at(signature_ref_index).is_utf8(),
          "Invalid constant pool index %u in class file %s",
          signature_ref_index, CHECK_(nullHandle));
        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 :
        {
          int class_index = cp->klass_index_at(index);
          check_property(
            valid_cp_range(class_index, length) &&
              cp->tag_at(class_index).is_utf8(),
            "Invalid constant pool index %u in class file %s",
            class_index, CHECK_(nullHandle));
          cp->unresolved_klass_at_put(index, cp->symbol_at(class_index));
        }
        break;
      case JVM_CONSTANT_UnresolvedString :
        ShouldNotReachHere();     // Only JVM_CONSTANT_StringIndex should be present
        break;
      case JVM_CONSTANT_StringIndex :
        {
          int string_index = cp->string_index_at(index);
          check_property(
            valid_cp_range(string_index, length) &&
              cp->tag_at(string_index).is_utf8(),
            "Invalid constant pool index %u in class file %s",
            string_index, CHECK_(nullHandle));
          Symbol* sym = cp->symbol_at(string_index);
          cp->unresolved_string_at_put(index, sym);
        }
        break;
      case JVM_CONSTANT_MethodHandle :
        {
          int ref_index = cp->method_handle_index_at(index);
          check_property(
            valid_cp_range(ref_index, length) &&
                EnableInvokeDynamic,
              "Invalid constant pool index %u in class file %s",
              ref_index, CHECK_(nullHandle));
          constantTag tag = cp->tag_at(ref_index);
          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:
            check_property(
              tag.is_field(),
              "Invalid constant pool index %u in class file %s (not a field)",
              ref_index, CHECK_(nullHandle));
            break;
          case JVM_REF_invokeVirtual:
          case JVM_REF_invokeStatic:
          case JVM_REF_invokeSpecial:
          case JVM_REF_newInvokeSpecial:
            check_property(
              tag.is_method(),
              "Invalid constant pool index %u in class file %s (not a method)",
              ref_index, CHECK_(nullHandle));
            break;
          case JVM_REF_invokeInterface:
            check_property(
              tag.is_interface_method(),
              "Invalid constant pool index %u in class file %s (not an interface method)",
              ref_index, CHECK_(nullHandle));
            break;
          default:
            classfile_parse_error(
              "Bad method handle kind at constant pool index %u in class file %s",
              index, CHECK_(nullHandle));
          }
          // Keep the ref_index unchanged.  It will be indirected at link-time.
        }
        break;
      case JVM_CONSTANT_MethodType :
        {
          int ref_index = cp->method_type_index_at(index);
          check_property(
            valid_cp_range(ref_index, length) &&
                cp->tag_at(ref_index).is_utf8() &&
                EnableInvokeDynamic,
              "Invalid constant pool index %u in class file %s",
              ref_index, CHECK_(nullHandle));
        }
        break;
      case JVM_CONSTANT_InvokeDynamic :
        {
          int name_and_type_ref_index = cp->invoke_dynamic_name_and_type_ref_index_at(index);
          check_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_(nullHandle));
          // bootstrap specifier index must be checked later, when BootstrapMethods attr is available
          break;
        }
      default:
        fatal(err_msg("bad constant pool tag value %u",
                      cp->tag_at(index).value()));
        ShouldNotReachHere();
        break;
    } // end of switch
  } // end of for

  if (_cp_patches != NULL) {
    // need to treat this_class specially...
    assert(EnableInvokeDynamic, "");
    int this_class_index;
    {
      cfs->guarantee_more(8, CHECK_(nullHandle));  // flags, this_class, super_class, infs_len
      u1* mark = cfs->current();
      u2 flags         = cfs->get_u2_fast();
      this_class_index = cfs->get_u2_fast();
      cfs->set_current(mark);  // revert to mark
    }

    for (index = 1; index < length; index++) {          // Index 0 is unused
      if (has_cp_patch_at(index)) {
        guarantee_property(index != this_class_index,
                           "Illegal constant pool patch to self at %d in class file %s",
                           index, CHECK_(nullHandle));
        patch_constant_pool(cp, index, cp_patch_at(index), CHECK_(nullHandle));
      }
    }
    // Ensure that all the patches have been used.
    for (index = 0; index < _cp_patches->length(); index++) {
      guarantee_property(!has_cp_patch_at(index),
                         "Unused constant pool patch at %d in class file %s",
                         index, CHECK_(nullHandle));
    }
  }

  if (!_need_verify) {
    cp_in_error.set_in_error(false);
    return cp;
  }

  // second verification pass - checks the strings are of the right format.
  // but not yet to the other entries
  for (index = 1; index < length; index++) {
    jbyte tag = cp->tag_at(index).value();
    switch (tag) {
      case JVM_CONSTANT_UnresolvedClass: {
        Symbol*  class_name = cp->unresolved_klass_at(index);
        // check the name, even if _cp_patches will overwrite it
        verify_legal_class_name(class_name, CHECK_(nullHandle));
        break;
      }
      case JVM_CONSTANT_NameAndType: {
        if (_need_verify && _major_version >= JAVA_7_VERSION) {
          int sig_index = cp->signature_ref_index_at(index);
          int name_index = cp->name_ref_index_at(index);
          Symbol*  name = cp->symbol_at(name_index);
          Symbol*  sig = cp->symbol_at(sig_index);
          if (sig->byte_at(0) == JVM_SIGNATURE_FUNC) {
            verify_legal_method_signature(name, sig, CHECK_(nullHandle));
          } else {
            verify_legal_field_signature(name, sig, CHECK_(nullHandle));
          }
        }
        break;
      }
      case JVM_CONSTANT_InvokeDynamic:
      case JVM_CONSTANT_Fieldref:
      case JVM_CONSTANT_Methodref:
      case JVM_CONSTANT_InterfaceMethodref: {
        int name_and_type_ref_index = cp->name_and_type_ref_index_at(index);
        // already verified to be utf8
        int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index);
        // already verified to be utf8
        int signature_ref_index = cp->signature_ref_index_at(name_and_type_ref_index);
        Symbol*  name = cp->symbol_at(name_ref_index);
        Symbol*  signature = cp->symbol_at(signature_ref_index);
        if (tag == JVM_CONSTANT_Fieldref) {
          verify_legal_field_name(name, CHECK_(nullHandle));
          if (_need_verify && _major_version >= JAVA_7_VERSION) {
            // Signature is verified above, when iterating NameAndType_info.
            // Need only to be sure it's the right type.
            if (signature->byte_at(0) == JVM_SIGNATURE_FUNC) {
              throwIllegalSignature(
                  "Field", name, signature, CHECK_(nullHandle));
            }
          } else {
            verify_legal_field_signature(name, signature, CHECK_(nullHandle));
          }
        } else {
          verify_legal_method_name(name, CHECK_(nullHandle));
          if (_need_verify && _major_version >= JAVA_7_VERSION) {
            // Signature is verified above, when iterating NameAndType_info.
            // Need only to be sure it's the right type.
            if (signature->byte_at(0) != JVM_SIGNATURE_FUNC) {
              throwIllegalSignature(
                  "Method", name, signature, CHECK_(nullHandle));
            }
          } else {
            verify_legal_method_signature(name, signature, CHECK_(nullHandle));
          }
          if (tag == JVM_CONSTANT_Methodref) {
            // 4509014: If a class method name begins with '<', it must be "<init>".
            assert(name != NULL, "method name in constant pool is null");
            unsigned int name_len = name->utf8_length();
            assert(name_len > 0, "bad method name");  // already verified as legal name
            if (name->byte_at(0) == '<') {
              if (name != vmSymbols::object_initializer_name()) {
                classfile_parse_error(
                  "Bad method name at constant pool index %u in class file %s",
                  name_ref_index, CHECK_(nullHandle));
              }
            }
          }
        }
        break;
      }
      case JVM_CONSTANT_MethodHandle: {
        int ref_index = cp->method_handle_index_at(index);
        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:
          {
            int name_and_type_ref_index = cp->name_and_type_ref_index_at(ref_index);
            int name_ref_index = cp->name_ref_index_at(name_and_type_ref_index);
            Symbol*  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, CHECK_(nullHandle));
              }
            } 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, CHECK_(nullHandle));
              }
            }
          }
          break;
          // Other ref_kinds are already fully checked in previous pass.
        }
        break;
      }
      case JVM_CONSTANT_MethodType: {
        Symbol* no_name = vmSymbols::type_name(); // place holder
        Symbol*  signature = cp->method_type_signature_at(index);
        verify_legal_method_signature(no_name, signature, CHECK_(nullHandle));
        break;
      }
      case JVM_CONSTANT_Utf8: {
        assert(cp->symbol_at(index)->refcount() != 0, "count corrupted");
      }
    }  // end of switch
  }  // end of for

  cp_in_error.set_in_error(false);
  return cp;
}


void ClassFileParser::patch_constant_pool(constantPoolHandle cp, int index, Handle patch, TRAPS) {
  assert(EnableInvokeDynamic, "");
  BasicType patch_type = T_VOID;
  switch (cp->tag_at(index).value()) {

  case JVM_CONSTANT_UnresolvedClass :
    // Patching a class means pre-resolving it.
    // The name in the constant pool is ignored.
    if (java_lang_Class::is_instance(patch())) {
      guarantee_property(!java_lang_Class::is_primitive(patch()),
                         "Illegal class patch at %d in class file %s",
                         index, CHECK);
      cp->klass_at_put(index, java_lang_Class::as_klassOop(patch()));
    } else {
      guarantee_property(java_lang_String::is_instance(patch()),
                         "Illegal class patch at %d in class file %s",
                         index, CHECK);
      Symbol* name = java_lang_String::as_symbol(patch(), CHECK);
      cp->unresolved_klass_at_put(index, name);
    }
    break;

  case JVM_CONSTANT_UnresolvedString :
    // Patching a string means pre-resolving it.
    // The spelling in the constant pool is ignored.
    // The constant reference may be any object whatever.
    // If it is not a real interned string, the constant is referred
    // to as a "pseudo-string", and must be presented to the CP
    // explicitly, because it may require scavenging.
    cp->pseudo_string_at_put(index, patch());
    break;

  case JVM_CONSTANT_Integer : patch_type = T_INT;    goto patch_prim;
  case JVM_CONSTANT_Float :   patch_type = T_FLOAT;  goto patch_prim;
  case JVM_CONSTANT_Long :    patch_type = T_LONG;   goto patch_prim;
  case JVM_CONSTANT_Double :  patch_type = T_DOUBLE; goto patch_prim;
  patch_prim:
    {
      jvalue value;
      BasicType value_type = java_lang_boxing_object::get_value(patch(), &value);
      guarantee_property(value_type == patch_type,
                         "Illegal primitive patch at %d in class file %s",
                         index, CHECK);
      switch (value_type) {
      case T_INT:    cp->int_at_put(index,   value.i); break;
      case T_FLOAT:  cp->float_at_put(index, value.f); break;
      case T_LONG:   cp->long_at_put(index,  value.j); break;
      case T_DOUBLE: cp->double_at_put(index, value.d); break;
      default:       assert(false, "");
      }
    }
    break;

  default:
    // %%% TODO: put method handles into CONSTANT_InterfaceMethodref, etc.
    guarantee_property(!has_cp_patch_at(index),
                       "Illegal unexpected patch at %d in class file %s",
                       index, CHECK);
    return;
  }

  // On fall-through, mark the patch as used.
  clear_cp_patch_at(index);
}



class NameSigHash: public ResourceObj {
 public:
  Symbol*       _name;       // name
  Symbol*       _sig;        // signature
  NameSigHash*  _next;       // Next entry in hash table
};


#define HASH_ROW_SIZE 256

unsigned int hash(Symbol* name, Symbol* sig) {
  unsigned int raw_hash = 0;
  raw_hash += ((unsigned int)(uintptr_t)name) >> (LogHeapWordSize + 2);
  raw_hash += ((unsigned int)(uintptr_t)sig) >> LogHeapWordSize;

  return (raw_hash + (unsigned int)(uintptr_t)name) % HASH_ROW_SIZE;
}


void initialize_hashtable(NameSigHash** table) {
  memset((void*)table, 0, sizeof(NameSigHash*) * HASH_ROW_SIZE);
}

// Return false if the name/sig combination is found in table.
// Return true if no duplicate is found. And name/sig is added as a new entry in table.
// The old format checker uses heap sort to find duplicates.
// NOTE: caller should guarantee that GC doesn't happen during the life cycle
// of table since we don't expect Symbol*'s to move.
bool put_after_lookup(Symbol* name, Symbol* sig, NameSigHash** table) {
  assert(name != NULL, "name in constant pool is NULL");

  // First lookup for duplicates
  int index = hash(name, sig);
  NameSigHash* entry = table[index];
  while (entry != NULL) {
    if (entry->_name == name && entry->_sig == sig) {
      return false;
    }
    entry = entry->_next;
  }

  // No duplicate is found, allocate a new entry and fill it.
  entry = new NameSigHash();
  entry->_name = name;
  entry->_sig = sig;

  // Insert into hash table
  entry->_next = table[index];
  table[index] = entry;

  return true;
}


objArrayHandle ClassFileParser::parse_interfaces(constantPoolHandle cp,
                                                 int length,
                                                 Handle class_loader,
                                                 Handle protection_domain,
                                                 Symbol* class_name,
                                                 TRAPS) {
  ClassFileStream* cfs = stream();
  assert(length > 0, "only called for length>0");
  objArrayHandle nullHandle;
  objArrayOop interface_oop = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
  objArrayHandle interfaces (THREAD, interface_oop);

  int index;
  for (index = 0; index < length; index++) {
    u2 interface_index = cfs->get_u2(CHECK_(nullHandle));
    KlassHandle interf;
    check_property(
      valid_cp_range(interface_index, cp->length()) &&
      is_klass_reference(cp, interface_index),
      "Interface name has bad constant pool index %u in class file %s",
      interface_index, CHECK_(nullHandle));
    if (cp->tag_at(interface_index).is_klass()) {
      interf = KlassHandle(THREAD, cp->resolved_klass_at(interface_index));
    } else {
      Symbol*  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->byte_at(0) != JVM_SIGNATURE_ARRAY,
                         "Bad interface name in class file %s", CHECK_(nullHandle));

      // Call resolve_super so classcircularity is checked
      klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
                    unresolved_klass, class_loader, protection_domain,
                    false, CHECK_(nullHandle));
      interf = KlassHandle(THREAD, k);

      if (LinkWellKnownClasses)  // my super type is well known to me
        cp->klass_at_put(interface_index, interf()); // eagerly resolve
    }

    if (!Klass::cast(interf())->is_interface()) {
      THROW_MSG_(vmSymbols::java_lang_IncompatibleClassChangeError(), "Implementing class", nullHandle);
    }
    interfaces->obj_at_put(index, interf());
  }

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

  // Check if there's any duplicates in interfaces
  ResourceMark rm(THREAD);
  NameSigHash** interface_names = NEW_RESOURCE_ARRAY_IN_THREAD(
    THREAD, NameSigHash*, HASH_ROW_SIZE);
  initialize_hashtable(interface_names);
  bool dup = false;
  {
    debug_only(No_Safepoint_Verifier nsv;)
    for (index = 0; index < length; index++) {
      klassOop k = (klassOop)interfaces->obj_at(index);
      Symbol* name = instanceKlass::cast(k)->name();
      // If no duplicates, add (name, NULL) in hashtable interface_names.
      if (!put_after_lookup(name, NULL, interface_names)) {
        dup = true;
        break;
      }
    }
  }
  if (dup) {
    classfile_parse_error("Duplicate interface name in class file %s",
                          CHECK_(nullHandle));
  }

  return interfaces;
}


void ClassFileParser::verify_constantvalue(int constantvalue_index, int signature_index, constantPoolHandle cp, TRAPS) {
  // 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);
  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() || value_type.is_unresolved_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, CHECK);
  }
}


// Parse attributes for a field.
void ClassFileParser::parse_field_attributes(constantPoolHandle cp,
                                             u2 attributes_count,
                                             bool is_static, u2 signature_index,
                                             u2* constantvalue_index_addr,
                                             bool* is_synthetic_addr,
                                             u2* generic_signature_index_addr,
                                             typeArrayHandle* field_annotations,
                                             TRAPS) {
  ClassFileStream* cfs = stream();
  assert(attributes_count > 0, "length should be greater than 0");
  u2 constantvalue_index = 0;
  u2 generic_signature_index = 0;
  bool is_synthetic = false;
  u1* runtime_visible_annotations = NULL;
  int runtime_visible_annotations_length = 0;
  u1* runtime_invisible_annotations = NULL;
  int runtime_invisible_annotations_length = 0;
  while (attributes_count--) {
    cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
    u2 attribute_name_index = cfs->get_u2_fast();
    u4 attribute_length = cfs->get_u4_fast();
    check_property(valid_cp_range(attribute_name_index, cp->length()) &&
                   cp->tag_at(attribute_name_index).is_utf8(),
                   "Invalid field attribute index %u in class file %s",
                   attribute_name_index,
                   CHECK);
    Symbol* 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", CHECK);
      }
      check_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(constantvalue_index, signature_index, cp, 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, CHECK);
      }
      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, CHECK);
      }
    } else if (_major_version >= JAVA_1_5_VERSION) {
      if (attribute_name == vmSymbols::tag_signature()) {
        if (attribute_length != 2) {
          classfile_parse_error(
            "Wrong size %u for field's Signature attribute in class file %s",
            attribute_length, CHECK);
        }
        generic_signature_index = cfs->get_u2(CHECK);
      } else if (attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
        runtime_visible_annotations_length = attribute_length;
        runtime_visible_annotations = cfs->get_u1_buffer();
        assert(runtime_visible_annotations != NULL, "null visible annotations");
        cfs->skip_u1(runtime_visible_annotations_length, CHECK);
      } else if (PreserveAllAnnotations && attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
        runtime_invisible_annotations_length = attribute_length;
        runtime_invisible_annotations = cfs->get_u1_buffer();
        assert(runtime_invisible_annotations != NULL, "null invisible annotations");
        cfs->skip_u1(runtime_invisible_annotations_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;
  *field_annotations = assemble_annotations(runtime_visible_annotations,
                                            runtime_visible_annotations_length,
                                            runtime_invisible_annotations,
                                            runtime_invisible_annotations_length,
                                            CHECK);
  return;
}


// Field allocation types. Used for computing field offsets.

enum FieldAllocationType {
  STATIC_OOP,           // Oops
  STATIC_BYTE,          // Boolean, Byte, char
  STATIC_SHORT,         // shorts
  STATIC_WORD,          // ints
  STATIC_DOUBLE,        // aligned long or double
  NONSTATIC_OOP,
  NONSTATIC_BYTE,
  NONSTATIC_SHORT,
  NONSTATIC_WORD,
  NONSTATIC_DOUBLE,
  MAX_FIELD_ALLOCATION_TYPE,
  BAD_ALLOCATION_TYPE = -1
};

static FieldAllocationType _basic_type_to_atype[2 * (T_CONFLICT + 1)] = {
  BAD_ALLOCATION_TYPE, // 0
  BAD_ALLOCATION_TYPE, // 1
  BAD_ALLOCATION_TYPE, // 2
  BAD_ALLOCATION_TYPE, // 3
  NONSTATIC_BYTE ,     // T_BOOLEAN  =  4,
  NONSTATIC_SHORT,     // T_CHAR     =  5,
  NONSTATIC_WORD,      // T_FLOAT    =  6,
  NONSTATIC_DOUBLE,    // T_DOUBLE   =  7,
  NONSTATIC_BYTE,      // T_BYTE     =  8,
  NONSTATIC_SHORT,     // T_SHORT    =  9,
  NONSTATIC_WORD,      // T_INT      = 10,
  NONSTATIC_DOUBLE,    // T_LONG     = 11,
  NONSTATIC_OOP,       // T_OBJECT   = 12,
  NONSTATIC_OOP,       // T_ARRAY    = 13,
  BAD_ALLOCATION_TYPE, // T_VOID     = 14,
  BAD_ALLOCATION_TYPE, // T_ADDRESS  = 15,
  BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16,
  BAD_ALLOCATION_TYPE, // T_CONFLICT = 17,
  BAD_ALLOCATION_TYPE, // 0
  BAD_ALLOCATION_TYPE, // 1
  BAD_ALLOCATION_TYPE, // 2
  BAD_ALLOCATION_TYPE, // 3
  STATIC_BYTE ,        // T_BOOLEAN  =  4,
  STATIC_SHORT,        // T_CHAR     =  5,
  STATIC_WORD,          // T_FLOAT    =  6,
  STATIC_DOUBLE,       // T_DOUBLE   =  7,
  STATIC_BYTE,         // T_BYTE     =  8,
  STATIC_SHORT,        // T_SHORT    =  9,
  STATIC_WORD,         // T_INT      = 10,
  STATIC_DOUBLE,       // T_LONG     = 11,
  STATIC_OOP,          // T_OBJECT   = 12,
  STATIC_OOP,          // T_ARRAY    = 13,
  BAD_ALLOCATION_TYPE, // T_VOID     = 14,
  BAD_ALLOCATION_TYPE, // T_ADDRESS  = 15,
  BAD_ALLOCATION_TYPE, // T_NARROWOOP= 16,
  BAD_ALLOCATION_TYPE, // T_CONFLICT = 17,
};

static FieldAllocationType basic_type_to_atype(bool is_static, BasicType type) {
  assert(type >= T_BOOLEAN && type < T_VOID, "only allowable values");
  FieldAllocationType result = _basic_type_to_atype[type + (is_static ? (T_CONFLICT + 1) : 0)];
  assert(result != BAD_ALLOCATION_TYPE, "bad type");
  return result;
}

class FieldAllocationCount: public ResourceObj {
 public:
  u2 count[MAX_FIELD_ALLOCATION_TYPE];

  FieldAllocationCount() {
    for (int i = 0; i < MAX_FIELD_ALLOCATION_TYPE; i++) {
      count[i] = 0;
    }
  }

  FieldAllocationType update(bool is_static, BasicType type) {
    FieldAllocationType atype = basic_type_to_atype(is_static, type);
    // Make sure there is no overflow with injected fields.
    assert(count[atype] < 0xFFFF, "More than 65535 fields");
    count[atype]++;
    return atype;
  }
};


typeArrayHandle ClassFileParser::parse_fields(Symbol* class_name,
                                              constantPoolHandle cp, bool is_interface,
                                              FieldAllocationCount *fac,
                                              objArrayHandle* fields_annotations,
                                              u2* java_fields_count_ptr, TRAPS) {
  ClassFileStream* cfs = stream();
  typeArrayHandle nullHandle;
  cfs->guarantee_more(2, CHECK_(nullHandle));  // length
  u2 length = cfs->get_u2_fast();
  *java_fields_count_ptr = length;

  int num_injected = 0;
  InjectedField* injected = JavaClasses::get_injected(class_name, &num_injected);

  // Tuples of shorts [access, name index, sig index, initial value index, byte offset, generic signature index]
  typeArrayOop new_fields = oopFactory::new_permanent_shortArray((length + num_injected) * FieldInfo::field_slots, CHECK_(nullHandle));
  typeArrayHandle fields(THREAD, new_fields);

  typeArrayHandle field_annotations;
  for (int n = 0; n < length; n++) {
    cfs->guarantee_more(8, CHECK_(nullHandle));  // access_flags, name_index, descriptor_index, attributes_count

    AccessFlags access_flags;
    jint flags = cfs->get_u2_fast() & JVM_RECOGNIZED_FIELD_MODIFIERS;
    verify_legal_field_modifiers(flags, is_interface, CHECK_(nullHandle));
    access_flags.set_flags(flags);

    u2 name_index = cfs->get_u2_fast();
    int cp_size = cp->length();
    check_property(
      valid_cp_range(name_index, cp_size) && cp->tag_at(name_index).is_utf8(),
      "Invalid constant pool index %u for field name in class file %s",
      name_index, CHECK_(nullHandle));
    Symbol*  name = cp->symbol_at(name_index);
    verify_legal_field_name(name, CHECK_(nullHandle));

    u2 signature_index = cfs->get_u2_fast();
    check_property(
      valid_cp_range(signature_index, cp_size) &&
        cp->tag_at(signature_index).is_utf8(),
      "Invalid constant pool index %u for field signature in class file %s",
      signature_index, CHECK_(nullHandle));
    Symbol*  sig = cp->symbol_at(signature_index);
    verify_legal_field_signature(name, sig, CHECK_(nullHandle));

    u2 constantvalue_index = 0;
    bool is_synthetic = false;
    u2 generic_signature_index = 0;
    bool is_static = access_flags.is_static();

    u2 attributes_count = cfs->get_u2_fast();
    if (attributes_count > 0) {
      parse_field_attributes(cp, attributes_count, is_static, signature_index,
                             &constantvalue_index, &is_synthetic,
                             &generic_signature_index, &field_annotations,
                             CHECK_(nullHandle));
      if (field_annotations.not_null()) {
        if (fields_annotations->is_null()) {
          objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
          *fields_annotations = objArrayHandle(THREAD, md);
        }
        (*fields_annotations)->obj_at_put(n, field_annotations());
      }
      if (is_synthetic) {
        access_flags.set_is_synthetic();
      }
    }

    FieldInfo* field = FieldInfo::from_field_array(fields(), n);
    field->initialize(access_flags.as_short(),
                      name_index,
                      signature_index,
                      constantvalue_index,
                      generic_signature_index,
                      0);

    BasicType type = cp->basic_type_for_signature_at(signature_index);

    // Remember how many oops we encountered and compute allocation type
    FieldAllocationType atype = fac->update(is_static, type);

    // The correct offset is computed later (all oop fields will be located together)
    // We temporarily store the allocation type in the offset field
    field->set_offset(atype);
  }

  if (num_injected != 0) {
    int index = length;
    for (int n = 0; n < num_injected; n++) {
      // Check for duplicates
      if (injected[n].may_be_java) {
        Symbol* name      = injected[n].name();
        Symbol* signature = injected[n].signature();
        bool duplicate = false;
        for (int i = 0; i < length; i++) {
          FieldInfo* f = FieldInfo::from_field_array(fields(), 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* field = FieldInfo::from_field_array(fields(), index);
      field->initialize(JVM_ACC_FIELD_INTERNAL,
                        injected[n].name_index,
                        injected[n].signature_index,
                        0,
                        0,
                        0);

      BasicType type = FieldType::basic_type(injected[n].signature());

      // Remember how many oops we encountered and compute allocation type
      FieldAllocationType atype = fac->update(false, type);

      // The correct offset is computed later (all oop fields will be located together)
      // We temporarily store the allocation type in the offset field
      field->set_offset(atype);
      index++;
    }

    if (index < length + num_injected) {
      // sometimes injected fields already exist in the Java source so
      // the fields array could be too long.  In that case trim the
      // fields array.
      new_fields = oopFactory::new_permanent_shortArray(index * FieldInfo::field_slots, CHECK_(nullHandle));
      for (int i = 0; i < index * FieldInfo::field_slots; i++) {
        new_fields->short_at_put(i, fields->short_at(i));
      }
      fields = new_fields;
    }
  }

  if (_need_verify && length > 1) {
    // Check duplicated fields
    ResourceMark rm(THREAD);
    NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD(
      THREAD, NameSigHash*, HASH_ROW_SIZE);
    initialize_hashtable(names_and_sigs);
    bool dup = false;
    {
      debug_only(No_Safepoint_Verifier nsv;)
      for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
        Symbol* name = fs.name();
        Symbol* sig = fs.signature();
        // If no duplicates, add name/signature in hashtable names_and_sigs.
        if (!put_after_lookup(name, sig, names_and_sigs)) {
          dup = true;
          break;
        }
      }
    }
    if (dup) {
      classfile_parse_error("Duplicate field name&signature in class file %s",
                            CHECK_(nullHandle));
    }
  }

  return fields;
}


static void copy_u2_with_conversion(u2* dest, u2* src, int length) {
  while (length-- > 0) {
    *dest++ = Bytes::get_Java_u2((u1*) (src++));
  }
}


typeArrayHandle ClassFileParser::parse_exception_table(u4 code_length,
                                                       u4 exception_table_length,
                                                       constantPoolHandle cp,
                                                       TRAPS) {
  ClassFileStream* cfs = stream();
  typeArrayHandle nullHandle;

  // 4-tuples of ints [start_pc, end_pc, handler_pc, catch_type index]
  typeArrayOop eh = oopFactory::new_permanent_intArray(exception_table_length*4, CHECK_(nullHandle));
  typeArrayHandle exception_handlers = typeArrayHandle(THREAD, eh);

  int index = 0;
  cfs->guarantee_more(8 * exception_table_length, CHECK_(nullHandle)); // start_pc, end_pc, handler_pc, catch_type_index
  for (unsigned int i = 0; i < exception_table_length; i++) {
    u2 start_pc = cfs->get_u2_fast();
    u2 end_pc = cfs->get_u2_fast();
    u2 handler_pc = cfs->get_u2_fast();
    u2 catch_type_index = cfs->get_u2_fast();
    // Will check legal target after parsing code array in verifier.
    if (_need_verify) {
      guarantee_property((start_pc < end_pc) && (end_pc <= code_length),
                         "Illegal exception table range in class file %s", CHECK_(nullHandle));
      guarantee_property(handler_pc < code_length,
                         "Illegal exception table handler in class file %s", CHECK_(nullHandle));
      if (catch_type_index != 0) {
        guarantee_property(valid_cp_range(catch_type_index, cp->length()) &&
                           is_klass_reference(cp, catch_type_index),
                           "Catch type in exception table has bad constant type in class file %s", CHECK_(nullHandle));
      }
    }
    exception_handlers->int_at_put(index++, start_pc);
    exception_handlers->int_at_put(index++, end_pc);
    exception_handlers->int_at_put(index++, handler_pc);
    exception_handlers->int_at_put(index++, catch_type_index);
  }
  return exception_handlers;
}

void ClassFileParser::parse_linenumber_table(
    u4 code_attribute_length, u4 code_length,
    CompressedLineNumberWriteStream** write_stream, TRAPS) {
  ClassFileStream* cfs = stream();
  unsigned int num_entries = cfs->get_u2(CHECK);

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

  // Verify line number attribute and table length
  check_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) == NULL) {
    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) {
    u2 bci  = cfs->get_u2_fast(); // start_pc
    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 file LocalVariableTable elements.
class Classfile_LVT_Element VALUE_OBJ_CLASS_SPEC {
 public:
  u2 start_bci;
  u2 length;
  u2 name_cp_index;
  u2 descriptor_cp_index;
  u2 slot;
};


class LVT_Hash: public CHeapObj {
 public:
  LocalVariableTableElement  *_elem;  // element
  LVT_Hash*                   _next;  // Next entry in hash table
};

unsigned int hash(LocalVariableTableElement *elem) {
  unsigned int raw_hash = elem->start_bci;

  raw_hash = elem->length        + raw_hash * 37;
  raw_hash = elem->name_cp_index + raw_hash * 37;
  raw_hash = elem->slot          + raw_hash * 37;

  return raw_hash % HASH_ROW_SIZE;
}

void initialize_hashtable(LVT_Hash** table) {
  for (int i = 0; i < HASH_ROW_SIZE; i++) {
    table[i] = NULL;
  }
}

void clear_hashtable(LVT_Hash** table) {
  for (int i = 0; i < HASH_ROW_SIZE; i++) {
    LVT_Hash* current = table[i];
    LVT_Hash* next;
    while (current != NULL) {
      next = current->_next;
      current->_next = NULL;
      delete(current);
      current = next;
    }
    table[i] = NULL;
  }
}

LVT_Hash* LVT_lookup(LocalVariableTableElement *elem, int index, LVT_Hash** table) {
  LVT_Hash* entry = table[index];

  /*
   * 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
   */
  while (entry != NULL) {
    if (elem->start_bci           == entry->_elem->start_bci
     && elem->length              == entry->_elem->length
     && elem->name_cp_index       == entry->_elem->name_cp_index
     && elem->slot                == entry->_elem->slot
    ) {
      return entry;
    }
    entry = entry->_next;
  }
  return NULL;
}

// Return false if the local variable is found in table.
// Return true if no duplicate is found.
// And local variable is added as a new entry in table.
bool LVT_put_after_lookup(LocalVariableTableElement *elem, LVT_Hash** table) {
  // First lookup for duplicates
  int index = hash(elem);
  LVT_Hash* entry = LVT_lookup(elem, index, table);

  if (entry != NULL) {
      return false;
  }
  // No duplicate is found, allocate a new entry and fill it.
  if ((entry = new LVT_Hash()) == NULL) {
    return false;
  }
  entry->_elem = elem;

  // Insert into hash table
  entry->_next = table[index];
  table[index] = entry;

  return true;
}

void copy_lvt_element(Classfile_LVT_Element *src, LocalVariableTableElement *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)
u2* ClassFileParser::parse_localvariable_table(u4 code_length,
                                               u2 max_locals,
                                               u4 code_attribute_length,
                                               constantPoolHandle cp,
                                               u2* localvariable_table_length,
                                               bool isLVTT,
                                               TRAPS) {
  ClassFileStream* cfs = stream();
  const char * tbl_name = (isLVTT) ? "LocalVariableTypeTable" : "LocalVariableTable";
  *localvariable_table_length = cfs->get_u2(CHECK_NULL);
  unsigned int size = (*localvariable_table_length) * sizeof(Classfile_LVT_Element) / sizeof(u2);
  // 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);
  }
  u2* localvariable_table_start = cfs->get_u2_buffer();
  assert(localvariable_table_start != NULL, "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++) {
      u2 start_pc = cfs->get_u2_fast();
      u2 length = cfs->get_u2_fast();
      u2 name_index = cfs->get_u2_fast();
      u2 descriptor_index = cfs->get_u2_fast();
      u2 index = cfs->get_u2_fast();
      // Assign to a u4 to avoid overflow
      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, CHECK_NULL);
      }
      if (end_pc > code_length) {
        classfile_parse_error(
          "Invalid length %u in %s in class file %s",
          length, tbl_name, CHECK_NULL);
      }
      int cp_size = cp->length();
      guarantee_property(
        valid_cp_range(name_index, cp_size) &&
          cp->tag_at(name_index).is_utf8(),
        "Name index %u in %s has bad constant type in class file %s",
        name_index, tbl_name, CHECK_NULL);
      guarantee_property(
        valid_cp_range(descriptor_index, cp_size) &&
          cp->tag_at(descriptor_index).is_utf8(),
        "Signature index %u in %s has bad constant type in class file %s",
        descriptor_index, tbl_name, CHECK_NULL);

      Symbol*  name = cp->symbol_at(name_index);
      Symbol*  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;
}


void ClassFileParser::parse_type_array(u2 array_length, u4 code_length, u4* u1_index, u4* u2_index,
                                      u1* u1_array, u2* u2_array, constantPoolHandle cp, TRAPS) {
  ClassFileStream* cfs = stream();
  u2 index = 0; // index in the array with long/double occupying two slots
  u4 i1 = *u1_index;
  u4 i2 = *u2_index + 1;
  for(int i = 0; i < array_length; i++) {
    u1 tag = u1_array[i1++] = cfs->get_u1(CHECK);
    index++;
    if (tag == ITEM_Long || tag == ITEM_Double) {
      index++;
    } else if (tag == ITEM_Object) {
      u2 class_index = u2_array[i2++] = cfs->get_u2(CHECK);
      guarantee_property(valid_cp_range(class_index, cp->length()) &&
                         is_klass_reference(cp, class_index),
                         "Bad class index %u in StackMap in class file %s",
                         class_index, CHECK);
    } else if (tag == ITEM_Uninitialized) {
      u2 offset = u2_array[i2++] = cfs->get_u2(CHECK);
      guarantee_property(
        offset < code_length,
        "Bad uninitialized type offset %u in StackMap in class file %s",
        offset, CHECK);
    } else {
      guarantee_property(
        tag <= (u1)ITEM_Uninitialized,
        "Unknown variable type %u in StackMap in class file %s",
        tag, CHECK);
    }
  }
  u2_array[*u2_index] = index;
  *u1_index = i1;
  *u2_index = i2;
}

typeArrayOop ClassFileParser::parse_stackmap_table(
    u4 code_attribute_length, TRAPS) {
  if (code_attribute_length == 0)
    return NULL;

  ClassFileStream* cfs = stream();
  u1* stackmap_table_start = cfs->get_u1_buffer();
  assert(stackmap_table_start != NULL, "null stackmap table");

  // check code_attribute_length first
  stream()->skip_u1(code_attribute_length, CHECK_NULL);

  if (!_need_verify && !DumpSharedSpaces) {
    return NULL;
  }

  typeArrayOop stackmap_data =
    oopFactory::new_permanent_byteArray(code_attribute_length, CHECK_NULL);

  stackmap_data->set_length(code_attribute_length);
  memcpy((void*)stackmap_data->byte_at_addr(0),
         (void*)stackmap_table_start, code_attribute_length);
  return stackmap_data;
}

u2* ClassFileParser::parse_checked_exceptions(u2* checked_exceptions_length,
                                              u4 method_attribute_length,
                                              constantPoolHandle cp, TRAPS) {
  ClassFileStream* cfs = stream();
  cfs->guarantee_more(2, CHECK_NULL);  // checked_exceptions_length
  *checked_exceptions_length = cfs->get_u2_fast();
  unsigned int size = (*checked_exceptions_length) * sizeof(CheckedExceptionElement) / sizeof(u2);
  u2* checked_exceptions_start = cfs->get_u2_buffer();
  assert(checked_exceptions_start != NULL, "null checked exceptions");
  if (!_need_verify) {
    cfs->skip_u2_fast(size);
  } else {
    // Verify each value in the checked exception table
    u2 checked_exception;
    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();
      check_property(
        valid_cp_range(checked_exception, cp->length()) &&
        is_klass_reference(cp, 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, Symbol* name, Symbol* sig, TRAPS) {
  ResourceMark rm(THREAD);
  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());
}

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

// Note: the parse_method below is big and clunky because all parsing of the code and exceptions
// attribute is inlined. This is curbersome to avoid since we inline most of the parts in the
// methodOop to save footprint, so we only know the size of the resulting methodOop when the
// entire method attribute is parsed.
//
// The promoted_flags parameter is used to pass relevant access_flags
// from the method back up to the containing klass. These flag values
// are added to klass's access_flags.

methodHandle ClassFileParser::parse_method(constantPoolHandle cp, bool is_interface,
                                           AccessFlags *promoted_flags,
                                           typeArrayHandle* method_annotations,
                                           typeArrayHandle* method_parameter_annotations,
                                           typeArrayHandle* method_default_annotations,
                                           TRAPS) {
  ClassFileStream* cfs = stream();
  methodHandle nullHandle;
  ResourceMark rm(THREAD);
  // Parse fixed parts
  cfs->guarantee_more(8, CHECK_(nullHandle)); // access_flags, name_index, descriptor_index, attributes_count

  int flags = cfs->get_u2_fast();
  u2 name_index = cfs->get_u2_fast();
  int cp_size = cp->length();
  check_property(
    valid_cp_range(name_index, cp_size) &&
      cp->tag_at(name_index).is_utf8(),
    "Illegal constant pool index %u for method name in class file %s",
    name_index, CHECK_(nullHandle));
  Symbol*  name = cp->symbol_at(name_index);
  verify_legal_method_name(name, CHECK_(nullHandle));

  u2 signature_index = cfs->get_u2_fast();
  guarantee_property(
    valid_cp_range(signature_index, cp_size) &&
      cp->tag_at(signature_index).is_utf8(),
    "Illegal constant pool index %u for method signature in class file %s",
    signature_index, CHECK_(nullHandle));
  Symbol*  signature = cp->symbol_at(signature_index);

  AccessFlags access_flags;
  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 | JVM_ACC_STRICT;
    }
  } else {
    verify_legal_method_modifiers(flags, is_interface, name, CHECK_(nullHandle));
  }

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

  access_flags.set_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;
  u1* code_start = 0;
  u2 exception_table_length = 0;
  typeArrayHandle exception_handlers(THREAD, Universe::the_empty_int_array());
  u2 checked_exceptions_length = 0;
  u2* checked_exceptions_start = NULL;
  CompressedLineNumberWriteStream* linenumber_table = NULL;
  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;
  u2** localvariable_table_start;
  u2* localvariable_type_table_length;
  u2** localvariable_type_table_start;
  bool parsed_code_attribute = false;
  bool parsed_checked_exceptions_attribute = false;
  bool parsed_stackmap_attribute = false;
  // stackmap attribute - JDK1.5
  typeArrayHandle stackmap_data;
  u2 generic_signature_index = 0;
  u1* runtime_visible_annotations = NULL;
  int runtime_visible_annotations_length = 0;
  u1* runtime_invisible_annotations = NULL;
  int runtime_invisible_annotations_length = 0;
  u1* runtime_visible_parameter_annotations = NULL;
  int runtime_visible_parameter_annotations_length = 0;
  u1* runtime_invisible_parameter_annotations = NULL;
  int runtime_invisible_parameter_annotations_length = 0;
  u1* annotation_default = NULL;
  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_(nullHandle));  // method_attribute_name_index, method_attribute_length
    u2 method_attribute_name_index = cfs->get_u2_fast();
    u4 method_attribute_length = cfs->get_u4_fast();
    check_property(
      valid_cp_range(method_attribute_name_index, cp_size) &&
        cp->tag_at(method_attribute_name_index).is_utf8(),
      "Invalid method attribute name index %u in class file %s",
      method_attribute_name_index, CHECK_(nullHandle));

    Symbol* 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_(nullHandle));
      }
      if (parsed_code_attribute) {
        classfile_parse_error("Multiple Code attributes in class file %s", CHECK_(nullHandle));
      }
      parsed_code_attribute = true;

      // Stack size, locals size, and code size
      if (_major_version == 45 && _minor_version <= 2) {
        cfs->guarantee_more(4, CHECK_(nullHandle));
        max_stack = cfs->get_u1_fast();
        max_locals = cfs->get_u1_fast();
        code_length = cfs->get_u2_fast();
      } else {
        cfs->guarantee_more(8, CHECK_(nullHandle));
        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_(nullHandle));
        guarantee_property(code_length > 0 && code_length <= MAX_CODE_SIZE,
                           "Invalid method Code length %u in class file %s",
                           code_length, CHECK_(nullHandle));
      }
      // Code pointer
      code_start = cfs->get_u1_buffer();
      assert(code_start != NULL, "null code start");
      cfs->guarantee_more(code_length, CHECK_(nullHandle));
      cfs->skip_u1_fast(code_length);

      // Exception handler table
      cfs->guarantee_more(2, CHECK_(nullHandle));  // exception_table_length
      exception_table_length = cfs->get_u2_fast();
      if (exception_table_length > 0) {
        exception_handlers =
              parse_exception_table(code_length, exception_table_length, cp, CHECK_(nullHandle));
      }

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

      unsigned int calculated_attribute_length = 0;

      if (_major_version > 45 || (_major_version == 45 && _minor_version > 2)) {
        calculated_attribute_length =
            sizeof(max_stack) + sizeof(max_locals) + sizeof(code_length);
      } else {
        // max_stack, locals and length are smaller in pre-version 45.2 classes
        calculated_attribute_length = sizeof(u1) + sizeof(u1) + sizeof(u2);
      }
      calculated_attribute_length +=
        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_(nullHandle));  // code_attribute_name_index, code_attribute_length
        u2 code_attribute_name_index = cfs->get_u2_fast();
        u4 code_attribute_length = cfs->get_u4_fast();
        calculated_attribute_length += code_attribute_length +
                                       sizeof(code_attribute_name_index) +
                                       sizeof(code_attribute_length);
        check_property(valid_cp_range(code_attribute_name_index, cp_size) &&
                       cp->tag_at(code_attribute_name_index).is_utf8(),
                       "Invalid code attribute name index %u in class file %s",
                       code_attribute_name_index,
                       CHECK_(nullHandle));
        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_(nullHandle));

        } 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, 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, u2*, INITIAL_MAX_LVT_NUMBER);
            lvt_allocated = true;
          }
          if (lvt_cnt == max_lvt_cnt) {
            max_lvt_cnt <<= 1;
            REALLOC_RESOURCE_ARRAY(u2, localvariable_table_length, lvt_cnt, max_lvt_cnt);
            REALLOC_RESOURCE_ARRAY(u2*, localvariable_table_start, lvt_cnt, max_lvt_cnt);
          }
          localvariable_table_start[lvt_cnt] =
            parse_localvariable_table(code_length,
                                      max_locals,
                                      code_attribute_length,
                                      cp,
                                      &localvariable_table_length[lvt_cnt],
                                      false,    // is not LVTT
                                      CHECK_(nullHandle));
          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, 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, u2*, INITIAL_MAX_LVT_NUMBER);
            lvt_allocated = true;
          }
          // Parse local variable type table
          if (lvtt_cnt == max_lvtt_cnt) {
            max_lvtt_cnt <<= 1;
            REALLOC_RESOURCE_ARRAY(u2, localvariable_type_table_length, lvtt_cnt, max_lvtt_cnt);
            REALLOC_RESOURCE_ARRAY(u2*, localvariable_type_table_start, lvtt_cnt, max_lvtt_cnt);
          }
          localvariable_type_table_start[lvtt_cnt] =
            parse_localvariable_table(code_length,
                                      max_locals,
                                      code_attribute_length,
                                      cp,
                                      &localvariable_type_table_length[lvtt_cnt],
                                      true,     // is LVTT
                                      CHECK_(nullHandle));
          lvtt_cnt++;
        } else if (UseSplitVerifier &&
                   _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", CHECK_(nullHandle));
          }
          typeArrayOop sm =
            parse_stackmap_table(code_attribute_length, CHECK_(nullHandle));
          stackmap_data = typeArrayHandle(THREAD, sm);
          parsed_stackmap_attribute = true;
        } else {
          // Skip unknown attributes
          cfs->skip_u1(code_attribute_length, CHECK_(nullHandle));
        }
      }
      // 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_(nullHandle));
      }
    } 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", CHECK_(nullHandle));
      }
      parsed_checked_exceptions_attribute = true;
      checked_exceptions_start =
            parse_checked_exceptions(&checked_exceptions_length,
                                     method_attribute_length,
                                     cp, CHECK_(nullHandle));
    } 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, CHECK_(nullHandle));
      }
      // 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, CHECK_(nullHandle));
      }
    } else if (_major_version >= JAVA_1_5_VERSION) {
      if (method_attribute_name == vmSymbols::tag_signature()) {
        if (method_attribute_length != 2) {
          classfile_parse_error(
            "Invalid Signature attribute length %u in class file %s",
            method_attribute_length, CHECK_(nullHandle));
        }
        cfs->guarantee_more(2, CHECK_(nullHandle));  // generic_signature_index
        generic_signature_index = cfs->get_u2_fast();
      } else if (method_attribute_name == vmSymbols::tag_runtime_visible_annotations()) {
        runtime_visible_annotations_length = method_attribute_length;
        runtime_visible_annotations = cfs->get_u1_buffer();
        assert(runtime_visible_annotations != NULL, "null visible annotations");
        cfs->skip_u1(runtime_visible_annotations_length, CHECK_(nullHandle));
      } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_annotations()) {
        runtime_invisible_annotations_length = method_attribute_length;
        runtime_invisible_annotations = cfs->get_u1_buffer();
        assert(runtime_invisible_annotations != NULL, "null invisible annotations");
        cfs->skip_u1(runtime_invisible_annotations_length, CHECK_(nullHandle));
      } else if (method_attribute_name == vmSymbols::tag_runtime_visible_parameter_annotations()) {
        runtime_visible_parameter_annotations_length = method_attribute_length;
        runtime_visible_parameter_annotations = cfs->get_u1_buffer();
        assert(runtime_visible_parameter_annotations != NULL, "null visible parameter annotations");
        cfs->skip_u1(runtime_visible_parameter_annotations_length, CHECK_(nullHandle));
      } else if (PreserveAllAnnotations && method_attribute_name == vmSymbols::tag_runtime_invisible_parameter_annotations()) {
        runtime_invisible_parameter_annotations_length = method_attribute_length;
        runtime_invisible_parameter_annotations = cfs->get_u1_buffer();
        assert(runtime_invisible_parameter_annotations != NULL, "null invisible parameter annotations");
        cfs->skip_u1(runtime_invisible_parameter_annotations_length, CHECK_(nullHandle));
      } else if (method_attribute_name == vmSymbols::tag_annotation_default()) {
        annotation_default_length = method_attribute_length;
        annotation_default = cfs->get_u1_buffer();
        assert(annotation_default != NULL, "null annotation default");
        cfs->skip_u1(annotation_default_length, CHECK_(nullHandle));
      } else {
        // Skip unknown attributes
        cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
      }
    } else {
      // Skip unknown attributes
      cfs->skip_u1(method_attribute_length, CHECK_(nullHandle));
    }
  }

  if (linenumber_table != NULL) {
    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_(nullHandle));
  }

  // All sizing information for a methodOop is finally available, now create it
  methodOop m_oop  = oopFactory::new_method(code_length, access_flags, linenumber_table_length,
                                            total_lvt_length, checked_exceptions_length,
                                            oopDesc::IsSafeConc, CHECK_(nullHandle));
  methodHandle m (THREAD, m_oop);

  ClassLoadingService::add_class_method_size(m_oop->size()*HeapWordSize);

  // 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->set_generic_signature_index(generic_signature_index);
#ifdef CC_INTERP
  // hmm is there a gc issue here??
  ResultTypeFinder rtf(cp->symbol_at(signature_index));
  m->set_result_index(rtf.type());
#endif

  if (args_size >= 0) {
    m->set_size_of_parameters(args_size);
  } else {
    m->compute_size_of_parameters(THREAD);
  }
#ifdef ASSERT
  if (args_size >= 0) {
    m->compute_size_of_parameters(THREAD);
    assert(args_size == m->size_of_parameters(), "");
  }
#endif

  // Fill in code attribute information
  m->set_max_stack(max_stack);
  m->set_max_locals(max_locals);
  m->constMethod()->set_stackmap_data(stackmap_data());

  /**
   * The exception_table field is the flag used to indicate
   * that the methodOop and it's associated constMethodOop are partially
   * initialized and thus are exempt from pre/post GC verification.  Once
   * the field is set, the oops are considered fully initialized so make
   * sure that the oops can pass verification when this field is set.
   */
  m->set_exception_table(exception_handlers());

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

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

  // Copy checked exceptions
  if (checked_exceptions_length > 0) {
    int size = checked_exceptions_length * sizeof(CheckedExceptionElement) / sizeof(u2);
    copy_u2_with_conversion((u2*) m->checked_exceptions_start(), checked_exceptions_start, size);
  }

  /* 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.
   */
  if (total_lvt_length > 0) {
    int tbl_no, idx;

    promoted_flags->set_has_localvariable_table();

    LVT_Hash** lvt_Hash = NEW_RESOURCE_ARRAY(LVT_Hash*, HASH_ROW_SIZE);
    initialize_hashtable(lvt_Hash);

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

    for (tbl_no = 0; tbl_no < lvt_cnt; tbl_no++) {
      cf_lvt = (Classfile_LVT_Element *) localvariable_table_start[tbl_no];
      for (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 lvt_Hash.
        if (LVT_put_after_lookup(lvt, lvt_Hash) == false
          && _need_verify
          && _major_version >= JAVA_1_5_VERSION ) {
          clear_hashtable(lvt_Hash);
          classfile_parse_error("Duplicated LocalVariableTable attribute "
                                "entry for '%s' in class file %s",
                                 cp->symbol_at(lvt->name_cp_index)->as_utf8(),
                                 CHECK_(nullHandle));
        }
      }
    }

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

    for (tbl_no = 0; tbl_no < lvtt_cnt; tbl_no++) {
      cf_lvtt = (Classfile_LVT_Element *) localvariable_type_table_start[tbl_no];
      for (idx = 0; idx < localvariable_type_table_length[tbl_no]; idx++) {
        copy_lvt_element(&cf_lvtt[idx], &lvtt_elem);
        int index = hash(&lvtt_elem);
        LVT_Hash* entry = LVT_lookup(&lvtt_elem, index, lvt_Hash);
        if (entry == NULL) {
          if (_need_verify) {
            clear_hashtable(lvt_Hash);
            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(),
                                   CHECK_(nullHandle));
          }
        } else if (entry->_elem->signature_cp_index != 0 && _need_verify) {
          clear_hashtable(lvt_Hash);
          classfile_parse_error("Duplicated LocalVariableTypeTable attribute "
                                "entry for '%s' in class file %s",
                                 cp->symbol_at(lvtt_elem.name_cp_index)->as_utf8(),
                                 CHECK_(nullHandle));
        } else {
          // to add generic signatures into LocalVariableTable
          entry->_elem->signature_cp_index = lvtt_elem.descriptor_cp_index;
        }
      }
    }
    clear_hashtable(lvt_Hash);
  }

  *method_annotations = assemble_annotations(runtime_visible_annotations,
                                             runtime_visible_annotations_length,
                                             runtime_invisible_annotations,
                                             runtime_invisible_annotations_length,
                                             CHECK_(nullHandle));
  *method_parameter_annotations = assemble_annotations(runtime_visible_parameter_annotations,
                                                       runtime_visible_parameter_annotations_length,
                                                       runtime_invisible_parameter_annotations,
                                                       runtime_invisible_parameter_annotations_length,
                                                       CHECK_(nullHandle));
  *method_default_annotations = assemble_annotations(annotation_default,
                                                     annotation_default_length,
                                                     NULL,
                                                     0,
                                                     CHECK_(nullHandle));

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

  if (EnableInvokeDynamic && (m->is_method_handle_invoke() ||
                              m->is_method_handle_adapter())) {
    THROW_MSG_(vmSymbols::java_lang_VirtualMachineError(),
               "Method handle invokers must be defined internally to the VM", nullHandle);
  }

  return m;
}


// The promoted_flags parameter is used to pass relevant access_flags
// from the methods back up to the containing klass. These flag values
// are added to klass's access_flags.

objArrayHandle ClassFileParser::parse_methods(constantPoolHandle cp, bool is_interface,
                                              AccessFlags* promoted_flags,
                                              bool* has_final_method,
                                              objArrayOop* methods_annotations_oop,
                                              objArrayOop* methods_parameter_annotations_oop,
                                              objArrayOop* methods_default_annotations_oop,
                                              TRAPS) {
  ClassFileStream* cfs = stream();
  objArrayHandle nullHandle;
  typeArrayHandle method_annotations;
  typeArrayHandle method_parameter_annotations;
  typeArrayHandle method_default_annotations;
  cfs->guarantee_more(2, CHECK_(nullHandle));  // length
  u2 length = cfs->get_u2_fast();
  if (length == 0) {
    return objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
  } else {
    objArrayOop m = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
    objArrayHandle methods(THREAD, m);
    HandleMark hm(THREAD);
    objArrayHandle methods_annotations;
    objArrayHandle methods_parameter_annotations;
    objArrayHandle methods_default_annotations;
    for (int index = 0; index < length; index++) {
      methodHandle method = parse_method(cp, is_interface,
                                         promoted_flags,
                                         &method_annotations,
                                         &method_parameter_annotations,
                                         &method_default_annotations,
                                         CHECK_(nullHandle));
      if (method->is_final()) {
        *has_final_method = true;
      }
      methods->obj_at_put(index, method());
      if (method_annotations.not_null()) {
        if (methods_annotations.is_null()) {
          objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
          methods_annotations = objArrayHandle(THREAD, md);
        }
        methods_annotations->obj_at_put(index, method_annotations());
      }
      if (method_parameter_annotations.not_null()) {
        if (methods_parameter_annotations.is_null()) {
          objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
          methods_parameter_annotations = objArrayHandle(THREAD, md);
        }
        methods_parameter_annotations->obj_at_put(index, method_parameter_annotations());
      }
      if (method_default_annotations.not_null()) {
        if (methods_default_annotations.is_null()) {
          objArrayOop md = oopFactory::new_system_objArray(length, CHECK_(nullHandle));
          methods_default_annotations = objArrayHandle(THREAD, md);
        }
        methods_default_annotations->obj_at_put(index, method_default_annotations());
      }
    }
    if (_need_verify && length > 1) {
      // Check duplicated methods
      ResourceMark rm(THREAD);
      NameSigHash** names_and_sigs = NEW_RESOURCE_ARRAY_IN_THREAD(
        THREAD, NameSigHash*, HASH_ROW_SIZE);
      initialize_hashtable(names_and_sigs);
      bool dup = false;
      {
        debug_only(No_Safepoint_Verifier nsv;)
        for (int i = 0; i < length; i++) {
          methodOop m = (methodOop)methods->obj_at(i);
          // If no duplicates, add name/signature in hashtable names_and_sigs.
          if (!put_after_lookup(m->name(), m->signature(), names_and_sigs)) {
            dup = true;
            break;
          }
        }
      }
      if (dup) {
        classfile_parse_error("Duplicate method name&signature in class file %s",
                              CHECK_(nullHandle));
      }
    }

    *methods_annotations_oop = methods_annotations();
    *methods_parameter_annotations_oop = methods_parameter_annotations();
    *methods_default_annotations_oop = methods_default_annotations();

    return methods;
  }
}


typeArrayHandle ClassFileParser::sort_methods(objArrayHandle methods,
                                              objArrayHandle methods_annotations,
                                              objArrayHandle methods_parameter_annotations,
                                              objArrayHandle methods_default_annotations,
                                              TRAPS) {
  typeArrayHandle nullHandle;
  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 methodOop 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() || DumpSharedSpaces) {
    for (int index = 0; index < length; index++) {
      methodOop m = methodOop(methods->obj_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
  methodOopDesc::sort_methods(methods(),
                              methods_annotations(),
                              methods_parameter_annotations(),
                              methods_default_annotations());

  // If JVMTI original method ordering or sharing is enabled construct int
  // array remembering the original ordering
  if (JvmtiExport::can_maintain_original_method_order() || DumpSharedSpaces) {
    typeArrayOop new_ordering = oopFactory::new_permanent_intArray(length, CHECK_(nullHandle));
    typeArrayHandle method_ordering(THREAD, new_ordering);
    for (int index = 0; index < length; index++) {
      methodOop m = methodOop(methods->obj_at(index));
      int old_index = m->vtable_index();
      assert(old_index >= 0 && old_index < length, "invalid method index");
      method_ordering->int_at_put(index, old_index);
      m->set_vtable_index(methodOopDesc::invalid_vtable_index);
    }
    return method_ordering;
  } else {
    return typeArrayHandle(THREAD, Universe::the_empty_int_array());
  }
}


void ClassFileParser::parse_classfile_sourcefile_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
  ClassFileStream* cfs = stream();
  cfs->guarantee_more(2, CHECK);  // sourcefile_index
  u2 sourcefile_index = cfs->get_u2_fast();
  check_property(
    valid_cp_range(sourcefile_index, cp->length()) &&
      cp->tag_at(sourcefile_index).is_utf8(),
    "Invalid SourceFile attribute at constant pool index %u in class file %s",
    sourcefile_index, CHECK);
  k->set_source_file_name(cp->symbol_at(sourcefile_index));
}



void ClassFileParser::parse_classfile_source_debug_extension_attribute(constantPoolHandle cp,
                                                                       instanceKlassHandle k,
                                                                       int length, TRAPS) {
  ClassFileStream* cfs = stream();
  u1* sde_buffer = cfs->get_u1_buffer();
  assert(sde_buffer != NULL, "null sde buffer");

  // Don't bother storing it if there is no way to retrieve it
  if (JvmtiExport::can_get_source_debug_extension()) {
    // Optimistically assume that only 1 byte UTF format is used
    // (common case)
    TempNewSymbol sde_symbol = SymbolTable::new_symbol((const char*)sde_buffer, length, CHECK);
    k->set_source_debug_extension(sde_symbol);
    // Note that set_source_debug_extension() increments the reference count
    // for its copy of the Symbol*, so use a TempNewSymbol here.
  }
  // 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)

// Return number of classes in the inner classes attribute table
u2 ClassFileParser::parse_classfile_inner_classes_attribute(u1* inner_classes_attribute_start,
                                                            bool parsed_enclosingmethod_attribute,
                                                            u2 enclosing_method_class_index,
                                                            u2 enclosing_method_method_index,
                                                            constantPoolHandle cp,
                                                            instanceKlassHandle k, TRAPS) {
  ClassFileStream* cfs = stream();
  u1* current_mark = cfs->current();
  u2 length = 0;
  if (inner_classes_attribute_start != NULL) {
    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]
  int size = length * 4 + (parsed_enclosingmethod_attribute ? 2 : 0);
  typeArrayOop ic = oopFactory::new_permanent_shortArray(size, CHECK_0);
  typeArrayHandle inner_classes(THREAD, ic);
  int index = 0;
  int cp_size = cp->length();
  cfs->guarantee_more(8 * length, CHECK_0);  // 4-tuples of u2
  for (int n = 0; n < length; n++) {
    // Inner class index
    u2 inner_class_info_index = cfs->get_u2_fast();
    check_property(
      inner_class_info_index == 0 ||
        (valid_cp_range(inner_class_info_index, cp_size) &&
        is_klass_reference(cp, 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
    u2 outer_class_info_index = cfs->get_u2_fast();
    check_property(
      outer_class_info_index == 0 ||
        (valid_cp_range(outer_class_info_index, cp_size) &&
        is_klass_reference(cp, outer_class_info_index)),
      "outer_class_info_index %u has bad constant type in class file %s",
      outer_class_info_index, CHECK_0);
    // Inner class name
    u2 inner_name_index = cfs->get_u2_fast();
    check_property(
      inner_name_index == 0 || (valid_cp_range(inner_name_index, cp_size) &&
        cp->tag_at(inner_name_index).is_utf8()),
      "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
    AccessFlags inner_access_flags;
    jint 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);
    inner_access_flags.set_flags(flags);

    inner_classes->short_at_put(index++, inner_class_info_index);
    inner_classes->short_at_put(index++, outer_class_info_index);
    inner_classes->short_at_put(index++, inner_name_index);
    inner_classes->short_at_put(index++, inner_access_flags.as_short());
  }

  // 4347400: make sure there's no duplicate entry in the classes array
  if (_need_verify && _major_version >= JAVA_1_5_VERSION) {
    for(int i = 0; i < length * 4; i += 4) {
      for(int j = i + 4; j < length * 4; j += 4) {
        guarantee_property((inner_classes->ushort_at(i)   != inner_classes->ushort_at(j) ||
                            inner_classes->ushort_at(i+1) != inner_classes->ushort_at(j+1) ||
                            inner_classes->ushort_at(i+2) != inner_classes->ushort_at(j+2) ||
                            inner_classes->ushort_at(i+3) != inner_classes->ushort_at(j+3)),
                            "Duplicate entry in InnerClasses in class file %s",
                            CHECK_0);
      }
    }
  }

  // Set EnclosingMethod class and method indexes.
  if (parsed_enclosingmethod_attribute) {
    inner_classes->short_at_put(index++, enclosing_method_class_index);
    inner_classes->short_at_put(index++, enclosing_method_method_index);
  }
  assert(index == size, "wrong size");

  // Update instanceKlass with inner class info.
  k->set_inner_classes(inner_classes());

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

  return length;
}

void ClassFileParser::parse_classfile_synthetic_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
  k->set_is_synthetic();
}

void ClassFileParser::parse_classfile_signature_attribute(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
  ClassFileStream* cfs = stream();
  u2 signature_index = cfs->get_u2(CHECK);
  check_property(
    valid_cp_range(signature_index, cp->length()) &&
      cp->tag_at(signature_index).is_utf8(),
    "Invalid constant pool index %u in Signature attribute in class file %s",
    signature_index, CHECK);
  k->set_generic_signature(cp->symbol_at(signature_index));
}

void ClassFileParser::parse_classfile_bootstrap_methods_attribute(constantPoolHandle cp, instanceKlassHandle k,
                                                                  u4 attribute_byte_length, TRAPS) {
  ClassFileStream* cfs = stream();
  u1* current_start = cfs->current();

  cfs->guarantee_more(2, CHECK);  // length
  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}}
  int operand_count = (attribute_byte_length - sizeof(u2)) / 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.
  int index_size = (attribute_array_length * 2);

  typeArrayOop operands_oop = oopFactory::new_permanent_intArray(index_size + operand_count, CHECK);
  typeArrayHandle operands(THREAD, operands_oop);
  operands_oop = NULL; // tidy

  int operand_fill_index = index_size;
  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.
    assert(constantPoolOopDesc::operand_offset_at(operands(), n) == 0, "");
    constantPoolOopDesc::operand_offset_at_put(operands(), n, operand_fill_index);

    // Read a bootstrap specifier.
    cfs->guarantee_more(sizeof(u2) * 2, CHECK);  // bsm, argc
    u2 bootstrap_method_index = cfs->get_u2_fast();
    u2 argument_count = cfs->get_u2_fast();
    check_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);
    operands->short_at_put(operand_fill_index++, bootstrap_method_index);
    operands->short_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++) {
      u2 argument_index = cfs->get_u2_fast();
      check_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->short_at_put(operand_fill_index++, argument_index);
    }
  }

  assert(operand_fill_index == operands()->length(), "exact fill");
  assert(constantPoolOopDesc::operand_array_length(operands()) == attribute_array_length, "correct decode");

  u1* current_end = cfs->current();
  guarantee_property(current_end == current_start + attribute_byte_length,
                     "Bad length on BootstrapMethods in class file %s",
                     CHECK);

  cp->set_operands(operands());
}


void ClassFileParser::parse_classfile_attributes(constantPoolHandle cp, instanceKlassHandle k, TRAPS) {
  ClassFileStream* cfs = stream();
  // Set inner classes attribute to default sentinel
  k->set_inner_classes(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_enclosingmethod_attribute = false;
  bool parsed_bootstrap_methods_attribute = false;
  u1* runtime_visible_annotations = NULL;
  int runtime_visible_annotations_length = 0;
  u1* runtime_invisible_annotations = NULL;
  int runtime_invisible_annotations_length = 0;
  u1* inner_classes_attribute_start = NULL;
  u4  inner_classes_attribute_length = 0;
  u2  enclosing_method_class_index = 0;
  u2  enclosing_method_method_index = 0;
  // Iterate over attributes
  while (attributes_count--) {
    cfs->guarantee_more(6, CHECK);  // attribute_name_index, attribute_length
    u2 attribute_name_index = cfs->get_u2_fast();
    u4 attribute_length = cfs->get_u4_fast();
    check_property(
      valid_cp_range(attribute_name_index, cp->length()) &&
        cp->tag_at(attribute_name_index).is_utf8(),
      "Attribute name has bad constant pool index %u in class file %s",
      attribute_name_index, CHECK);
    Symbol* 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", CHECK);
      } else {
        parsed_sourcefile_attribute = true;
      }
      parse_classfile_sourcefile_attribute(cp, k, CHECK);
    } else if (tag == vmSymbols::tag_source_debug_extension()) {
      // Check for SourceDebugExtension tag
      parse_classfile_source_debug_extension_attribute(cp, k, (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", CHECK);
      } else {
        parsed_innerclasses_attribute = true;
      }
      inner_classes_attribute_start = cfs->get_u1_buffer();
      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, CHECK);
      }
      parse_classfile_synthetic_attribute(cp, k, CHECK);
    } else if (tag == vmSymbols::tag_deprecated()) {
      // Check for Deprecatd tag - 4276120
      if (attribute_length != 0) {
        classfile_parse_error(
          "Invalid Deprecated classfile attribute length %u in class file %s",
          attribute_length, CHECK);
      }
    } else if (_major_version >= JAVA_1_5_VERSION) {
      if (tag == vmSymbols::tag_signature()) {
        if (attribute_length != 2) {
          classfile_parse_error(
            "Wrong Signature attribute length %u in class file %s",
            attribute_length, CHECK);
        }
        parse_classfile_signature_attribute(cp, k, CHECK);
      } else if (tag == vmSymbols::tag_runtime_visible_annotations()) {
        runtime_visible_annotations_length = attribute_length;
        runtime_visible_annotations = cfs->get_u1_buffer();
        assert(runtime_visible_annotations != NULL, "null visible annotations");
        cfs->skip_u1(runtime_visible_annotations_length, CHECK);
      } else if (PreserveAllAnnotations && tag == vmSymbols::tag_runtime_invisible_annotations()) {
        runtime_invisible_annotations_length = attribute_length;
        runtime_invisible_annotations = cfs->get_u1_buffer();
        assert(runtime_invisible_annotations != NULL, "null invisible annotations");
        cfs->skip_u1(runtime_invisible_annotations_length, CHECK);
      } else if (tag == vmSymbols::tag_enclosing_method()) {
        if (parsed_enclosingmethod_attribute) {
          classfile_parse_error("Multiple EnclosingMethod attributes in class file %s", CHECK);
        }   else {
          parsed_enclosingmethod_attribute = true;
        }
        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", CHECK);
        }
        // Validate the constant pool indices and types
        if (!cp->is_within_bounds(enclosing_method_class_index) ||
            !is_klass_reference(cp, enclosing_method_class_index)) {
          classfile_parse_error("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", CHECK);
        }
      } 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", CHECK);
        parsed_bootstrap_methods_attribute = true;
        parse_classfile_bootstrap_methods_attribute(cp, k, attribute_length, CHECK);
      } else {
        // Unknown attribute
        cfs->skip_u1(attribute_length, CHECK);
      }
    } else {
      // Unknown attribute
      cfs->skip_u1(attribute_length, CHECK);
    }
  }
  typeArrayHandle annotations = assemble_annotations(runtime_visible_annotations,
                                                     runtime_visible_annotations_length,
                                                     runtime_invisible_annotations,
                                                     runtime_invisible_annotations_length,
                                                     CHECK);
  k->set_class_annotations(annotations());

  if (parsed_innerclasses_attribute || parsed_enclosingmethod_attribute) {
    u2 num_of_classes = parse_classfile_inner_classes_attribute(
                            inner_classes_attribute_start,
                            parsed_innerclasses_attribute,
                            enclosing_method_class_index,
                            enclosing_method_method_index,
                            cp, k, 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 (_max_bootstrap_specifier_index >= 0) {
    guarantee_property(parsed_bootstrap_methods_attribute,
                       "Missing BootstrapMethods attribute in class file %s", CHECK);
  }
}


typeArrayHandle ClassFileParser::assemble_annotations(u1* runtime_visible_annotations,
                                                      int runtime_visible_annotations_length,
                                                      u1* runtime_invisible_annotations,
                                                      int runtime_invisible_annotations_length, TRAPS) {
  typeArrayHandle annotations;
  if (runtime_visible_annotations != NULL ||
      runtime_invisible_annotations != NULL) {
    typeArrayOop anno = oopFactory::new_permanent_byteArray(runtime_visible_annotations_length +
                                                            runtime_invisible_annotations_length, CHECK_(annotations));
    annotations = typeArrayHandle(THREAD, anno);
    if (runtime_visible_annotations != NULL) {
      memcpy(annotations->byte_at_addr(0), runtime_visible_annotations, runtime_visible_annotations_length);
    }
    if (runtime_invisible_annotations != NULL) {
      memcpy(annotations->byte_at_addr(runtime_visible_annotations_length), runtime_invisible_annotations, runtime_invisible_annotations_length);
    }
  }
  return annotations;
}


instanceKlassHandle ClassFileParser::parseClassFile(Symbol* name,
                                                    Handle class_loader,
                                                    Handle protection_domain,
                                                    KlassHandle host_klass,
                                                    GrowableArray<Handle>* cp_patches,
                                                    TempNewSymbol& parsed_name,
                                                    bool verify,
                                                    TRAPS) {
  // When a retransformable agent is attached, JVMTI caches the
  // class bytes that existed before the first retransformation.
  // If RedefineClasses() was used before the retransformable
  // agent attached, then the cached class bytes may not be the
  // original class bytes.
  unsigned char *cached_class_file_bytes = NULL;
  jint cached_class_file_length;

  ClassFileStream* cfs = stream();
  // Timing
  assert(THREAD->is_Java_thread(), "must be a JavaThread");
  JavaThread* jt = (JavaThread*) THREAD;

  PerfClassTraceTime ctimer(ClassLoader::perf_class_parse_time(),
                            ClassLoader::perf_class_parse_selftime(),
                            NULL,
                            jt->get_thread_stat()->perf_recursion_counts_addr(),
                            jt->get_thread_stat()->perf_timers_addr(),
                            PerfClassTraceTime::PARSE_CLASS);

  _has_finalizer = _has_empty_finalizer = _has_vanilla_constructor = false;
  _max_bootstrap_specifier_index = -1;

  if (JvmtiExport::should_post_class_file_load_hook()) {
    // Get the cached class file bytes (if any) from the class that
    // is being redefined or retransformed. We use jvmti_thread_state()
    // instead of JvmtiThreadState::state_for(jt) so we don't allocate
    // a JvmtiThreadState any earlier than necessary. This will help
    // avoid the bug described by 7126851.
    JvmtiThreadState *state = jt->jvmti_thread_state();
    if (state != NULL) {
      KlassHandle *h_class_being_redefined =
                     state->get_class_being_redefined();
      if (h_class_being_redefined != NULL) {
        instanceKlassHandle ikh_class_being_redefined =
          instanceKlassHandle(THREAD, (*h_class_being_redefined)());
        cached_class_file_bytes =
          ikh_class_being_redefined->get_cached_class_file_bytes();
        cached_class_file_length =
          ikh_class_being_redefined->get_cached_class_file_len();
      }
    }

    unsigned char* ptr = cfs->buffer();
    unsigned char* end_ptr = cfs->buffer() + cfs->length();

    JvmtiExport::post_class_file_load_hook(name, class_loader, protection_domain,
                                           &ptr, &end_ptr,
                                           &cached_class_file_bytes,
                                           &cached_class_file_length);

    if (ptr != cfs->buffer()) {
      // JVMTI agent has modified class file data.
      // Set new class file stream using JVMTI agent modified
      // class file data.
      cfs = new ClassFileStream(ptr, end_ptr - ptr, cfs->source());
      set_stream(cfs);
    }
  }

  _host_klass = host_klass;
  _cp_patches = cp_patches;

  instanceKlassHandle nullHandle;

  // Figure out whether we can skip format checking (matching classic VM behavior)
  _need_verify = Verifier::should_verify_for(class_loader(), verify);

  // Set the verify flag in stream
  cfs->set_verify(_need_verify);

  // Save the class file name for easier error message printing.
  _class_name = (name != NULL) ? name : vmSymbols::unknown_class_name();

  cfs->guarantee_more(8, CHECK_(nullHandle));  // magic, major, minor
  // Magic value
  u4 magic = cfs->get_u4_fast();
  guarantee_property(magic == JAVA_CLASSFILE_MAGIC,
                     "Incompatible magic value %u in class file %s",
                     magic, CHECK_(nullHandle));

  // Version numbers
  u2 minor_version = cfs->get_u2_fast();
  u2 major_version = cfs->get_u2_fast();

  // Check version numbers - we check this even with verifier off
  if (!is_supported_version(major_version, minor_version)) {
    if (name == NULL) {
      Exceptions::fthrow(
        THREAD_AND_LOCATION,
        vmSymbols::java_lang_UnsupportedClassVersionError(),
        "Unsupported major.minor version %u.%u",
        major_version,
        minor_version);
    } else {
      ResourceMark rm(THREAD);
      Exceptions::fthrow(
        THREAD_AND_LOCATION,
        vmSymbols::java_lang_UnsupportedClassVersionError(),
        "%s : Unsupported major.minor version %u.%u",
        name->as_C_string(),
        major_version,
        minor_version);
    }
    return nullHandle;
  }

  _major_version = major_version;
  _minor_version = minor_version;


  // Check if verification needs to be relaxed for this class file
  // Do not restrict it to jdk1.0 or jdk1.1 to maintain backward compatibility (4982376)
  _relax_verify = Verifier::relax_verify_for(class_loader());

  // Constant pool
  constantPoolHandle cp = parse_constant_pool(CHECK_(nullHandle));
  ConstantPoolCleaner error_handler(cp); // set constant pool to be cleaned up.

  int cp_size = cp->length();

  cfs->guarantee_more(8, CHECK_(nullHandle));  // flags, this_class, super_class, infs_len

  // Access flags
  AccessFlags access_flags;
  jint flags = cfs->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_(nullHandle));
  access_flags.set_flags(flags);

  // This class and superclass
  instanceKlassHandle super_klass;
  u2 this_class_index = cfs->get_u2_fast();
  check_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_(nullHandle));

  Symbol*  class_name  = cp->unresolved_klass_at(this_class_index);
  assert(class_name != NULL, "class_name can't be null");

  // It's important to set parsed_name *before* resolving the super class.
  // (it's used for cleanup by the caller if parsing fails)
  parsed_name = class_name;
  // parsed_name is returned and can be used if there's an error, so add to
  // its reference count.  Caller will decrement the refcount.
  parsed_name->increment_refcount();

  // Update _class_name which could be null previously to be class_name
  _class_name = class_name;

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

  klassOop preserve_this_klass;   // for storing result across HandleMark

  // release all handles when parsing is done
  { HandleMark hm(THREAD);

    // Checks if name in class file matches requested name
    if (name != NULL && class_name != name) {
      ResourceMark rm(THREAD);
      Exceptions::fthrow(
        THREAD_AND_LOCATION,
        vmSymbols::java_lang_NoClassDefFoundError(),
        "%s (wrong name: %s)",
        name->as_C_string(),
        class_name->as_C_string()
      );
      return nullHandle;
    }

    if (TraceClassLoadingPreorder) {
      tty->print("[Loading %s", name->as_klass_external_name());
      if (cfs->source() != NULL) tty->print(" from %s", cfs->source());
      tty->print_cr("]");
    }

    u2 super_class_index = cfs->get_u2_fast();
    if (super_class_index == 0) {
      check_property(class_name == vmSymbols::java_lang_Object(),
                     "Invalid superclass index %u in class file %s",
                     super_class_index,
                     CHECK_(nullHandle));
    } else {
      check_property(valid_cp_range(super_class_index, cp_size) &&
                     is_klass_reference(cp, super_class_index),
                     "Invalid superclass index %u in class file %s",
                     super_class_index,
                     CHECK_(nullHandle));
      // 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 = instanceKlassHandle(THREAD, cp->resolved_klass_at(super_class_index));
        if (_need_verify)
          is_array = super_klass->oop_is_array();
      } else if (_need_verify) {
        is_array = (cp->unresolved_klass_at(super_class_index)->byte_at(0) == JVM_SIGNATURE_ARRAY);
      }
      if (_need_verify) {
        guarantee_property(!is_array,
                          "Bad superclass name in class file %s", CHECK_(nullHandle));
      }
    }

    // Interfaces
    u2 itfs_len = cfs->get_u2_fast();
    objArrayHandle local_interfaces;
    if (itfs_len == 0) {
      local_interfaces = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
    } else {
      local_interfaces = parse_interfaces(cp, itfs_len, class_loader, protection_domain, _class_name, CHECK_(nullHandle));
    }

    u2 java_fields_count = 0;
    // Fields (offsets are filled in later)
    FieldAllocationCount fac;
    objArrayHandle fields_annotations;
    typeArrayHandle fields = parse_fields(class_name, cp, access_flags.is_interface(), &fac, &fields_annotations,
                                          &java_fields_count,
                                          CHECK_(nullHandle));
    // Methods
    bool has_final_method = false;
    AccessFlags promoted_flags;
    promoted_flags.set_flags(0);
    // These need to be oop pointers because they are allocated lazily
    // inside parse_methods inside a nested HandleMark
    objArrayOop methods_annotations_oop = NULL;
    objArrayOop methods_parameter_annotations_oop = NULL;
    objArrayOop methods_default_annotations_oop = NULL;
    objArrayHandle methods = parse_methods(cp, access_flags.is_interface(),
                                           &promoted_flags,
                                           &has_final_method,
                                           &methods_annotations_oop,
                                           &methods_parameter_annotations_oop,
                                           &methods_default_annotations_oop,
                                           CHECK_(nullHandle));

    objArrayHandle methods_annotations(THREAD, methods_annotations_oop);
    objArrayHandle methods_parameter_annotations(THREAD, methods_parameter_annotations_oop);
    objArrayHandle methods_default_annotations(THREAD, methods_default_annotations_oop);

    // We check super class after class file is parsed and format is checked
    if (super_class_index > 0 && super_klass.is_null()) {
      Symbol*  sk  = 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(sk == vmSymbols::java_lang_Object(),
                           "Interfaces must have java.lang.Object as superclass in class file %s",
                           CHECK_(nullHandle));
      }
      klassOop k = SystemDictionary::resolve_super_or_fail(class_name,
                                                           sk,
                                                           class_loader,
                                                           protection_domain,
                                                           true,
                                                           CHECK_(nullHandle));

      KlassHandle kh (THREAD, k);
      super_klass = instanceKlassHandle(THREAD, kh());
      if (LinkWellKnownClasses)  // my super class is well known to me
        cp->klass_at_put(super_class_index, super_klass()); // eagerly resolve
    }
    if (super_klass.not_null()) {
      if (super_klass->is_interface()) {
        ResourceMark rm(THREAD);
        Exceptions::fthrow(
          THREAD_AND_LOCATION,
          vmSymbols::java_lang_IncompatibleClassChangeError(),
          "class %s has interface %s as super class",
          class_name->as_klass_external_name(),
          super_klass->external_name()
        );
        return nullHandle;
      }
      // Make sure super class is not final
      if (super_klass->is_final()) {
        THROW_MSG_(vmSymbols::java_lang_VerifyError(), "Cannot inherit from final class", nullHandle);
      }
    }

    // Compute the transitive list of all unique interfaces implemented by this class
    objArrayHandle transitive_interfaces = compute_transitive_interfaces(super_klass, local_interfaces, CHECK_(nullHandle));

    // sort methods
    typeArrayHandle method_ordering = sort_methods(methods,
                                                   methods_annotations,
                                                   methods_parameter_annotations,
                                                   methods_default_annotations,
                                                   CHECK_(nullHandle));

    // promote flags from parse_methods() to the klass' flags
    access_flags.add_promoted_flags(promoted_flags.as_int());

    // Size of Java vtable (in words)
    int vtable_size = 0;
    int itable_size = 0;
    int num_miranda_methods = 0;

    klassVtable::compute_vtable_size_and_num_mirandas(vtable_size,
                                                      num_miranda_methods,
                                                      super_klass(),
                                                      methods(),
                                                      access_flags,
                                                      class_loader,
                                                      class_name,
                                                      local_interfaces(),
                                                      CHECK_(nullHandle));

    // Size of Java itable (in words)
    itable_size = access_flags.is_interface() ? 0 : klassItable::compute_itable_size(transitive_interfaces);

    // Field size and offset computation
    int nonstatic_field_size = super_klass() == NULL ? 0 : super_klass->nonstatic_field_size();
#ifndef PRODUCT
    int orig_nonstatic_field_size = 0;
#endif
    int static_field_size = 0;
    int next_static_oop_offset;
    int next_static_double_offset;
    int next_static_word_offset;
    int next_static_short_offset;
    int next_static_byte_offset;
    int next_static_type_offset;
    int next_nonstatic_oop_offset;
    int next_nonstatic_double_offset;
    int next_nonstatic_word_offset;
    int next_nonstatic_short_offset;
    int next_nonstatic_byte_offset;
    int next_nonstatic_type_offset;
    int first_nonstatic_oop_offset;
    int first_nonstatic_field_offset;
    int next_nonstatic_field_offset;

    // Calculate the starting byte offsets
    next_static_oop_offset      = instanceMirrorKlass::offset_of_static_fields();
    next_static_double_offset   = next_static_oop_offset +
                                  (fac.count[STATIC_OOP] * heapOopSize);
    if ( fac.count[STATIC_DOUBLE] &&
         (Universe::field_type_should_be_aligned(T_DOUBLE) ||
          Universe::field_type_should_be_aligned(T_LONG)) ) {
      next_static_double_offset = align_size_up(next_static_double_offset, BytesPerLong);
    }

    next_static_word_offset     = next_static_double_offset +
                                  (fac.count[STATIC_DOUBLE] * BytesPerLong);
    next_static_short_offset    = next_static_word_offset +
                                  (fac.count[STATIC_WORD] * BytesPerInt);
    next_static_byte_offset     = next_static_short_offset +
                                  (fac.count[STATIC_SHORT] * BytesPerShort);
    next_static_type_offset     = align_size_up((next_static_byte_offset +
                                  fac.count[STATIC_BYTE] ), wordSize );
    static_field_size           = (next_static_type_offset -
                                  next_static_oop_offset) / wordSize;

    first_nonstatic_field_offset = instanceOopDesc::base_offset_in_bytes() +
                                   nonstatic_field_size * heapOopSize;
    next_nonstatic_field_offset = first_nonstatic_field_offset;

    unsigned int nonstatic_double_count = fac.count[NONSTATIC_DOUBLE];
    unsigned int nonstatic_word_count   = fac.count[NONSTATIC_WORD];
    unsigned int nonstatic_short_count  = fac.count[NONSTATIC_SHORT];
    unsigned int nonstatic_byte_count   = fac.count[NONSTATIC_BYTE];
    unsigned int nonstatic_oop_count    = fac.count[NONSTATIC_OOP];

    bool super_has_nonstatic_fields =
            (super_klass() != NULL && super_klass->has_nonstatic_fields());
    bool has_nonstatic_fields  =  super_has_nonstatic_fields ||
            ((nonstatic_double_count + nonstatic_word_count +
              nonstatic_short_count + nonstatic_byte_count +
              nonstatic_oop_count) != 0);


    // Prepare list of oops for oop map generation.
    int* nonstatic_oop_offsets;
    unsigned int* nonstatic_oop_counts;
    unsigned int nonstatic_oop_map_count = 0;

    nonstatic_oop_offsets = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, int, nonstatic_oop_count + 1);
    nonstatic_oop_counts  = NEW_RESOURCE_ARRAY_IN_THREAD(
              THREAD, unsigned int, nonstatic_oop_count + 1);

    first_nonstatic_oop_offset = 0; // will be set for first oop field

#ifndef PRODUCT
    if( PrintCompactFieldsSavings ) {
      next_nonstatic_double_offset = next_nonstatic_field_offset +
                                     (nonstatic_oop_count * heapOopSize);
      if ( nonstatic_double_count > 0 ) {
        next_nonstatic_double_offset = align_size_up(next_nonstatic_double_offset, BytesPerLong);
      }
      next_nonstatic_word_offset  = next_nonstatic_double_offset +
                                    (nonstatic_double_count * BytesPerLong);
      next_nonstatic_short_offset = next_nonstatic_word_offset +
                                    (nonstatic_word_count * BytesPerInt);
      next_nonstatic_byte_offset  = next_nonstatic_short_offset +
                                    (nonstatic_short_count * BytesPerShort);
      next_nonstatic_type_offset  = align_size_up((next_nonstatic_byte_offset +
                                    nonstatic_byte_count ), heapOopSize );
      orig_nonstatic_field_size   = nonstatic_field_size +
      ((next_nonstatic_type_offset - first_nonstatic_field_offset)/heapOopSize);
    }
#endif
    bool compact_fields   = CompactFields;
    int  allocation_style = FieldsAllocationStyle;
    if( allocation_style < 0 || allocation_style > 2 ) { // Out of range?
      assert(false, "0 <= FieldsAllocationStyle <= 2");
      allocation_style = 1; // Optimistic
    }

    // The next classes have predefined hard-coded fields offsets
    // (see in JavaClasses::compute_hard_coded_offsets()).
    // Use default fields allocation order for them.
    if( (allocation_style != 0 || compact_fields ) && class_loader.is_null() &&
        (class_name == vmSymbols::java_lang_AssertionStatusDirectives() ||
         class_name == vmSymbols::java_lang_Class() ||
         class_name == vmSymbols::java_lang_ClassLoader() ||
         class_name == vmSymbols::java_lang_ref_Reference() ||
         class_name == vmSymbols::java_lang_ref_SoftReference() ||
         class_name == vmSymbols::java_lang_StackTraceElement() ||
         class_name == vmSymbols::java_lang_String() ||
         class_name == vmSymbols::java_lang_Throwable() ||
         class_name == vmSymbols::java_lang_Boolean() ||
         class_name == vmSymbols::java_lang_Character() ||
         class_name == vmSymbols::java_lang_Float() ||
         class_name == vmSymbols::java_lang_Double() ||
         class_name == vmSymbols::java_lang_Byte() ||
         class_name == vmSymbols::java_lang_Short() ||
         class_name == vmSymbols::java_lang_Integer() ||
         class_name == vmSymbols::java_lang_Long())) {
      allocation_style = 0;     // Allocate oops first
      compact_fields   = false; // Don't compact fields
    }

    if( allocation_style == 0 ) {
      // Fields order: oops, longs/doubles, ints, shorts/chars, bytes
      next_nonstatic_oop_offset    = next_nonstatic_field_offset;
      next_nonstatic_double_offset = next_nonstatic_oop_offset +
                                      (nonstatic_oop_count * heapOopSize);
    } else if( allocation_style == 1 ) {
      // Fields order: longs/doubles, ints, shorts/chars, bytes, oops
      next_nonstatic_double_offset = next_nonstatic_field_offset;
    } else if( allocation_style == 2 ) {
      // Fields allocation: oops fields in super and sub classes are together.
      if( nonstatic_field_size > 0 && super_klass() != NULL &&
          super_klass->nonstatic_oop_map_size() > 0 ) {
        int map_count = super_klass->nonstatic_oop_map_count();
        OopMapBlock* first_map = super_klass->start_of_nonstatic_oop_maps();
        OopMapBlock* last_map = first_map + map_count - 1;
        int next_offset = last_map->offset() + (last_map->count() * heapOopSize);
        if (next_offset == next_nonstatic_field_offset) {
          allocation_style = 0;   // allocate oops first
          next_nonstatic_oop_offset    = next_nonstatic_field_offset;
          next_nonstatic_double_offset = next_nonstatic_oop_offset +
                                         (nonstatic_oop_count * heapOopSize);
        }
      }
      if( allocation_style == 2 ) {
        allocation_style = 1;     // allocate oops last
        next_nonstatic_double_offset = next_nonstatic_field_offset;
      }
    } else {
      ShouldNotReachHere();
    }

    int nonstatic_oop_space_count   = 0;
    int nonstatic_word_space_count  = 0;
    int nonstatic_short_space_count = 0;
    int nonstatic_byte_space_count  = 0;
    int nonstatic_oop_space_offset;
    int nonstatic_word_space_offset;
    int nonstatic_short_space_offset;
    int nonstatic_byte_space_offset;

    if( nonstatic_double_count > 0 ) {
      int offset = next_nonstatic_double_offset;
      next_nonstatic_double_offset = align_size_up(offset, BytesPerLong);
      if( compact_fields && offset != next_nonstatic_double_offset ) {
        // Allocate available fields into the gap before double field.
        int length = next_nonstatic_double_offset - offset;
        assert(length == BytesPerInt, "");
        nonstatic_word_space_offset = offset;
        if( nonstatic_word_count > 0 ) {
          nonstatic_word_count      -= 1;
          nonstatic_word_space_count = 1; // Only one will fit
          length -= BytesPerInt;
          offset += BytesPerInt;
        }
        nonstatic_short_space_offset = offset;
        while( length >= BytesPerShort && nonstatic_short_count > 0 ) {
          nonstatic_short_count       -= 1;
          nonstatic_short_space_count += 1;
          length -= BytesPerShort;
          offset += BytesPerShort;
        }
        nonstatic_byte_space_offset = offset;
        while( length > 0 && nonstatic_byte_count > 0 ) {
          nonstatic_byte_count       -= 1;
          nonstatic_byte_space_count += 1;
          length -= 1;
        }
        // Allocate oop field in the gap if there are no other fields for that.
        nonstatic_oop_space_offset = offset;
        if( length >= heapOopSize && nonstatic_oop_count > 0 &&
            allocation_style != 0 ) { // when oop fields not first
          nonstatic_oop_count      -= 1;
          nonstatic_oop_space_count = 1; // Only one will fit
          length -= heapOopSize;
          offset += heapOopSize;
        }
      }
    }

    next_nonstatic_word_offset  = next_nonstatic_double_offset +
                                  (nonstatic_double_count * BytesPerLong);
    next_nonstatic_short_offset = next_nonstatic_word_offset +
                                  (nonstatic_word_count * BytesPerInt);
    next_nonstatic_byte_offset  = next_nonstatic_short_offset +
                                  (nonstatic_short_count * BytesPerShort);

    int notaligned_offset;
    if( allocation_style == 0 ) {
      notaligned_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
    } else { // allocation_style == 1
      next_nonstatic_oop_offset = next_nonstatic_byte_offset + nonstatic_byte_count;
      if( nonstatic_oop_count > 0 ) {
        next_nonstatic_oop_offset = align_size_up(next_nonstatic_oop_offset, heapOopSize);
      }
      notaligned_offset = next_nonstatic_oop_offset + (nonstatic_oop_count * heapOopSize);
    }
    next_nonstatic_type_offset = align_size_up(notaligned_offset, heapOopSize );
    nonstatic_field_size = nonstatic_field_size + ((next_nonstatic_type_offset
                                   - first_nonstatic_field_offset)/heapOopSize);

    // Iterate over fields again and compute correct offsets.
    // The field allocation type was temporarily stored in the offset slot.
    // oop fields are located before non-oop fields (static and non-static).
    for (AllFieldStream fs(fields, cp); !fs.done(); fs.next()) {
      int real_offset;
      FieldAllocationType atype = (FieldAllocationType) fs.offset();
      switch (atype) {
        case STATIC_OOP:
          real_offset = next_static_oop_offset;
          next_static_oop_offset += heapOopSize;
          break;
        case STATIC_BYTE:
          real_offset = next_static_byte_offset;
          next_static_byte_offset += 1;
          break;
        case STATIC_SHORT:
          real_offset = next_static_short_offset;
          next_static_short_offset += BytesPerShort;
          break;
        case STATIC_WORD:
          real_offset = next_static_word_offset;
          next_static_word_offset += BytesPerInt;
          break;
        case STATIC_DOUBLE:
          real_offset = next_static_double_offset;
          next_static_double_offset += BytesPerLong;
          break;
        case NONSTATIC_OOP:
          if( nonstatic_oop_space_count > 0 ) {
            real_offset = nonstatic_oop_space_offset;
            nonstatic_oop_space_offset += heapOopSize;
            nonstatic_oop_space_count  -= 1;
          } else {
            real_offset = next_nonstatic_oop_offset;
            next_nonstatic_oop_offset += heapOopSize;
          }
          // Update oop maps
          if( nonstatic_oop_map_count > 0 &&
              nonstatic_oop_offsets[nonstatic_oop_map_count - 1] ==
              real_offset -
              int(nonstatic_oop_counts[nonstatic_oop_map_count - 1]) *
              heapOopSize ) {
            // Extend current oop map
            nonstatic_oop_counts[nonstatic_oop_map_count - 1] += 1;
          } else {
            // Create new oop map
            nonstatic_oop_offsets[nonstatic_oop_map_count] = real_offset;
            nonstatic_oop_counts [nonstatic_oop_map_count] = 1;
            nonstatic_oop_map_count += 1;
            if( first_nonstatic_oop_offset == 0 ) { // Undefined
              first_nonstatic_oop_offset = real_offset;
            }
          }
          break;
        case NONSTATIC_BYTE:
          if( nonstatic_byte_space_count > 0 ) {
            real_offset = nonstatic_byte_space_offset;
            nonstatic_byte_space_offset += 1;
            nonstatic_byte_space_count  -= 1;
          } else {
            real_offset = next_nonstatic_byte_offset;
            next_nonstatic_byte_offset += 1;
          }
          break;
        case NONSTATIC_SHORT:
          if( nonstatic_short_space_count > 0 ) {
            real_offset = nonstatic_short_space_offset;
            nonstatic_short_space_offset += BytesPerShort;
            nonstatic_short_space_count  -= 1;
          } else {
            real_offset = next_nonstatic_short_offset;
            next_nonstatic_short_offset += BytesPerShort;
          }
          break;
        case NONSTATIC_WORD:
          if( nonstatic_word_space_count > 0 ) {
            real_offset = nonstatic_word_space_offset;
            nonstatic_word_space_offset += BytesPerInt;
            nonstatic_word_space_count  -= 1;
          } else {
            real_offset = next_nonstatic_word_offset;
            next_nonstatic_word_offset += BytesPerInt;
          }
          break;
        case NONSTATIC_DOUBLE:
          real_offset = next_nonstatic_double_offset;
          next_nonstatic_double_offset += BytesPerLong;
          break;
        default:
          ShouldNotReachHere();
      }
      fs.set_offset(real_offset);
    }

    // Size of instances
    int instance_size;

    next_nonstatic_type_offset = align_size_up(notaligned_offset, wordSize );
    instance_size = align_object_size(next_nonstatic_type_offset / wordSize);

    assert(instance_size == align_object_size(align_size_up((instanceOopDesc::base_offset_in_bytes() + nonstatic_field_size*heapOopSize), wordSize) / wordSize), "consistent layout helper value");

    // Number of non-static oop map blocks allocated at end of klass.
    const unsigned int total_oop_map_count =
      compute_oop_map_count(super_klass, nonstatic_oop_map_count,
                            first_nonstatic_oop_offset);

    // Compute reference type
    ReferenceType rt;
    if (super_klass() == NULL) {
      rt = REF_NONE;
    } else {
      rt = super_klass->reference_type();
    }

    // We can now create the basic klassOop for this klass
    klassOop ik = oopFactory::new_instanceKlass(name, vtable_size, itable_size,
                                                static_field_size,
                                                total_oop_map_count,
                                                rt, CHECK_(nullHandle));
    instanceKlassHandle this_klass (THREAD, ik);

    assert(this_klass->static_field_size() == static_field_size, "sanity");
    assert(this_klass->nonstatic_oop_map_count() == total_oop_map_count,
           "sanity");

    // Fill in information already parsed
    this_klass->set_access_flags(access_flags);
    this_klass->set_should_verify_class(verify);
    jint lh = Klass::instance_layout_helper(instance_size, false);
    this_klass->set_layout_helper(lh);
    assert(this_klass->oop_is_instance(), "layout is correct");
    assert(this_klass->size_helper() == instance_size, "correct size_helper");
    // Not yet: supers are done below to support the new subtype-checking fields
    //this_klass->set_super(super_klass());
    this_klass->set_class_loader(class_loader());
    this_klass->set_nonstatic_field_size(nonstatic_field_size);
    this_klass->set_has_nonstatic_fields(has_nonstatic_fields);
    this_klass->set_static_oop_field_count(fac.count[STATIC_OOP]);
    cp->set_pool_holder(this_klass());
    error_handler.set_in_error(false);   // turn off error handler for cp
    this_klass->set_constants(cp());
    this_klass->set_local_interfaces(local_interfaces());
    this_klass->set_fields(fields(), java_fields_count);
    this_klass->set_methods(methods());
    if (has_final_method) {
      this_klass->set_has_final_method();
    }
    this_klass->set_method_ordering(method_ordering());
    // The instanceKlass::_methods_jmethod_ids cache and the
    // instanceKlass::_methods_cached_itable_indices cache are
    // both 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.
    this_klass->set_initial_method_idnum(methods->length());
    this_klass->set_name(cp->klass_name_at(this_class_index));
    if (LinkWellKnownClasses || is_anonymous())  // I am well known to myself
      cp->klass_at_put(this_class_index, this_klass()); // eagerly resolve
    this_klass->set_protection_domain(protection_domain());
    this_klass->set_fields_annotations(fields_annotations());
    this_klass->set_methods_annotations(methods_annotations());
    this_klass->set_methods_parameter_annotations(methods_parameter_annotations());
    this_klass->set_methods_default_annotations(methods_default_annotations());

    this_klass->set_minor_version(minor_version);
    this_klass->set_major_version(major_version);

    // Set up methodOop::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.)
    if (methodOopDesc::klass_id_for_intrinsics(this_klass->as_klassOop()) != vmSymbols::NO_SID) {
      for (int j = 0; j < methods->length(); j++) {
        ((methodOop)methods->obj_at(j))->init_intrinsic_id();
      }
    }

    if (cached_class_file_bytes != NULL) {
      // JVMTI: we have an instanceKlass now, tell it about the cached bytes
      this_klass->set_cached_class_file(cached_class_file_bytes,
                                        cached_class_file_length);
    }

    // Miranda methods
    if ((num_miranda_methods > 0) ||
        // if this class introduced new miranda methods or
        (super_klass.not_null() && (super_klass->has_miranda_methods()))
        // super class exists and this class inherited miranda methods
        ) {
      this_klass->set_has_miranda_methods(); // then set a flag
    }

    // Additional attributes
    parse_classfile_attributes(cp, this_klass, CHECK_(nullHandle));

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

    // VerifyOops believes that once this has been set, the object is completely loaded.
    // Compute transitive closure of interfaces this class implements
    this_klass->set_transitive_interfaces(transitive_interfaces());

    // Fill in information needed to compute superclasses.
    this_klass->initialize_supers(super_klass(), CHECK_(nullHandle));

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

    // Do final class setup
    fill_oop_maps(this_klass, nonstatic_oop_map_count, nonstatic_oop_offsets, nonstatic_oop_counts);

    set_precomputed_flags(this_klass);

    // reinitialize modifiers, using the InnerClasses attribute
    int computed_modifiers = this_klass->compute_modifier_flags(CHECK_(nullHandle));
    this_klass->set_modifier_flags(computed_modifiers);

    // check if this class can access its super class
    check_super_class_access(this_klass, CHECK_(nullHandle));

    // check if this class can access its superinterfaces
    check_super_interface_access(this_klass, CHECK_(nullHandle));

    // check if this class overrides any final method
    check_final_method_override(this_klass, CHECK_(nullHandle));

    // check that if this class is an interface then it doesn't have static methods
    if (this_klass->is_interface()) {
      check_illegal_static_method(this_klass, CHECK_(nullHandle));
    }

    // Allocate mirror and initialize static fields
    java_lang_Class::create_mirror(this_klass, CHECK_(nullHandle));

    ClassLoadingService::notify_class_loaded(instanceKlass::cast(this_klass()),
                                             false /* not shared class */);

    if (TraceClassLoading) {
      // print in a single call to reduce interleaving of output
      if (cfs->source() != NULL) {
        tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
                   cfs->source());
      } else if (class_loader.is_null()) {
        if (THREAD->is_Java_thread()) {
          klassOop caller = ((JavaThread*)THREAD)->security_get_caller_class(1);
          tty->print("[Loaded %s by instance of %s]\n",
                     this_klass->external_name(),
                     instanceKlass::cast(caller)->external_name());
        } else {
          tty->print("[Loaded %s]\n", this_klass->external_name());
        }
      } else {
        ResourceMark rm;
        tty->print("[Loaded %s from %s]\n", this_klass->external_name(),
                   instanceKlass::cast(class_loader->klass())->external_name());
      }
    }

    if (TraceClassResolution) {
      // print out the superclass.
      const char * from = Klass::cast(this_klass())->external_name();
      if (this_klass->java_super() != NULL) {
        tty->print("RESOLVE %s %s (super)\n", from, instanceKlass::cast(this_klass->java_super())->external_name());
      }
      // print out each of the interface classes referred to by this class.
      objArrayHandle local_interfaces(THREAD, this_klass->local_interfaces());
      if (!local_interfaces.is_null()) {
        int length = local_interfaces->length();
        for (int i = 0; i < length; i++) {
          klassOop k = klassOop(local_interfaces->obj_at(i));
          instanceKlass* to_class = instanceKlass::cast(k);
          const char * to = to_class->external_name();
          tty->print("RESOLVE %s %s (interface)\n", from, to);
        }
      }
    }

#ifndef PRODUCT
    if( PrintCompactFieldsSavings ) {
      if( nonstatic_field_size < orig_nonstatic_field_size ) {
        tty->print("[Saved %d of %d bytes in %s]\n",
                 (orig_nonstatic_field_size - nonstatic_field_size)*heapOopSize,
                 orig_nonstatic_field_size*heapOopSize,
                 this_klass->external_name());
      } else if( nonstatic_field_size > orig_nonstatic_field_size ) {
        tty->print("[Wasted %d over %d bytes in %s]\n",
                 (nonstatic_field_size - orig_nonstatic_field_size)*heapOopSize,
                 orig_nonstatic_field_size*heapOopSize,
                 this_klass->external_name());
      }
    }
#endif

    // preserve result across HandleMark
    preserve_this_klass = this_klass();
  }

  // Create new handle outside HandleMark
  instanceKlassHandle this_klass (THREAD, preserve_this_klass);
  debug_only(this_klass->as_klassOop()->verify();)

  return this_klass;
}


unsigned int
ClassFileParser::compute_oop_map_count(instanceKlassHandle super,
                                       unsigned int nonstatic_oop_map_count,
                                       int first_nonstatic_oop_offset) {
  unsigned int map_count =
    super.is_null() ? 0 : super->nonstatic_oop_map_count();
  if (nonstatic_oop_map_count > 0) {
    // We have oops to add to map
    if (map_count == 0) {
      map_count = nonstatic_oop_map_count;
    } else {
      // Check whether we should add a new map block or whether the last one can
      // be extended
      OopMapBlock* const first_map = super->start_of_nonstatic_oop_maps();
      OopMapBlock* const last_map = first_map + map_count - 1;

      int next_offset = last_map->offset() + last_map->count() * heapOopSize;
      if (next_offset == first_nonstatic_oop_offset) {
        // There is no gap bettwen superklass's last oop field and first
        // local oop field, merge maps.
        nonstatic_oop_map_count -= 1;
      } else {
        // Superklass didn't end with a oop field, add extra maps
        assert(next_offset < first_nonstatic_oop_offset, "just checking");
      }
      map_count += nonstatic_oop_map_count;
    }
  }
  return map_count;
}


void ClassFileParser::fill_oop_maps(instanceKlassHandle k,
                                    unsigned int nonstatic_oop_map_count,
                                    int* nonstatic_oop_offsets,
                                    unsigned int* nonstatic_oop_counts) {
  OopMapBlock* this_oop_map = k->start_of_nonstatic_oop_maps();
  const instanceKlass* const super = k->superklass();
  const unsigned int super_count = super ? super->nonstatic_oop_map_count() : 0;
  if (super_count > 0) {
    // Copy maps from superklass
    OopMapBlock* super_oop_map = super->start_of_nonstatic_oop_maps();
    for (unsigned int i = 0; i < super_count; ++i) {
      *this_oop_map++ = *super_oop_map++;
    }
  }

  if (nonstatic_oop_map_count > 0) {
    if (super_count + nonstatic_oop_map_count > k->nonstatic_oop_map_count()) {
      // The counts differ because there is no gap between superklass's last oop
      // field and the first local oop field.  Extend the last oop map copied
      // from the superklass instead of creating new one.
      nonstatic_oop_map_count--;
      nonstatic_oop_offsets++;
      this_oop_map--;
      this_oop_map->set_count(this_oop_map->count() + *nonstatic_oop_counts++);
      this_oop_map++;
    }

    // Add new map blocks, fill them
    while (nonstatic_oop_map_count-- > 0) {
      this_oop_map->set_offset(*nonstatic_oop_offsets++);
      this_oop_map->set_count(*nonstatic_oop_counts++);
      this_oop_map++;
    }
    assert(k->start_of_nonstatic_oop_maps() + k->nonstatic_oop_map_count() ==
           this_oop_map, "sanity");
  }
}


void ClassFileParser::set_precomputed_flags(instanceKlassHandle k) {
  klassOop super = k->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 != NULL && super->klass_part()->has_finalizer())) {
      k->set_has_finalizer();
    }
  }

#ifdef ASSERT
  bool f = false;
  methodOop m = k->lookup_method(vmSymbols::finalize_method_name(),
                                 vmSymbols::void_method_signature());
  if (m != NULL && !m->is_empty_method()) {
    f = true;
  }
  assert(f == k->has_finalizer(), "inconsistent has_finalizer");
#endif

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

  // Check if this klass has a vanilla default constructor
  if (super == NULL) {
    // java.lang.Object has empty default constructor
    k->set_has_vanilla_constructor();
  } else {
    if (Klass::cast(super)->has_vanilla_constructor() &&
        _has_vanilla_constructor) {
      k->set_has_vanilla_constructor();
    }
#ifdef ASSERT
    bool v = false;
    if (Klass::cast(super)->has_vanilla_constructor()) {
      methodOop constructor = k->find_method(vmSymbols::object_initializer_name(
), vmSymbols::void_method_signature());
      if (constructor != NULL && constructor->is_vanilla_constructor()) {
        v = true;
      }
    }
    assert(v == k->has_vanilla_constructor(), "inconsistent has_vanilla_constructor");
#endif
  }

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


// utility method for appending and array with check for duplicates

void append_interfaces(objArrayHandle result, int& index, objArrayOop ifs) {
  // iterate over new interfaces
  for (int i = 0; i < ifs->length(); i++) {
    oop e = ifs->obj_at(i);
    assert(e->is_klass() && instanceKlass::cast(klassOop(e))->is_interface(), "just checking");
    // check for duplicates
    bool duplicate = false;
    for (int j = 0; j < index; j++) {
      if (result->obj_at(j) == e) {
        duplicate = true;
        break;
      }
    }
    // add new interface
    if (!duplicate) {
      result->obj_at_put(index++, e);
    }
  }
}

objArrayHandle ClassFileParser::compute_transitive_interfaces(instanceKlassHandle super, objArrayHandle local_ifs, TRAPS) {
  // Compute maximum size for transitive interfaces
  int max_transitive_size = 0;
  int super_size = 0;
  // Add superclass transitive interfaces size
  if (super.not_null()) {
    super_size = super->transitive_interfaces()->length();
    max_transitive_size += super_size;
  }
  // Add local interfaces' super interfaces
  int local_size = local_ifs->length();
  for (int i = 0; i < local_size; i++) {
    klassOop l = klassOop(local_ifs->obj_at(i));
    max_transitive_size += instanceKlass::cast(l)->transitive_interfaces()->length();
  }
  // Finally add local interfaces
  max_transitive_size += local_size;
  // Construct array
  objArrayHandle result;
  if (max_transitive_size == 0) {
    // no interfaces, use canonicalized array
    result = objArrayHandle(THREAD, Universe::the_empty_system_obj_array());
  } else if (max_transitive_size == super_size) {
    // no new local interfaces added, share superklass' transitive interface array
    result = objArrayHandle(THREAD, super->transitive_interfaces());
  } else if (max_transitive_size == local_size) {
    // only local interfaces added, share local interface array
    result = local_ifs;
  } else {
    objArrayHandle nullHandle;
    objArrayOop new_objarray = oopFactory::new_system_objArray(max_transitive_size, CHECK_(nullHandle));
    result = objArrayHandle(THREAD, new_objarray);
    int index = 0;
    // Copy down from superclass
    if (super.not_null()) {
      append_interfaces(result, index, super->transitive_interfaces());
    }
    // Copy down from local interfaces' superinterfaces
    for (int i = 0; i < local_ifs->length(); i++) {
      klassOop l = klassOop(local_ifs->obj_at(i));
      append_interfaces(result, index, instanceKlass::cast(l)->transitive_interfaces());
    }
    // Finally add local interfaces
    append_interfaces(result, index, local_ifs());

    // Check if duplicates were removed
    if (index != max_transitive_size) {
      assert(index < max_transitive_size, "just checking");
      objArrayOop new_result = oopFactory::new_system_objArray(index, CHECK_(nullHandle));
      for (int i = 0; i < index; i++) {
        oop e = result->obj_at(i);
        assert(e != NULL, "just checking");
        new_result->obj_at_put(i, e);
      }
      result = objArrayHandle(THREAD, new_result);
    }
  }
  return result;
}


void ClassFileParser::check_super_class_access(instanceKlassHandle this_klass, TRAPS) {
  klassOop super = this_klass->super();
  if ((super != NULL) &&
      (!Reflection::verify_class_access(this_klass->as_klassOop(), super, false))) {
    ResourceMark rm(THREAD);
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_IllegalAccessError(),
      "class %s cannot access its superclass %s",
      this_klass->external_name(),
      instanceKlass::cast(super)->external_name()
    );
    return;
  }
}


void ClassFileParser::check_super_interface_access(instanceKlassHandle this_klass, TRAPS) {
  objArrayHandle local_interfaces (THREAD, this_klass->local_interfaces());
  int lng = local_interfaces->length();
  for (int i = lng - 1; i >= 0; i--) {
    klassOop k = klassOop(local_interfaces->obj_at(i));
    assert (k != NULL && Klass::cast(k)->is_interface(), "invalid interface");
    if (!Reflection::verify_class_access(this_klass->as_klassOop(), k, false)) {
      ResourceMark rm(THREAD);
      Exceptions::fthrow(
        THREAD_AND_LOCATION,
        vmSymbols::java_lang_IllegalAccessError(),
        "class %s cannot access its superinterface %s",
        this_klass->external_name(),
        instanceKlass::cast(k)->external_name()
      );
      return;
    }
  }
}


void ClassFileParser::check_final_method_override(instanceKlassHandle this_klass, TRAPS) {
  objArrayHandle methods (THREAD, this_klass->methods());
  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++) {
    methodOop m = (methodOop)methods->obj_at(index);

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

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

          if (super_m->is_final() &&
              // matching method in super is final
              (Reflection::verify_field_access(this_klass->as_klassOop(),
                                               super_m->method_holder(),
                                               super_m->method_holder(),
                                               super_m->access_flags(), false))
            // this class can access super final method and therefore override
            ) {
            ResourceMark rm(THREAD);
            Exceptions::fthrow(
              THREAD_AND_LOCATION,
              vmSymbols::java_lang_VerifyError(),
              "class %s overrides final method %s.%s",
              this_klass->external_name(),
              name->as_C_string(),
              signature->as_C_string()
            );
            return;
          }

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

        k = k->klass_part()->super();
      }
    }
  }
}


// assumes that this_klass is an interface
void ClassFileParser::check_illegal_static_method(instanceKlassHandle this_klass, TRAPS) {
  assert(this_klass->is_interface(), "not an interface");
  objArrayHandle methods (THREAD, this_klass->methods());
  int num_methods = methods->length();

  for (int index = 0; index < num_methods; index++) {
    methodOop m = (methodOop)methods->obj_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);
      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) {
  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_15  = _major_version >= JAVA_1_5_VERSION;

  if ((is_abstract && is_final) ||
      (is_interface && !is_abstract) ||
      (is_interface && major_gte_15 && (is_super || is_enum)) ||
      (!is_interface && major_gte_15 && is_annotation)) {
    ResourceMark rm(THREAD);
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Illegal class modifiers in class %s: 0x%X",
      _class_name->as_C_string(), flags
    );
    return;
  }
}

bool ClassFileParser::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));
}

bool ClassFileParser::is_supported_version(u2 major, u2 minor) {
  u2 max_version =
    JDK_Version::is_gte_jdk17x_version() ? JAVA_MAX_SUPPORTED_VERSION :
    (JDK_Version::is_gte_jdk16x_version() ? JAVA_6_VERSION : JAVA_1_5_VERSION);
  return (major >= JAVA_MIN_SUPPORTED_VERSION) &&
         (major <= max_version) &&
         ((major != max_version) ||
          (minor <= JAVA_MAX_SUPPORTED_MINOR_VERSION));
}

void ClassFileParser::verify_legal_field_modifiers(
    jint flags, bool is_interface, TRAPS) {
  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_15 = _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_15 && 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);
    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, Symbol* name, TRAPS) {
  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 major_gte_15    = _major_version >= JAVA_1_5_VERSION;
  const bool is_initializer  = (name == vmSymbols::object_initializer_name());

  bool is_illegal = false;

  if (is_interface) {
    if (!is_abstract || !is_public || is_static || is_final ||
        is_native || (major_gte_15 && (is_synchronized || is_strict))) {
      is_illegal = true;
    }
  } else { // not interface
    if (is_initializer) {
      if (is_static || is_final || is_synchronized || is_native ||
          is_abstract || (major_gte_15 && is_bridge)) {
        is_illegal = true;
      }
    } else { // not initializer
      if (is_abstract) {
        if ((is_final || is_native || is_private || is_static ||
            (major_gte_15 && (is_synchronized || is_strict)))) {
          is_illegal = true;
        }
      }
      if (has_illegal_visibility(flags)) {
        is_illegal = true;
      }
    }
  }

  if (is_illegal) {
    ResourceMark rm(THREAD);
    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) {
  assert(_need_verify, "only called when _need_verify is true");
  int i = 0;
  int count = length >> 2;
  for (int k=0; k<count; k++) {
    unsigned char b0 = buffer[i];
    unsigned char b1 = buffer[i+1];
    unsigned char b2 = buffer[i+2];
    unsigned char b3 = buffer[i+3];
    // For an unsigned char v,
    // (v | v - 1) is < 128 (highest bit 0) for 0 < v < 128;
    // (v | v - 1) is >= 128 (highest bit 1) for v == 0 or v >= 128.
    unsigned char res = b0 | b0 - 1 |
                        b1 | b1 - 1 |
                        b2 | b2 - 1 |
                        b3 | b3 - 1;
    if (res >= 128) break;
    i += 4;
  }
  for(; i < length; i++) {
    unsigned short c;
    // no embedded zeros
    guarantee_property((buffer[i] != 0), "Illegal UTF8 string in constant pool in class file %s", CHECK);
    if(buffer[i] < 128) {
      continue;
    }
    if ((i + 5) < length) { // see if it's legal supplementary character
      if (UTF8::is_supplementary_character(&buffer[i])) {
        c = UTF8::get_supplementary_character(&buffer[i]);
        i += 5;
        continue;
      }
    }
    switch (buffer[i] >> 4) {
      default: break;
      case 0x8: case 0x9: case 0xA: case 0xB: case 0xF:
        classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK);
      case 0xC: case 0xD:  // 110xxxxx  10xxxxxx
        c = (buffer[i] & 0x1F) << 6;
        i++;
        if ((i < length) && ((buffer[i] & 0xC0) == 0x80)) {
          c += buffer[i] & 0x3F;
          if (_major_version <= 47 || c == 0 || c >= 0x80) {
            // for classes with major > 47, c must a null or a character in its shortest form
            break;
          }
        }
        classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK);
      case 0xE:  // 1110xxxx 10xxxxxx 10xxxxxx
        c = (buffer[i] & 0xF) << 12;
        i += 2;
        if ((i < length) && ((buffer[i-1] & 0xC0) == 0x80) && ((buffer[i] & 0xC0) == 0x80)) {
          c += ((buffer[i-1] & 0x3F) << 6) + (buffer[i] & 0x3F);
          if (_major_version <= 47 || c >= 0x800) {
            // for classes with major > 47, c must be in its shortest form
            break;
          }
        }
        classfile_parse_error("Illegal UTF8 string in constant pool in class file %s", CHECK);
    }  // end of switch
  } // end of for
}

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

  char buf[fixed_buffer_size];
  char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
  unsigned int length = name->utf8_length();
  bool legal = false;

  if (length > 0) {
    char* p;
    if (bytes[0] == JVM_SIGNATURE_ARRAY) {
      p = skip_over_field_signature(bytes, false, length, CHECK);
      legal = (p != NULL) && ((p - bytes) == (int)length);
    } else if (_major_version < JAVA_1_5_VERSION) {
      if (bytes[0] != '<') {
        p = skip_over_field_name(bytes, true, length);
        legal = (p != NULL) && ((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);
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Illegal class name \"%s\" in class file %s", bytes,
      _class_name->as_C_string()
    );
    return;
  }
}

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

  char buf[fixed_buffer_size];
  char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
  unsigned int length = name->utf8_length();
  bool legal = false;

  if (length > 0) {
    if (_major_version < JAVA_1_5_VERSION) {
      if (bytes[0] != '<') {
        char* p = skip_over_field_name(bytes, false, length);
        legal = (p != NULL) && ((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);
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Illegal field name \"%s\" in class %s", bytes,
      _class_name->as_C_string()
    );
    return;
  }
}

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

  assert(name != NULL, "method name is null");
  char buf[fixed_buffer_size];
  char* bytes = name->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
  unsigned int length = name->utf8_length();
  bool legal = false;

  if (length > 0) {
    if (bytes[0] == '<') {
      if (name == vmSymbols::object_initializer_name() || name == vmSymbols::class_initializer_name()) {
        legal = true;
      }
    } else if (_major_version < JAVA_1_5_VERSION) {
      char* p;
      p = skip_over_field_name(bytes, false, length);
      legal = (p != NULL) && ((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);
    Exceptions::fthrow(
      THREAD_AND_LOCATION,
      vmSymbols::java_lang_ClassFormatError(),
      "Illegal method name \"%s\" in class %s", bytes,
      _class_name->as_C_string()
    );
    return;
  }
}


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

  char buf[fixed_buffer_size];
  char* bytes = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
  unsigned int length = signature->utf8_length();
  char* p = skip_over_field_signature(bytes, false, length, CHECK);

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

// Checks if signature is a legal method signature.
// Returns number of parameters
int ClassFileParser::verify_legal_method_signature(Symbol* name, Symbol* signature, TRAPS) {
  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;
  char buf[fixed_buffer_size];
  char* p = signature->as_utf8_flexible_buffer(THREAD, buf, fixed_buffer_size);
  unsigned int length = signature->utf8_length();
  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 != NULL)) {
      args_size++;
      if (p[0] == 'J' || p[0] == 'D') {
        args_size++;
      }
      length -= 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--;
      if (name->utf8_length() > 0 && name->byte_at(0) == '<') {
        // All internal methods must return void
        if ((length == 1) && (p[0] == JVM_SIGNATURE_VOID)) {
          return args_size;
        }
      } else {
        // 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, CHECK_0);
  return 0;
}


// Unqualified names may not contain the characters '.', ';', '[', or '/'.
// 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.
bool ClassFileParser::verify_unqualified_name(
    char* name, unsigned int length, int type) {
  jchar ch;

  for (char* p = name; p != name + length; ) {
    ch = *p;
    if (ch < 128) {
      p++;
      if (ch == '.' || ch == ';' || ch == '[' ) {
        return false;   // do not permit '.', ';', or '['
      }
      if (type != LegalClass && ch == '/') {
        return false;   // do not permit '/' unless it's class name
      }
      if (type == LegalMethod && (ch == '<' || ch == '>')) {
        return false;   // do not permit '<' or '>' in method names
      }
    } else {
      char* tmp_p = UTF8::next(p, &ch);
      p = tmp_p;
    }
  }
  return true;
}


// Take pointer to a string. Skip over the longest part of the string that could
// be taken as a fieldname. Allow '/' 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).
char* ClassFileParser::skip_over_field_name(char* name, bool slash_ok, unsigned int length) {
  char* p;
  jchar ch;
  jboolean last_is_slash = false;
  jboolean not_first_ch = false;

  for (p = name; p != name + length; not_first_ch = true) {
    char* old_p = p;
    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 == '/') {
        if (last_is_slash) {
          return NULL;  // 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;
      instanceKlassHandle klass (THREAD, SystemDictionary::Character_klass());

      // return value
      JavaValue result(T_BOOLEAN);
      // Set up the arguments to isJavaIdentifierStart and isJavaIdentifierPart
      JavaCallArguments args;
      args.push_int(unicode_ch);

      // public static boolean isJavaIdentifierStart(char ch);
      JavaCalls::call_static(&result,
                             klass,
                             vmSymbols::isJavaIdentifierStart_name(),
                             vmSymbols::int_bool_signature(),
                             &args,
                             THREAD);

      if (HAS_PENDING_EXCEPTION) {
        CLEAR_PENDING_EXCEPTION;
        return 0;
      }
      if (result.get_jboolean()) {
        continue;
      }

      if (not_first_ch) {
        // public static boolean isJavaIdentifierPart(char ch);
        JavaCalls::call_static(&result,
                               klass,
                               vmSymbols::isJavaIdentifierPart_name(),
                               vmSymbols::int_bool_signature(),
                               &args,
                               THREAD);

        if (HAS_PENDING_EXCEPTION) {
          CLEAR_PENDING_EXCEPTION;
          return 0;
        }

        if (result.get_jboolean()) {
          continue;
        }
      }
    }
    return (not_first_ch) ? old_p : NULL;
  }
  return (not_first_ch) ? p : NULL;
}


// Take pointer to a string. 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.
char* ClassFileParser::skip_over_field_signature(char* signature,
                                                 bool void_ok,
                                                 unsigned int length,
                                                 TRAPS) {
  unsigned int array_dim = 0;
  while (length > 0) {
    switch (signature[0]) {
      case JVM_SIGNATURE_VOID: if (!void_ok) { return NULL; }
      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
          char* p = skip_over_field_name(signature + 1, true, --length);

          // The next character better be a semicolon
          if (p && (p - signature) > 1 && p[0] == ';') {
            return p + 1;
          }
        } else {
          // 4900761: For class version > 48, any unicode is allowed in class name.
          length--;
          signature++;
          while (length > 0 && signature[0] != ';') {
            if (signature[0] == '.') {
              classfile_parse_error("Class name contains illegal character '.' in descriptor in class file %s", CHECK_0);
            }
            length--;
            signature++;
          }
          if (signature[0] == ';') { return signature + 1; }
        }

        return NULL;
      }
      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", CHECK_0);
        }
        // The rest of what's there better be a legal signature
        signature++;
        length--;
        void_ok = false;
        break;

      default:
        return NULL;
    }
  }
  return NULL;
}
