< prev index next >

src/hotspot/share/classfile/verifier.cpp

Print this page
*** 61,10 ***
--- 61,11 ---
  #include "utilities/bytes.hpp"
  
  #define NOFAILOVER_MAJOR_VERSION                       51
  #define NONZERO_PADDING_BYTES_IN_SWITCH_MAJOR_VERSION  51
  #define STATIC_METHOD_IN_INTERFACE_MAJOR_VERSION       52
+ #define INLINE_TYPE_MAJOR_VERSION                       56
  #define MAX_ARRAY_DIMENSIONS 255
  
  // Access to external entry for VerifyClassForMajorVersion - old byte code verifier
  
  extern "C" {

*** 273,11 ***
    bool is_reflect = refl_magic_klass != nullptr && klass->is_subtype_of(refl_magic_klass);
  
    return (should_verify_for(klass->class_loader(), should_verify_class) &&
      // return if the class is a bootstrapping class
      // or defineClass specified not to verify by default (flags override passed arg)
!     // We need to skip the following four for bootstraping
      name != vmSymbols::java_lang_Object() &&
      name != vmSymbols::java_lang_Class() &&
      name != vmSymbols::java_lang_String() &&
      name != vmSymbols::java_lang_Throwable() &&
  
--- 274,11 ---
    bool is_reflect = refl_magic_klass != nullptr && klass->is_subtype_of(refl_magic_klass);
  
    return (should_verify_for(klass->class_loader(), should_verify_class) &&
      // return if the class is a bootstrapping class
      // or defineClass specified not to verify by default (flags override passed arg)
!     // We need to skip the following four for bootstrapping
      name != vmSymbols::java_lang_Object() &&
      name != vmSymbols::java_lang_Class() &&
      name != vmSymbols::java_lang_String() &&
      name != vmSymbols::java_lang_Throwable() &&
  

*** 496,10 ***
--- 497,17 ---
        ss->print("Expected stackmap frame at this location.");
        break;
      case BAD_STACKMAP:
        ss->print("Invalid stackmap specification.");
        break;
+     case WRONG_INLINE_TYPE:
+       ss->print("Type ");
+       _type.details(ss);
+       ss->print(" and type ");
+       _expected.details(ss);
+       ss->print(" must be identical inline types.");
+       break;
      case UNKNOWN:
      default:
        ShouldNotReachHere();
        ss->print_cr("Unknown");
    }

*** 590,14 ***
    }
  }
  
  // Methods in ClassVerifier
  
  ClassVerifier::ClassVerifier(JavaThread* current, InstanceKlass* klass)
      : _thread(current), _previous_symbol(nullptr), _symbols(nullptr), _exception_type(nullptr),
        _message(nullptr), _klass(klass) {
!   _this_type = VerificationType::reference_type(klass->name());
  }
  
  ClassVerifier::~ClassVerifier() {
    // Decrement the reference count for any symbols created.
    if (_symbols != nullptr) {
--- 598,22 ---
    }
  }
  
  // Methods in ClassVerifier
  
