hotspot/src/share/vm/classfile/verificationType.hpp
author trims
Thu, 27 May 2010 19:08:38 -0700
changeset 5547 f4b087cbb361
parent 1 489c9b5090e2
child 7397 5b173b4ca846
permissions -rw-r--r--
6941466: Oracle rebranding changes for Hotspot repositories Summary: Change all the Sun copyrights to Oracle copyright Reviewed-by: ohair
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     1
/*
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
     2
 * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     4
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
489c9b5090e2 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
489c9b5090e2 Initial load
duke
parents:
diff changeset
     7
 * published by the Free Software Foundation.
489c9b5090e2 Initial load
duke
parents:
diff changeset
     8
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
     9
 * This code is distributed in the hope that it will be useful, but WITHOUT
489c9b5090e2 Initial load
duke
parents:
diff changeset
    10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
489c9b5090e2 Initial load
duke
parents:
diff changeset
    11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
489c9b5090e2 Initial load
duke
parents:
diff changeset
    12
 * version 2 for more details (a copy is included in the LICENSE file that
489c9b5090e2 Initial load
duke
parents:
diff changeset
    13
 * accompanied this code).
489c9b5090e2 Initial load
duke
parents:
diff changeset
    14
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    15
 * You should have received a copy of the GNU General Public License version
489c9b5090e2 Initial load
duke
parents:
diff changeset
    16
 * 2 along with this work; if not, write to the Free Software Foundation,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    18
 *
5547
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    20
 * or visit www.oracle.com if you need additional information or have any
f4b087cbb361 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 1
diff changeset
    21
 * questions.
1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    22
 *
489c9b5090e2 Initial load
duke
parents:
diff changeset
    23
 */
489c9b5090e2 Initial load
duke
parents:
diff changeset
    24
489c9b5090e2 Initial load
duke
parents:
diff changeset
    25
enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    26
  // As specifed in the JVM spec
489c9b5090e2 Initial load
duke
parents:
diff changeset
    27
  ITEM_Top = 0,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    28
  ITEM_Integer = 1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    29
  ITEM_Float = 2,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    30
  ITEM_Double = 3,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    31
  ITEM_Long = 4,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    32
  ITEM_Null = 5,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    33
  ITEM_UninitializedThis = 6,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    34
  ITEM_Object = 7,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    35
  ITEM_Uninitialized = 8,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    36
  ITEM_Bogus = (uint)-1
489c9b5090e2 Initial load
duke
parents:
diff changeset
    37
};
489c9b5090e2 Initial load
duke
parents:
diff changeset
    38
489c9b5090e2 Initial load
duke
parents:
diff changeset
    39
class VerificationType VALUE_OBJ_CLASS_SPEC {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    40
  private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
    41
    // Least significant bits of _handle are always 0, so we use these as
489c9b5090e2 Initial load
duke
parents:
diff changeset
    42
    // the indicator that the _handle is valid.  Otherwise, the _data field
489c9b5090e2 Initial load
duke
parents:
diff changeset
    43
    // contains encoded data (as specified below).  Should the VM change
489c9b5090e2 Initial load
duke
parents:
diff changeset
    44
    // and the lower bits on oops aren't 0, the assert in the constructor
489c9b5090e2 Initial load
duke
parents:
diff changeset
    45
    // will catch this and we'll have to add a descriminator tag to this
489c9b5090e2 Initial load
duke
parents:
diff changeset
    46
    // structure.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    47
    union {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    48
      symbolOop* _handle;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    49
      uintptr_t _data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    50
    } _u;
489c9b5090e2 Initial load
duke
parents:
diff changeset
    51
489c9b5090e2 Initial load
duke
parents:
diff changeset
    52
    enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    53
      // These rest are not found in classfiles, but used by the verifier
489c9b5090e2 Initial load
duke
parents:
diff changeset
    54
      ITEM_Boolean = 9, ITEM_Byte, ITEM_Short, ITEM_Char,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    55
      ITEM_Long_2nd, ITEM_Double_2nd
489c9b5090e2 Initial load
duke
parents:
diff changeset
    56
    };
489c9b5090e2 Initial load
duke
parents:
diff changeset
    57
489c9b5090e2 Initial load
duke
parents:
diff changeset
    58
    // Enum for the _data field
