Wed, 12 Oct 2011 21:00:13 -0700
7092712: JSR 292: unloaded invokedynamic call sites can lead to a crash with signature types not on BCP
Reviewed-by: jrose, never
duke@435 | 1 | /* |
twisti@3050 | 2 | * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. |
duke@435 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
duke@435 | 4 | * |
duke@435 | 5 | * This code is free software; you can redistribute it and/or modify it |
duke@435 | 6 | * under the terms of the GNU General Public License version 2 only, as |
duke@435 | 7 | * published by the Free Software Foundation. |
duke@435 | 8 | * |
duke@435 | 9 | * This code is distributed in the hope that it will be useful, but WITHOUT |
duke@435 | 10 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
duke@435 | 11 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
duke@435 | 12 | * version 2 for more details (a copy is included in the LICENSE file that |
duke@435 | 13 | * accompanied this code). |
duke@435 | 14 | * |
duke@435 | 15 | * You should have received a copy of the GNU General Public License version |
duke@435 | 16 | * 2 along with this work; if not, write to the Free Software Foundation, |
duke@435 | 17 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
duke@435 | 18 | * |
trims@1907 | 19 | * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
trims@1907 | 20 | * or visit www.oracle.com if you need additional information or have any |
trims@1907 | 21 | * questions. |
duke@435 | 22 | * |
duke@435 | 23 | */ |
duke@435 | 24 | |
stefank@2314 | 25 | #ifndef SHARE_VM_CI_CIFIELD_HPP |
stefank@2314 | 26 | #define SHARE_VM_CI_CIFIELD_HPP |
stefank@2314 | 27 | |
stefank@2314 | 28 | #include "ci/ciClassList.hpp" |
stefank@2314 | 29 | #include "ci/ciConstant.hpp" |
stefank@2314 | 30 | #include "ci/ciFlags.hpp" |
stefank@2314 | 31 | #include "ci/ciInstance.hpp" |
stefank@2314 | 32 | |
duke@435 | 33 | // ciField |
duke@435 | 34 | // |
duke@435 | 35 | // This class represents the result of a field lookup in the VM. |
duke@435 | 36 | // The lookup may not succeed, in which case the information in |
duke@435 | 37 | // the ciField will be incomplete. |
duke@435 | 38 | class ciField : public ResourceObj { |
duke@435 | 39 | CI_PACKAGE_ACCESS |
duke@435 | 40 | friend class ciEnv; |
duke@435 | 41 | friend class ciInstanceKlass; |
duke@435 | 42 | friend class NonStaticFieldFiller; |
duke@435 | 43 | |
duke@435 | 44 | private: |
duke@435 | 45 | ciFlags _flags; |
duke@435 | 46 | ciInstanceKlass* _holder; |
duke@435 | 47 | ciSymbol* _name; |
duke@435 | 48 | ciSymbol* _signature; |
duke@435 | 49 | ciType* _type; |
duke@435 | 50 | int _offset; |
duke@435 | 51 | bool _is_constant; |
duke@435 | 52 | ciInstanceKlass* _known_to_link_with; |
duke@435 | 53 | ciConstant _constant_value; |
duke@435 | 54 | |
duke@435 | 55 | // Used for will_link |
duke@435 | 56 | int _cp_index; |
duke@435 | 57 | |
duke@435 | 58 | ciType* compute_type(); |
duke@435 | 59 | ciType* compute_type_impl(); |
duke@435 | 60 | |
duke@435 | 61 | ciField(ciInstanceKlass* klass, int index); |
duke@435 | 62 | ciField(fieldDescriptor* fd); |
duke@435 | 63 | |
duke@435 | 64 | // shared constructor code |
duke@435 | 65 | void initialize_from(fieldDescriptor* fd); |
duke@435 | 66 | |
duke@435 | 67 | public: |
duke@435 | 68 | ciFlags flags() { return _flags; } |
duke@435 | 69 | |
duke@435 | 70 | // Of which klass is this field a member? |
duke@435 | 71 | // |
duke@435 | 72 | // Usage note: the declared holder of a field is the class |
duke@435 | 73 | // referenced by name in the bytecodes. The canonical holder |
duke@435 | 74 | // is the most general class which holds the field. This |
duke@435 | 75 | // method returns the canonical holder. The declared holder |
duke@435 | 76 | // can be accessed via a method in ciBytecodeStream. |
duke@435 | 77 | // |
duke@435 | 78 | // Ex. |
duke@435 | 79 | // class A { |
duke@435 | 80 | // public int f = 7; |
duke@435 | 81 | // } |
duke@435 | 82 | // class B extends A { |
duke@435 | 83 | // public void test() { |
duke@435 | 84 | // System.out.println(f); |
duke@435 | 85 | // } |
duke@435 | 86 | // } |
duke@435 | 87 | // |
duke@435 | 88 | // A java compiler is permitted to compile the access to |
duke@435 | 89 | // field f as: |
duke@435 | 90 | // |
duke@435 | 91 | // getfield B.f |
duke@435 | 92 | // |
duke@435 | 93 | // In that case the declared holder of f would be B and |
duke@435 | 94 | // the canonical holder of f would be A. |
duke@435 | 95 | ciInstanceKlass* holder() { return _holder; } |
duke@435 | 96 | |
duke@435 | 97 | // Name of this field? |
duke@435 | 98 | ciSymbol* name() { return _name; } |
duke@435 | 99 | |
duke@435 | 100 | // Signature of this field? |
duke@435 | 101 | ciSymbol* signature() { return _signature; } |
duke@435 | 102 | |
duke@435 | 103 | // Of what type is this field? |
duke@435 | 104 | ciType* type() { return (_type == NULL) ? compute_type() : _type; } |
duke@435 | 105 | |
duke@435 | 106 | // How is this field actually stored in memory? |
duke@435 | 107 | BasicType layout_type() { return type2field[(_type == NULL) ? T_OBJECT : _type->basic_type()]; } |
duke@435 | 108 | |
duke@435 | 109 | // How big is this field in memory? |
kvn@464 | 110 | int size_in_bytes() { return type2aelembytes(layout_type()); } |
duke@435 | 111 | |
duke@435 | 112 | // What is the offset of this field? |
duke@435 | 113 | int offset() { |
duke@435 | 114 | assert(_offset >= 1, "illegal call to offset()"); |
duke@435 | 115 | return _offset; |
duke@435 | 116 | } |
duke@435 | 117 | |
duke@435 | 118 | // Same question, explicit units. (Fields are aligned to the byte level.) |
duke@435 | 119 | int offset_in_bytes() { |
duke@435 | 120 | return offset(); |
duke@435 | 121 | } |
duke@435 | 122 | |
duke@435 | 123 | // Is this field shared? |
duke@435 | 124 | bool is_shared() { |
duke@435 | 125 | // non-static fields of shared holders are cached |
duke@435 | 126 | return _holder->is_shared() && !is_static(); |
duke@435 | 127 | } |
duke@435 | 128 | |
duke@435 | 129 | // Is this field a constant? |
duke@435 | 130 | // |
duke@435 | 131 | // Clarification: A field is considered constant if: |
duke@435 | 132 | // 1. The field is both static and final |
duke@435 | 133 | // 2. The canonical holder of the field has undergone |
duke@435 | 134 | // static initialization. |
duke@435 | 135 | // 3. If the field is an object or array, then the oop |
duke@435 | 136 | // in question is allocated in perm space. |
duke@435 | 137 | // 4. The field is not one of the special static/final |
duke@435 | 138 | // non-constant fields. These are java.lang.System.in |
duke@435 | 139 | // and java.lang.System.out. Abomination. |
duke@435 | 140 | // |
duke@435 | 141 | // Note: the check for case 4 is not yet implemented. |
duke@435 | 142 | bool is_constant() { return _is_constant; } |
duke@435 | 143 | |
duke@435 | 144 | // Get the constant value of this field. |
duke@435 | 145 | ciConstant constant_value() { |
twisti@1573 | 146 | assert(is_static() && is_constant(), "illegal call to constant_value()"); |
duke@435 | 147 | return _constant_value; |
duke@435 | 148 | } |
duke@435 | 149 | |
twisti@1573 | 150 | // Get the constant value of non-static final field in the given |
twisti@1573 | 151 | // object. |
twisti@1573 | 152 | ciConstant constant_value_of(ciObject* object) { |
twisti@1573 | 153 | assert(!is_static() && is_constant(), "only if field is non-static constant"); |
twisti@1573 | 154 | assert(object->is_instance(), "must be instance"); |
twisti@1573 | 155 | return object->as_instance()->field_value(this); |
twisti@1573 | 156 | } |
twisti@1573 | 157 | |
duke@435 | 158 | // Check for link time errors. Accessing a field from a |
duke@435 | 159 | // certain class via a certain bytecode may or may not be legal. |
duke@435 | 160 | // This call checks to see if an exception may be raised by |
duke@435 | 161 | // an access of this field. |
duke@435 | 162 | // |
duke@435 | 163 | // Usage note: if the same field is accessed multiple times |
duke@435 | 164 | // in the same compilation, will_link will need to be checked |
duke@435 | 165 | // at each point of access. |
duke@435 | 166 | bool will_link(ciInstanceKlass* accessing_klass, |
duke@435 | 167 | Bytecodes::Code bc); |
duke@435 | 168 | |
duke@435 | 169 | // Java access flags |
duke@435 | 170 | bool is_public () { return flags().is_public(); } |
duke@435 | 171 | bool is_private () { return flags().is_private(); } |
duke@435 | 172 | bool is_protected () { return flags().is_protected(); } |
duke@435 | 173 | bool is_static () { return flags().is_static(); } |
duke@435 | 174 | bool is_final () { return flags().is_final(); } |
duke@435 | 175 | bool is_volatile () { return flags().is_volatile(); } |
duke@435 | 176 | bool is_transient () { return flags().is_transient(); } |
duke@435 | 177 | |
twisti@3101 | 178 | bool is_call_site_target() { |
kvn@3107 | 179 | ciInstanceKlass* callsite_klass = CURRENT_ENV->CallSite_klass(); |
kvn@3107 | 180 | if (callsite_klass == NULL) |
kvn@3107 | 181 | return false; |
kvn@3107 | 182 | return (holder()->is_subclass_of(callsite_klass) && (name() == ciSymbol::target_name())); |
twisti@3101 | 183 | } |
twisti@3050 | 184 | |
duke@435 | 185 | // Debugging output |
duke@435 | 186 | void print(); |
duke@435 | 187 | void print_name_on(outputStream* st); |
duke@435 | 188 | }; |
stefank@2314 | 189 | |
stefank@2314 | 190 | #endif // SHARE_VM_CI_CIFIELD_HPP |