+ VerificationType reference_or_inline_type(InstanceKlass* klass) {
+   if (klass->is_inline_klass()) {
+     return VerificationType::inline_type(klass->name());
+   } else {
+     return VerificationType::reference_type(klass->name());
+   }
+ }
+ 
  ClassVerifier::ClassVerifier(JavaThread* current, InstanceKlass* klass)
      : _thread(current), _previous_symbol(nullptr), _symbols(nullptr), _exception_type(nullptr),
        _message(nullptr), _klass(klass) {
!   _this_type = reference_or_inline_type(klass);
  }
  
  ClassVerifier::~ClassVerifier() {
    // Decrement the reference count for any symbols created.
    if (_symbols != nullptr) {

*** 1033,11 ***
          case Bytecodes::_aaload : {
            type = current_frame.pop_stack(
              VerificationType::integer_type(), CHECK_VERIFY(this));
            atype = current_frame.pop_stack(
              VerificationType::reference_check(), CHECK_VERIFY(this));
!           if (!atype.is_reference_array()) {
              verify_error(ErrorContext::bad_type(bci,
                  current_frame.stack_top_ctx(),
                  TypeOrigin::implicit(VerificationType::reference_check())),
                  bad_type_msg, "aaload");
              return;
--- 1049,11 ---
          case Bytecodes::_aaload : {
            type = current_frame.pop_stack(
              VerificationType::integer_type(), CHECK_VERIFY(this));
            atype = current_frame.pop_stack(
              VerificationType::reference_check(), CHECK_VERIFY(this));
!           if (!atype.is_nonscalar_array()) {
              verify_error(ErrorContext::bad_type(bci,
                  current_frame.stack_top_ctx(),
                  TypeOrigin::implicit(VerificationType::reference_check())),
                  bad_type_msg, "aaload");
              return;

*** 1206,11 ***
            type2 = current_frame.pop_stack(
              VerificationType::integer_type(), CHECK_VERIFY(this));
            atype = current_frame.pop_stack(
              VerificationType::reference_check(), CHECK_VERIFY(this));
            // more type-checking is done at runtime
!           if (!atype.is_reference_array()) {
              verify_error(ErrorContext::bad_type(bci,
                  current_frame.stack_top_ctx(),
                  TypeOrigin::implicit(VerificationType::reference_check())),
                  bad_type_msg, "aastore");
              return;
--- 1222,11 ---
            type2 = current_frame.pop_stack(
              VerificationType::integer_type(), CHECK_VERIFY(this));
            atype = current_frame.pop_stack(
              VerificationType::reference_check(), CHECK_VERIFY(this));
            // more type-checking is done at runtime
!           if (!atype.is_nonscalar_array()) {
              verify_error(ErrorContext::bad_type(bci,
                  current_frame.stack_top_ctx(),
                  TypeOrigin::implicit(VerificationType::reference_check())),
                  bad_type_msg, "aastore");
              return;

*** 1606,16 ***
              &current_frame, target, CHECK_VERIFY(this));
            no_control_flow = false; break;
          case Bytecodes::_if_acmpeq :
          case Bytecodes::_if_acmpne :
            current_frame.pop_stack(
!             VerificationType::reference_check(), CHECK_VERIFY(this));
            // fall through
          case Bytecodes::_ifnull :
          case Bytecodes::_ifnonnull :
            current_frame.pop_stack(
!             VerificationType::reference_check(), CHECK_VERIFY(this));
            target = bcs.dest();
            stackmap_table.check_jump_target
              (&current_frame, target, CHECK_VERIFY(this));
            no_control_flow = false; break;
          case Bytecodes::_goto :
--- 1622,16 ---
              &current_frame, target, CHECK_VERIFY(this));
            no_control_flow = false; break;
          case Bytecodes::_if_acmpeq :
          case Bytecodes::_if_acmpne :
            current_frame.pop_stack(
!             VerificationType::nonscalar_check(), CHECK_VERIFY(this));
            // fall through
          case Bytecodes::_ifnull :
          case Bytecodes::_ifnonnull :
            current_frame.pop_stack(
!             VerificationType::nonscalar_check(), CHECK_VERIFY(this));
            target = bcs.dest();
            stackmap_table.check_jump_target
              (&current_frame, target, CHECK_VERIFY(this));
            no_control_flow = false; break;
          case Bytecodes::_goto :

*** 1662,11 ***
            verify_return_value(return_type, type, bci,
                                &current_frame, CHECK_VERIFY(this));
            no_control_flow = true; break;
          case Bytecodes::_areturn :
            type = current_frame.pop_stack(
!             VerificationType::reference_check(), CHECK_VERIFY(this));
            verify_return_value(return_type, type, bci,
                                &current_frame, CHECK_VERIFY(this));
            no_control_flow = true; break;
          case Bytecodes::_return :
            if (return_type != VerificationType::bogus_type()) {
--- 1678,11 ---
            verify_return_value(return_type, type, bci,
                                &current_frame, CHECK_VERIFY(this));
            no_control_flow = true; break;
          case Bytecodes::_areturn :
            type = current_frame.pop_stack(
!             VerificationType::nonscalar_check(), CHECK_VERIFY(this));
            verify_return_value(return_type, type, bci,
                                &current_frame, CHECK_VERIFY(this));
            no_control_flow = true; break;
          case Bytecodes::_return :
            if (return_type != VerificationType::bogus_type()) {

*** 1674,11 ***
                           "Method expects a return value");
              return;
            }
            // Make sure "this" has been initialized if current method is an
            // <init>.
!           if (_method->name() == vmSymbols::object_initializer_name() &&
                current_frame.flag_this_uninit()) {
              verify_error(ErrorContext::bad_code(bci),
                           "Constructor must call super() or this() "
                           "before return");
              return;
--- 1690,11 ---
                           "Method expects a return value");
              return;
            }
            // Make sure "this" has been initialized if current method is an
            // <init>.
!           if (_method->is_object_constructor() &&
                current_frame.flag_this_uninit()) {
              verify_error(ErrorContext::bad_code(bci),
                           "Constructor must call super() or this() "
                           "before return");
              return;

*** 1694,22 ***
          case Bytecodes::_putfield :
            // pass FALSE, operand can't be an array type for getfield/putfield.
            verify_field_instructions(
              &bcs, &current_frame, cp, false, CHECK_VERIFY(this));
            no_control_flow = false; break;
          case Bytecodes::_invokevirtual :
          case Bytecodes::_invokespecial :
          case Bytecodes::_invokestatic :
-           verify_invoke_instructions(
-             &bcs, code_length, &current_frame, (bci >= ex_min && bci < ex_max),
-             &this_uninit, return_type, cp, &stackmap_table, CHECK_VERIFY(this));
-           no_control_flow = false; break;
          case Bytecodes::_invokeinterface :
          case Bytecodes::_invokedynamic :
            verify_invoke_instructions(
              &bcs, code_length, &current_frame, (bci >= ex_min && bci < ex_max),
!             &this_uninit, return_type, cp, &stackmap_table, CHECK_VERIFY(this));
            no_control_flow = false; break;
          case Bytecodes::_new :
          {
            index = bcs.get_index_u2();
            verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
--- 1710,29 ---
          case Bytecodes::_putfield :
            // pass FALSE, operand can't be an array type for getfield/putfield.
            verify_field_instructions(
              &bcs, &current_frame, cp, false, CHECK_VERIFY(this));
            no_control_flow = false; break;
+         case Bytecodes::_withfield :
+           if (_klass->major_version() < INLINE_TYPE_MAJOR_VERSION) {
+             class_format_error(
+               "withfield not supported by this class file version (%d.%d), class %s",
+               _klass->major_version(), _klass->minor_version(), _klass->external_name());
+             return;
+           }
+           // pass FALSE, operand can't be an array type for withfield.
+           verify_field_instructions(
+             &bcs, &current_frame, cp, false, CHECK_VERIFY(this));
+           no_control_flow = false; break;
          case Bytecodes::_invokevirtual :
          case Bytecodes::_invokespecial :
          case Bytecodes::_invokestatic :
          case Bytecodes::_invokeinterface :
          case Bytecodes::_invokedynamic :
            verify_invoke_instructions(
              &bcs, code_length, &current_frame, (bci >= ex_min && bci < ex_max),
!             &this_uninit, cp, &stackmap_table, CHECK_VERIFY(this));
            no_control_flow = false; break;
          case Bytecodes::_new :
          {
            index = bcs.get_index_u2();
            verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));

*** 1723,10 ***
--- 1746,32 ---
            }
            type = VerificationType::uninitialized_type(bci);
            current_frame.push_stack(type, CHECK_VERIFY(this));
            no_control_flow = false; break;
          }
+         case Bytecodes::_aconst_init :
+         {
+           if (_klass->major_version() < INLINE_TYPE_MAJOR_VERSION) {
+             class_format_error(
+               "aconst_init not supported by this class file version (%d.%d), class %s",
+               _klass->major_version(), _klass->minor_version(), _klass->external_name());
+             return;
+           }
+           index = bcs.get_index_u2();
+           verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
+           VerificationType ref_type = cp_index_to_type(index, cp, CHECK_VERIFY(this));
+           if (!ref_type.is_object()) {
+             verify_error(ErrorContext::bad_type(bci,
+                 TypeOrigin::cp(index, ref_type)),
+                 "Illegal aconst_init instruction");
+             return;
+           }
+           VerificationType inline_type =
+             VerificationType::change_ref_to_inline_type(ref_type);
+           current_frame.push_stack(inline_type, CHECK_VERIFY(this));
+           no_control_flow = false; break;
+         }
          case Bytecodes::_newarray :
            type = get_newarray_type(bcs.get_index(), bci, CHECK_VERIFY(this));
            current_frame.pop_stack(
              VerificationType::integer_type(),  CHECK_VERIFY(this));
            current_frame.push_stack(type, CHECK_VERIFY(this));

*** 1763,14 ***
            current_frame.push_stack(
              VerificationType::integer_type(), CHECK_VERIFY(this));
            no_control_flow = false; break;
          }
          case Bytecodes::_monitorenter :
!         case Bytecodes::_monitorexit :
!           current_frame.pop_stack(
!             VerificationType::reference_check(), CHECK_VERIFY(this));
            no_control_flow = false; break;
          case Bytecodes::_multianewarray :
          {
            index = bcs.get_index_u2();
            u2 dim = *(bcs.bcp()+3);
            verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));
--- 1808,15 ---
            current_frame.push_stack(
              VerificationType::integer_type(), CHECK_VERIFY(this));
            no_control_flow = false; break;
          }
          case Bytecodes::_monitorenter :
!         case Bytecodes::_monitorexit : {
!           VerificationType ref = current_frame.pop_stack(
!             VerificationType::nonscalar_check(), CHECK_VERIFY(this));
            no_control_flow = false; break;
+         }
          case Bytecodes::_multianewarray :
          {
            index = bcs.get_index_u2();
            u2 dim = *(bcs.bcp()+3);
            verify_cp_class_type(bci, index, cp, CHECK_VERIFY(this));

*** 2031,10 ***
--- 2077,11 ---
    // We must check was_recursively_verified() before we get here.
    guarantee(cp->cache() == nullptr, "not rewritten yet");
  
    verify_cp_index(bci, cp, index, CHECK_VERIFY(this));
    unsigned int tag = cp->tag_at(index).value();
+ 
    if ((types & (1 << tag)) == 0) {
      verify_error(ErrorContext::bad_cp_index(bci, index),
        "Illegal type at constant pool entry %d in class %s",
        index, cp->pool_holder()->external_name());
      return;

*** 2145,11 ***
    constantTag tag = cp->tag_at(index);
    unsigned int types = 0;
    if (opcode == Bytecodes::_ldc || opcode == Bytecodes::_ldc_w) {
      if (!tag.is_unresolved_klass()) {
        types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float)
!             | (1 << JVM_CONSTANT_String)  | (1 << JVM_CONSTANT_Class)
              | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType)
              | (1 << JVM_CONSTANT_Dynamic);
        // Note:  The class file parser already verified the legality of
        // MethodHandle and MethodType constants.
        verify_cp_type(bci, index, cp, types, CHECK_VERIFY(this));
--- 2192,11 ---
    constantTag tag = cp->tag_at(index);
    unsigned int types = 0;
    if (opcode == Bytecodes::_ldc || opcode == Bytecodes::_ldc_w) {
      if (!tag.is_unresolved_klass()) {
        types = (1 << JVM_CONSTANT_Integer) | (1 << JVM_CONSTANT_Float)
!             | (1 << JVM_CONSTANT_String) | (1 << JVM_CONSTANT_Class)
              | (1 << JVM_CONSTANT_MethodHandle) | (1 << JVM_CONSTANT_MethodType)
              | (1 << JVM_CONSTANT_Dynamic);
        // Note:  The class file parser already verified the legality of
        // MethodHandle and MethodType constants.
        verify_cp_type(bci, index, cp, types, CHECK_VERIFY(this));

*** 2320,17 ***
  
    // Get referenced class type
    VerificationType ref_class_type = cp_ref_index_to_type(
      index, cp, CHECK_VERIFY(this));
    if (!ref_class_type.is_object() &&
!     (!allow_arrays || !ref_class_type.is_array())) {
      verify_error(ErrorContext::bad_type(bcs->bci(),
          TypeOrigin::cp(index, ref_class_type)),
          "Expecting reference to class in class %s at constant pool index %d",
          _klass->external_name(), index);
      return;
    }
    VerificationType target_class_type = ref_class_type;
  
    assert(sizeof(VerificationType) == sizeof(uintptr_t),
          "buffer type must match VerificationType size");
    uintptr_t field_type_buffer[2];
--- 2367,18 ---
  
    // Get referenced class type
    VerificationType ref_class_type = cp_ref_index_to_type(
      index, cp, CHECK_VERIFY(this));
    if (!ref_class_type.is_object() &&
!       (!allow_arrays || !ref_class_type.is_array())) {
      verify_error(ErrorContext::bad_type(bcs->bci(),
          TypeOrigin::cp(index, ref_class_type)),
          "Expecting reference to class in class %s at constant pool index %d",
          _klass->external_name(), index);
      return;
    }
+ 
    VerificationType target_class_type = ref_class_type;
  
    assert(sizeof(VerificationType) == sizeof(uintptr_t),
          "buffer type must match VerificationType size");
    uintptr_t field_type_buffer[2];

*** 2356,10 ***
--- 2404,21 ---
        for (int i = n - 1; i >= 0; i--) {
          current_frame->pop_stack(field_type[i], CHECK_VERIFY(this));
        }
        break;
      }
+     case Bytecodes::_withfield: {
+       for (int i = n - 1; i >= 0; i--) {
+         current_frame->pop_stack(field_type[i], CHECK_VERIFY(this));
+       }
+       // Check that the receiver is a subtype of the referenced class.
+       current_frame->pop_stack(target_class_type, CHECK_VERIFY(this));
+       VerificationType target_inline_type =
+         VerificationType::change_ref_to_inline_type(target_class_type);
+       current_frame->push_stack(target_inline_type, CHECK_VERIFY(this));
+       break;
+     }
      case Bytecodes::_getfield: {
        is_getfield = true;
        stack_object_type = current_frame->pop_stack(
          target_class_type, CHECK_VERIFY(this));
        goto check_protected;

*** 2777,11 ***
    return false;
  }
  
  void ClassVerifier::verify_invoke_instructions(
      RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
!     bool in_try_block, bool *this_uninit, VerificationType return_type,
      const constantPoolHandle& cp, StackMapTable* stackmap_table, TRAPS) {
    // Make sure the constant pool item is the right type
    u2 index = bcs->get_index_u2();
    Bytecodes::Code opcode = bcs->raw_code();
    unsigned int types = 0;
--- 2836,11 ---
    return false;
  }
  
  void ClassVerifier::verify_invoke_instructions(
      RawBytecodeStream* bcs, u4 code_length, StackMapFrame* current_frame,
!     bool in_try_block, bool *this_uninit,
      const constantPoolHandle& cp, StackMapTable* stackmap_table, TRAPS) {
    // Make sure the constant pool item is the right type
    u2 index = bcs->get_index_u2();
    Bytecodes::Code opcode = bcs->raw_code();
    unsigned int types = 0;

*** 2809,11 ***
  
    // Method signature was checked in ClassFileParser.
    assert(SignatureVerifier::is_valid_method_signature(method_sig),
           "Invalid method signature");
  
!   // Get referenced class type
    VerificationType ref_class_type;
    if (opcode == Bytecodes::_invokedynamic) {
      if (_klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
        class_format_error(
          "invokedynamic instructions not supported by this class file version (%d), class %s",
--- 2868,11 ---
  
    // Method signature was checked in ClassFileParser.
    assert(SignatureVerifier::is_valid_method_signature(method_sig),
           "Invalid method signature");
  
!   // Get referenced class
    VerificationType ref_class_type;
    if (opcode == Bytecodes::_invokedynamic) {
      if (_klass->major_version() < Verifier::INVOKEDYNAMIC_MAJOR_VERSION) {
        class_format_error(
          "invokedynamic instructions not supported by this class file version (%d), class %s",

*** 2875,21 ***
        return;
      }
    }
  
    if (method_name->char_at(0) == JVM_SIGNATURE_SPECIAL) {
!     // Make sure <init> can only be invoked by invokespecial
!     if (opcode != Bytecodes::_invokespecial ||
!         method_name != vmSymbols::object_initializer_name()) {
        verify_error(ErrorContext::bad_code(bci),
            "Illegal call to internal method");
        return;
      }
    } else if (opcode == Bytecodes::_invokespecial
               && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type)
               && !ref_class_type.equals(VerificationType::reference_type(
!                   current_class()->super()->name()))) {
      bool subtype = false;
      bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref;
      subtype = ref_class_type.is_assignable_from(
                 current_type(), this, false, CHECK_VERIFY(this));
      if (!subtype) {
--- 2934,25 ---
        return;
      }
    }
  
    if (method_name->char_at(0) == JVM_SIGNATURE_SPECIAL) {
!     // Make sure:
!     //   <init> can only be invoked by invokespecial.
!     //   <vnew> can only be invoked by invokestatic.
+     if (!((opcode == Bytecodes::_invokestatic &&
+            method_name == vmSymbols::inline_factory_name()) ||
+          (opcode == Bytecodes::_invokespecial &&
+           method_name == vmSymbols::object_initializer_name()))) {
        verify_error(ErrorContext::bad_code(bci),
            "Illegal call to internal method");
        return;
      }
    } else if (opcode == Bytecodes::_invokespecial
               && !is_same_or_direct_interface(current_class(), current_type(), ref_class_type)
               && !ref_class_type.equals(VerificationType::reference_type(
!                   current_class()->super()->name()))) { // super() can never be an inline_type.
      bool subtype = false;
      bool have_imr_indirect = cp->tag_at(index).value() == JVM_CONSTANT_InterfaceMethodref;
      subtype = ref_class_type.is_assignable_from(
                 current_type(), this, false, CHECK_VERIFY(this));
      if (!subtype) {

*** 2970,13 ***
    }
    // Push the result type.
    int sig_verif_types_len = sig_verif_types->length();
    if (sig_verif_types_len > nargs) {  // There's a return type
      if (method_name == vmSymbols::object_initializer_name()) {
!       // <init> method must have a void return type
-       /* Unreachable?  Class file parser verifies that methods with '<' have
-        * void return */
        verify_error(ErrorContext::bad_code(bci),
            "Return type must be void in <init> method");
        return;
      }
  
--- 3033,11 ---
    }
    // Push the result type.
    int sig_verif_types_len = sig_verif_types->length();
    if (sig_verif_types_len > nargs) {  // There's a return type
      if (method_name == vmSymbols::object_initializer_name()) {
!       // an <init> method must have a void return type
        verify_error(ErrorContext::bad_code(bci),
            "Return type must be void in <init> method");
        return;
      }
  

*** 2985,10 ***
--- 3046,17 ---
      for (int i = nargs; i < sig_verif_types_len; i++) {
        assert(i == nargs || sig_verif_types->at(i).is_long2() ||
               sig_verif_types->at(i).is_double2(), "Unexpected return verificationType");
        current_frame->push_stack(sig_verif_types->at(i), CHECK_VERIFY(this));
      }
+   } else { // no return type
+     // <vnew> method may not have a void return type
+     if (method_name == vmSymbols::inline_factory_name()) {
+       verify_error(ErrorContext::bad_code(bci),
+           "Return type must be non-void in <vnew> static factory method");
+       return;
+     }
    }
  }
  
  VerificationType ClassVerifier::get_newarray_type(
      u2 index, u2 bci, TRAPS) {

*** 3032,15 ***
      int n = os::snprintf(arr_sig_str, length + 1, "%c%s",
                           JVM_SIGNATURE_ARRAY, component_name);
      assert(n == length, "Unexpected number of characters in string");
    } else {         // it's an object or interface
      const char* component_name = component_type.name()->as_utf8();
!     // add one dimension to component with 'L' prepended and ';' postpended.
      length = (int)strlen(component_name) + 3;
      arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length + 1);
      int n = os::snprintf(arr_sig_str, length + 1, "%c%c%s;",
!                          JVM_SIGNATURE_ARRAY, JVM_SIGNATURE_CLASS, component_name);
      assert(n == length, "Unexpected number of characters in string");
    }
    Symbol* arr_sig = create_temporary_symbol(arr_sig_str, length);
    VerificationType new_array_type = VerificationType::reference_type(arr_sig);
    current_frame->push_stack(new_array_type, CHECK_VERIFY(this));
--- 3100,16 ---
      int n = os::snprintf(arr_sig_str, length + 1, "%c%s",
                           JVM_SIGNATURE_ARRAY, component_name);
      assert(n == length, "Unexpected number of characters in string");
    } else {         // it's an object or interface
      const char* component_name = component_type.name()->as_utf8();
!     char Q_or_L = component_type.is_inline_type() ? JVM_SIGNATURE_PRIMITIVE_OBJECT : JVM_SIGNATURE_CLASS;
+     // add one dimension to component with 'L' or 'Q' prepended and ';' appended.
      length = (int)strlen(component_name) + 3;
      arr_sig_str = NEW_RESOURCE_ARRAY_IN_THREAD(THREAD, char, length + 1);
      int n = os::snprintf(arr_sig_str, length + 1, "%c%c%s;",
!                          JVM_SIGNATURE_ARRAY, Q_or_L, component_name);
      assert(n == length, "Unexpected number of characters in string");
    }
    Symbol* arr_sig = create_temporary_symbol(arr_sig_str, length);
    VerificationType new_array_type = VerificationType::reference_type(arr_sig);
    current_frame->push_stack(new_array_type, CHECK_VERIFY(this));

*** 3078,11 ***
      VerificationType::double2_type(), CHECK_VERIFY(this));
  }
  
  void ClassVerifier::verify_aload(u2 index, StackMapFrame* current_frame, TRAPS) {
    VerificationType type = current_frame->get_local(
!     index, VerificationType::reference_check(), CHECK_VERIFY(this));
    current_frame->push_stack(type, CHECK_VERIFY(this));
  }
  
  void ClassVerifier::verify_istore(u2 index, StackMapFrame* current_frame, TRAPS) {
    current_frame->pop_stack(
--- 3147,11 ---
      VerificationType::double2_type(), CHECK_VERIFY(this));
  }
  
  void ClassVerifier::verify_aload(u2 index, StackMapFrame* current_frame, TRAPS) {
    VerificationType type = current_frame->get_local(
!     index, VerificationType::nonscalar_check(), CHECK_VERIFY(this));
    current_frame->push_stack(type, CHECK_VERIFY(this));
  }
  
  void ClassVerifier::verify_istore(u2 index, StackMapFrame* current_frame, TRAPS) {
    current_frame->pop_stack(

*** 3115,11 ***
      VerificationType::double2_type(), CHECK_VERIFY(this));
  }
  
  void ClassVerifier::verify_astore(u2 index, StackMapFrame* current_frame, TRAPS) {
    VerificationType type = current_frame->pop_stack(
!     VerificationType::reference_check(), CHECK_VERIFY(this));
    current_frame->set_local(index, type, CHECK_VERIFY(this));
  }
  
  void ClassVerifier::verify_iinc(u2 index, StackMapFrame* current_frame, TRAPS) {
    VerificationType type = current_frame->get_local(
--- 3184,11 ---
      VerificationType::double2_type(), CHECK_VERIFY(this));
  }
  
  void ClassVerifier::verify_astore(u2 index, StackMapFrame* current_frame, TRAPS) {
    VerificationType type = current_frame->pop_stack(
!     VerificationType::nonscalar_check(), CHECK_VERIFY(this));
    current_frame->set_local(index, type, CHECK_VERIFY(this));
  }
  
  void ClassVerifier::verify_iinc(u2 index, StackMapFrame* current_frame, TRAPS) {
    VerificationType type = current_frame->get_local(
< prev index next >