489c9b5090e2 Initial load
duke
parents:
diff changeset
    59
    enum {
489c9b5090e2 Initial load
duke
parents:
diff changeset
    60
      // Bottom two bits determine if the type is a reference, primitive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    61
      // uninitialized or a query-type.
489c9b5090e2 Initial load
duke
parents:
diff changeset
    62
      TypeMask           = 0x00000003,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    63
489c9b5090e2 Initial load
duke
parents:
diff changeset
    64
      // Topmost types encoding
489c9b5090e2 Initial load
duke
parents:
diff changeset
    65
      Reference          = 0x0,        // _handle contains the name
489c9b5090e2 Initial load
duke
parents:
diff changeset
    66
      Primitive          = 0x1,        // see below for primitive list
489c9b5090e2 Initial load
duke
parents:
diff changeset
    67
      Uninitialized      = 0x2,        // 0x00ffff00 contains bci
489c9b5090e2 Initial load
duke
parents:
diff changeset
    68
      TypeQuery          = 0x3,        // Meta-types used for category testing
489c9b5090e2 Initial load
duke
parents:
diff changeset
    69
489c9b5090e2 Initial load
duke
parents:
diff changeset
    70
      // Utility flags
489c9b5090e2 Initial load
duke
parents:
diff changeset
    71
      ReferenceFlag      = 0x00,       // For reference query types
489c9b5090e2 Initial load
duke
parents:
diff changeset
    72
      Category1Flag      = 0x01,       // One-word values
489c9b5090e2 Initial load
duke
parents:
diff changeset
    73
      Category2Flag      = 0x02,       // First word of a two-word value
489c9b5090e2 Initial load
duke
parents:
diff changeset
    74
      Category2_2ndFlag  = 0x04,       // Second word of a two-word value
489c9b5090e2 Initial load
duke
parents:
diff changeset
    75
489c9b5090e2 Initial load
duke
parents:
diff changeset
    76
      // special reference values
489c9b5090e2 Initial load
duke
parents:
diff changeset
    77
      Null               = 0x00000000, // A reference with a 0 handle is null
489c9b5090e2 Initial load
duke
parents:
diff changeset
    78
489c9b5090e2 Initial load
duke
parents:
diff changeset
    79
      // Primitives categories (the second byte determines the category)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    80
      Category1          = (Category1Flag     << 1 * BitsPerByte) | Primitive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    81
      Category2          = (Category2Flag     << 1 * BitsPerByte) | Primitive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    82
      Category2_2nd      = (Category2_2ndFlag << 1 * BitsPerByte) | Primitive,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    83
489c9b5090e2 Initial load
duke
parents:
diff changeset
    84
      // Primitive values (type descriminator stored in most-signifcant bytes)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    85
      Bogus              = (ITEM_Bogus      << 2 * BitsPerByte) | Category1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    86
      Boolean            = (ITEM_Boolean    << 2 * BitsPerByte) | Category1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    87
      Byte               = (ITEM_Byte       << 2 * BitsPerByte) | Category1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    88
      Short              = (ITEM_Short      << 2 * BitsPerByte) | Category1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    89
      Char               = (ITEM_Char       << 2 * BitsPerByte) | Category1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    90
      Integer            = (ITEM_Integer    << 2 * BitsPerByte) | Category1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    91
      Float              = (ITEM_Float      << 2 * BitsPerByte) | Category1,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    92
      Long               = (ITEM_Long       << 2 * BitsPerByte) | Category2,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    93
      Double             = (ITEM_Double     << 2 * BitsPerByte) | Category2,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    94
      Long_2nd           = (ITEM_Long_2nd   << 2 * BitsPerByte) | Category2_2nd,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    95
      Double_2nd         = (ITEM_Double_2nd << 2 * BitsPerByte) | Category2_2nd,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    96
489c9b5090e2 Initial load
duke
parents:
diff changeset
    97
      // Used by Uninitialized (second and third bytes hold the bci)
489c9b5090e2 Initial load
duke
parents:
diff changeset
    98
      BciMask            = 0xffff << 1 * BitsPerByte,
489c9b5090e2 Initial load
duke
parents:
diff changeset
    99
      BciForThis         = ((u2)-1),   // A bci of -1 is an Unintialized-This
489c9b5090e2 Initial load
duke
parents:
diff changeset
   100
489c9b5090e2 Initial load
duke
parents:
diff changeset
   101
      // Query values
489c9b5090e2 Initial load
duke
parents:
diff changeset
   102
      ReferenceQuery     = (ReferenceFlag     << 1 * BitsPerByte) | TypeQuery,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   103
      Category1Query     = (Category1Flag     << 1 * BitsPerByte) | TypeQuery,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   104
      Category2Query     = (Category2Flag     << 1 * BitsPerByte) | TypeQuery,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   105
      Category2_2ndQuery = (Category2_2ndFlag << 1 * BitsPerByte) | TypeQuery
489c9b5090e2 Initial load
duke
parents:
diff changeset
   106
    };
489c9b5090e2 Initial load
duke
parents:
diff changeset
   107
489c9b5090e2 Initial load
duke
parents:
diff changeset
   108
  VerificationType(uintptr_t raw_data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   109
    _u._data = raw_data;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   110
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   111
489c9b5090e2 Initial load
duke
parents:
diff changeset
   112
 public:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   113
489c9b5090e2 Initial load
duke
parents:
diff changeset
   114
  VerificationType() { *this = bogus_type(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   115
489c9b5090e2 Initial load
duke
parents:
diff changeset
   116
  // Create verification types
489c9b5090e2 Initial load
duke
parents:
diff changeset
   117
  static VerificationType bogus_type() { return VerificationType(Bogus); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   118
  static VerificationType null_type() { return VerificationType(Null); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   119
  static VerificationType integer_type() { return VerificationType(Integer); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   120
  static VerificationType float_type() { return VerificationType(Float); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   121
  static VerificationType long_type() { return VerificationType(Long); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   122
  static VerificationType long2_type() { return VerificationType(Long_2nd); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   123
  static VerificationType double_type() { return VerificationType(Double); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   124
  static VerificationType boolean_type() { return VerificationType(Boolean); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   125
  static VerificationType byte_type() { return VerificationType(Byte); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   126
  static VerificationType char_type() { return VerificationType(Char); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   127
  static VerificationType short_type() { return VerificationType(Short); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   128
  static VerificationType double2_type()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   129
    { return VerificationType(Double_2nd); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   130
489c9b5090e2 Initial load
duke
parents:
diff changeset
   131
  // "check" types are used for queries.  A "check" type is not assignable
489c9b5090e2 Initial load
duke
parents:
diff changeset
   132
  // to anything, but the specified types are assignable to a "check".  For
489c9b5090e2 Initial load
duke
parents:
diff changeset
   133
  // example, any category1 primitive is assignable to category1_check and
489c9b5090e2 Initial load
duke
parents:
diff changeset
   134
  // any reference is assignable to reference_check.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   135
  static VerificationType reference_check()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   136
    { return VerificationType(ReferenceQuery); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   137
  static VerificationType category1_check()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   138
    { return VerificationType(Category1Query); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   139
  static VerificationType category2_check()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   140
    { return VerificationType(Category2Query); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   141
  static VerificationType category2_2nd_check()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   142
    { return VerificationType(Category2_2ndQuery); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   143
489c9b5090e2 Initial load
duke
parents:
diff changeset
   144
  // For reference types, store the actual oop* handle
489c9b5090e2 Initial load
duke
parents:
diff changeset
   145
  static VerificationType reference_type(symbolHandle sh) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   146
      assert(((uintptr_t)sh.raw_value() & 0x3) == 0, "Oops must be aligned");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   147
      // If the above assert fails in the future because oop* isn't aligned,
489c9b5090e2 Initial load
duke
parents:
diff changeset
   148
      // then this type encoding system will have to change to have a tag value
489c9b5090e2 Initial load
duke
parents:
diff changeset
   149
      // to descriminate between oops and primitives.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   150
      return VerificationType((uintptr_t)((symbolOop*)sh.raw_value()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   151
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   152
  static VerificationType reference_type(symbolOop s, TRAPS)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   153
    { return reference_type(symbolHandle(THREAD, s)); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   154
489c9b5090e2 Initial load
duke
parents:
diff changeset
   155
  static VerificationType uninitialized_type(u2 bci)
489c9b5090e2 Initial load
duke
parents:
diff changeset
   156
    { return VerificationType(bci << 1 * BitsPerByte | Uninitialized); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   157
  static VerificationType uninitialized_this_type()
489c9b5090e2 Initial load
duke
parents:
diff changeset
   158
    { return uninitialized_type(BciForThis); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   159
489c9b5090e2 Initial load
duke
parents:
diff changeset
   160
  // Create based on u1 read from classfile
489c9b5090e2 Initial load
duke
parents:
diff changeset
   161
  static VerificationType from_tag(u1 tag);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   162
489c9b5090e2 Initial load
duke
parents:
diff changeset
   163
  bool is_bogus() const     { return (_u._data == Bogus); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   164
  bool is_null() const      { return (_u._data == Null); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   165
  bool is_boolean() const   { return (_u._data == Boolean); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   166
  bool is_byte() const      { return (_u._data == Byte); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   167
  bool is_char() const      { return (_u._data == Char); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   168
  bool is_short() const     { return (_u._data == Short); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   169
  bool is_integer() const   { return (_u._data == Integer); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   170
  bool is_long() const      { return (_u._data == Long); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   171
  bool is_float() const     { return (_u._data == Float); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   172
  bool is_double() const    { return (_u._data == Double); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   173
  bool is_long2() const     { return (_u._data == Long_2nd); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   174
  bool is_double2() const   { return (_u._data == Double_2nd); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   175
  bool is_reference() const { return ((_u._data & TypeMask) == Reference); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   176
  bool is_category1() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   177
    // This should return true for all one-word types, which are category1
489c9b5090e2 Initial load
duke
parents:
diff changeset
   178
    // primitives, and references (including uninitialized refs).  Though
489c9b5090e2 Initial load
duke
parents:
diff changeset
   179
    // the 'query' types should technically return 'false' here, if we
489c9b5090e2 Initial load
duke
parents:
diff changeset
   180
    // allow this to return true, we can perform the test using only
489c9b5090e2 Initial load
duke
parents:
diff changeset
   181
    // 2 operations rather than 8 (3 masks, 3 compares and 2 logical 'ands').
489c9b5090e2 Initial load
duke
parents:
diff changeset
   182
    // Since noone should call this on a query type anyway, this is ok.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   183
    assert(!is_check(), "Must not be a check type (wrong value returned)");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   184
    return ((_u._data & Category1) != Primitive);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   185
    // should only return false if it's a primitive, and the category1 flag
489c9b5090e2 Initial load
duke
parents:
diff changeset
   186
    // is not set.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   187
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   188
  bool is_category2() const { return ((_u._data & Category2) == Category2); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   189
  bool is_category2_2nd() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   190
    return ((_u._data & Category2_2nd) == Category2_2nd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   191
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   192
  bool is_reference_check() const { return _u._data == ReferenceQuery; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   193
  bool is_category1_check() const { return _u._data == Category1Query; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   194
  bool is_category2_check() const { return _u._data == Category2Query; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   195
  bool is_category2_2nd_check() const { return _u._data == Category2_2ndQuery; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   196
  bool is_check() const { return (_u._data & TypeQuery) == TypeQuery; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   197
489c9b5090e2 Initial load
duke
parents:
diff changeset
   198
  bool is_x_array(char sig) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   199
    return is_null() || (is_array() && (name()->byte_at(1) == sig));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   200
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   201
  bool is_int_array() const { return is_x_array('I'); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   202
  bool is_byte_array() const { return is_x_array('B'); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   203
  bool is_bool_array() const { return is_x_array('Z'); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   204
  bool is_char_array() const { return is_x_array('C'); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   205
  bool is_short_array() const { return is_x_array('S'); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   206
  bool is_long_array() const { return is_x_array('J'); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   207
  bool is_float_array() const { return is_x_array('F'); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   208
  bool is_double_array() const { return is_x_array('D'); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   209
  bool is_object_array() const { return is_x_array('L'); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   210
  bool is_array_array() const { return is_x_array('['); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   211
  bool is_reference_array() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   212
    { return is_object_array() || is_array_array(); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   213
  bool is_object() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   214
    { return (is_reference() && !is_null() && name()->utf8_length() >= 1 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   215
              name()->byte_at(0) != '['); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   216
  bool is_array() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   217
    { return (is_reference() && !is_null() && name()->utf8_length() >= 2 &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   218
              name()->byte_at(0) == '['); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   219
  bool is_uninitialized() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   220
    { return ((_u._data & Uninitialized) == Uninitialized); }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   221
  bool is_uninitialized_this() const
489c9b5090e2 Initial load
duke
parents:
diff changeset
   222
    { return is_uninitialized() && bci() == BciForThis; }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   223
489c9b5090e2 Initial load
duke
parents:
diff changeset
   224
  VerificationType to_category2_2nd() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   225
    assert(is_category2(), "Must be a double word");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   226
    return VerificationType(is_long() ? Long_2nd : Double_2nd);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   227
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   228
489c9b5090e2 Initial load
duke
parents:
diff changeset
   229
  u2 bci() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   230
    assert(is_uninitialized(), "Must be uninitialized type");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   231
    return ((_u._data & BciMask) >> 1 * BitsPerByte);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   232
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   233
489c9b5090e2 Initial load
duke
parents:
diff changeset
   234
  symbolHandle name_handle() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   235
    assert(is_reference() && !is_null(), "Must be a non-null reference");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   236
    return symbolHandle(_u._handle, true);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   237
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   238
  symbolOop name() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   239
    assert(is_reference() && !is_null(), "Must be a non-null reference");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   240
    return *(_u._handle);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   241
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   242
489c9b5090e2 Initial load
duke
parents:
diff changeset
   243
  bool equals(const VerificationType& t) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   244
    return (_u._data == t._u._data ||
489c9b5090e2 Initial load
duke
parents:
diff changeset
   245
      (is_reference() && t.is_reference() && !is_null() && !t.is_null() &&
489c9b5090e2 Initial load
duke
parents:
diff changeset
   246
       name() == t.name()));
489c9b5090e2 Initial load
duke
parents:
diff changeset
   247
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   248
489c9b5090e2 Initial load
duke
parents:
diff changeset
   249
  bool operator ==(const VerificationType& t) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   250
    return equals(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   251
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   252
489c9b5090e2 Initial load
duke
parents:
diff changeset
   253
  bool operator !=(const VerificationType& t) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   254
    return !equals(t);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   255
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   256
489c9b5090e2 Initial load
duke
parents:
diff changeset
   257
  // The whole point of this type system - check to see if one type
489c9b5090e2 Initial load
duke
parents:
diff changeset
   258
  // is assignable to another.  Returns true if one can assign 'from' to
489c9b5090e2 Initial load
duke
parents:
diff changeset
   259
  // this.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   260
  bool is_assignable_from(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   261
      const VerificationType& from, instanceKlassHandle context, TRAPS) const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   262
    if (equals(from) || is_bogus()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   263
      return true;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   264
    } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   265
      switch(_u._data) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   266
        case Category1Query:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   267
          return from.is_category1();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   268
        case Category2Query:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   269
          return from.is_category2();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   270
        case Category2_2ndQuery:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   271
          return from.is_category2_2nd();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   272
        case ReferenceQuery:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   273
          return from.is_reference() || from.is_uninitialized();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   274
        case Boolean:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   275
        case Byte:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   276
        case Char:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   277
        case Short:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   278
          // An int can be assigned to boolean, byte, char or short values.
489c9b5090e2 Initial load
duke
parents:
diff changeset
   279
          return from.is_integer();
489c9b5090e2 Initial load
duke
parents:
diff changeset
   280
        default:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   281
          if (is_reference() && from.is_reference()) {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   282
            return is_reference_assignable_from(from, context, CHECK_false);
489c9b5090e2 Initial load
duke
parents:
diff changeset
   283
          } else {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   284
            return false;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   285
          }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   286
      }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   287
    }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   288
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   289
489c9b5090e2 Initial load
duke
parents:
diff changeset
   290
  VerificationType get_component(TRAPS) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   291
489c9b5090e2 Initial load
duke
parents:
diff changeset
   292
  int dimensions() const {
489c9b5090e2 Initial load
duke
parents:
diff changeset
   293
    assert(is_array(), "Must be an array");
489c9b5090e2 Initial load
duke
parents:
diff changeset
   294
    int index = 0;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   295
    while (name()->byte_at(index++) == '[');
489c9b5090e2 Initial load
duke
parents:
diff changeset
   296
    return index;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   297
  }
489c9b5090e2 Initial load
duke
parents:
diff changeset
   298
489c9b5090e2 Initial load
duke
parents:
diff changeset
   299
  void print_on(outputStream* st) const PRODUCT_RETURN;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   300
489c9b5090e2 Initial load
duke
parents:
diff changeset
   301
 private:
489c9b5090e2 Initial load
duke
parents:
diff changeset
   302
489c9b5090e2 Initial load
duke
parents:
diff changeset
   303
  bool is_reference_assignable_from(
489c9b5090e2 Initial load
duke
parents:
diff changeset
   304
    const VerificationType&, instanceKlassHandle, TRAPS) const;
489c9b5090e2 Initial load
duke
parents:
diff changeset
   305
};