Mon, 23 Jun 2014 13:33:23 +0200
8046289: compiler/6340864/TestLongVect.java timeout with
Reviewed-by: iveresov, vlivanov
duke@435 | 1 | /* |
drchase@6680 | 2 | * Copyright (c) 1997, 2014, 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 | #include "precompiled.hpp" |
coleenp@4037 | 26 | #include "ci/ciMethodData.hpp" |
stefank@2314 | 27 | #include "ci/ciTypeFlow.hpp" |
stefank@2314 | 28 | #include "classfile/symbolTable.hpp" |
stefank@2314 | 29 | #include "classfile/systemDictionary.hpp" |
stefank@2314 | 30 | #include "compiler/compileLog.hpp" |
stefank@2314 | 31 | #include "libadt/dict.hpp" |
stefank@2314 | 32 | #include "memory/gcLocker.hpp" |
stefank@2314 | 33 | #include "memory/oopFactory.hpp" |
stefank@2314 | 34 | #include "memory/resourceArea.hpp" |
stefank@2314 | 35 | #include "oops/instanceKlass.hpp" |
never@2658 | 36 | #include "oops/instanceMirrorKlass.hpp" |
stefank@2314 | 37 | #include "oops/objArrayKlass.hpp" |
stefank@2314 | 38 | #include "oops/typeArrayKlass.hpp" |
stefank@2314 | 39 | #include "opto/matcher.hpp" |
stefank@2314 | 40 | #include "opto/node.hpp" |
stefank@2314 | 41 | #include "opto/opcodes.hpp" |
stefank@2314 | 42 | #include "opto/type.hpp" |
stefank@2314 | 43 | |
drchase@6680 | 44 | PRAGMA_FORMAT_MUTE_WARNINGS_FOR_GCC |
drchase@6680 | 45 | |
duke@435 | 46 | // Portions of code courtesy of Clifford Click |
duke@435 | 47 | |
duke@435 | 48 | // Optimization - Graph Style |
duke@435 | 49 | |
duke@435 | 50 | // Dictionary of types shared among compilations. |
duke@435 | 51 | Dict* Type::_shared_type_dict = NULL; |
duke@435 | 52 | |
duke@435 | 53 | // Array which maps compiler types to Basic Types |
coleenp@4037 | 54 | Type::TypeInfo Type::_type_info[Type::lastype] = { |
coleenp@4037 | 55 | { Bad, T_ILLEGAL, "bad", false, Node::NotAMachineReg, relocInfo::none }, // Bad |
coleenp@4037 | 56 | { Control, T_ILLEGAL, "control", false, 0, relocInfo::none }, // Control |
coleenp@4037 | 57 | { Bottom, T_VOID, "top", false, 0, relocInfo::none }, // Top |
coleenp@4037 | 58 | { Bad, T_INT, "int:", false, Op_RegI, relocInfo::none }, // Int |
coleenp@4037 | 59 | { Bad, T_LONG, "long:", false, Op_RegL, relocInfo::none }, // Long |
coleenp@4037 | 60 | { Half, T_VOID, "half", false, 0, relocInfo::none }, // Half |
coleenp@4037 | 61 | { Bad, T_NARROWOOP, "narrowoop:", false, Op_RegN, relocInfo::none }, // NarrowOop |
roland@4159 | 62 | { Bad, T_NARROWKLASS,"narrowklass:", false, Op_RegN, relocInfo::none }, // NarrowKlass |
coleenp@4037 | 63 | { Bad, T_ILLEGAL, "tuple:", false, Node::NotAMachineReg, relocInfo::none }, // Tuple |
coleenp@4037 | 64 | { Bad, T_ARRAY, "array:", false, Node::NotAMachineReg, relocInfo::none }, // Array |
coleenp@4037 | 65 | |
goetz@6487 | 66 | #ifdef SPARC |
goetz@6487 | 67 | { Bad, T_ILLEGAL, "vectors:", false, 0, relocInfo::none }, // VectorS |
goetz@6487 | 68 | { Bad, T_ILLEGAL, "vectord:", false, Op_RegD, relocInfo::none }, // VectorD |
goetz@6487 | 69 | { Bad, T_ILLEGAL, "vectorx:", false, 0, relocInfo::none }, // VectorX |
goetz@6487 | 70 | { Bad, T_ILLEGAL, "vectory:", false, 0, relocInfo::none }, // VectorY |
goetz@6487 | 71 | #elif defined(PPC64) |
goetz@6487 | 72 | { Bad, T_ILLEGAL, "vectors:", false, 0, relocInfo::none }, // VectorS |
goetz@6487 | 73 | { Bad, T_ILLEGAL, "vectord:", false, Op_RegL, relocInfo::none }, // VectorD |
goetz@6487 | 74 | { Bad, T_ILLEGAL, "vectorx:", false, 0, relocInfo::none }, // VectorX |
goetz@6487 | 75 | { Bad, T_ILLEGAL, "vectory:", false, 0, relocInfo::none }, // VectorY |
goetz@6487 | 76 | #else // all other |
coleenp@4037 | 77 | { Bad, T_ILLEGAL, "vectors:", false, Op_VecS, relocInfo::none }, // VectorS |
coleenp@4037 | 78 | { Bad, T_ILLEGAL, "vectord:", false, Op_VecD, relocInfo::none }, // VectorD |
coleenp@4037 | 79 | { Bad, T_ILLEGAL, "vectorx:", false, Op_VecX, relocInfo::none }, // VectorX |
coleenp@4037 | 80 | { Bad, T_ILLEGAL, "vectory:", false, Op_VecY, relocInfo::none }, // VectorY |
goetz@6487 | 81 | #endif |
coleenp@4037 | 82 | { Bad, T_ADDRESS, "anyptr:", false, Op_RegP, relocInfo::none }, // AnyPtr |
coleenp@4037 | 83 | { Bad, T_ADDRESS, "rawptr:", false, Op_RegP, relocInfo::none }, // RawPtr |
coleenp@4037 | 84 | { Bad, T_OBJECT, "oop:", true, Op_RegP, relocInfo::oop_type }, // OopPtr |
coleenp@4037 | 85 | { Bad, T_OBJECT, "inst:", true, Op_RegP, relocInfo::oop_type }, // InstPtr |
coleenp@4037 | 86 | { Bad, T_OBJECT, "ary:", true, Op_RegP, relocInfo::oop_type }, // AryPtr |
coleenp@4037 | 87 | { Bad, T_METADATA, "metadata:", false, Op_RegP, relocInfo::metadata_type }, // MetadataPtr |
coleenp@4037 | 88 | { Bad, T_METADATA, "klass:", false, Op_RegP, relocInfo::metadata_type }, // KlassPtr |
coleenp@4037 | 89 | { Bad, T_OBJECT, "func", false, 0, relocInfo::none }, // Function |
coleenp@4037 | 90 | { Abio, T_ILLEGAL, "abIO", false, 0, relocInfo::none }, // Abio |
coleenp@4037 | 91 | { Return_Address, T_ADDRESS, "return_address",false, Op_RegP, relocInfo::none }, // Return_Address |
coleenp@4037 | 92 | { Memory, T_ILLEGAL, "memory", false, 0, relocInfo::none }, // Memory |
coleenp@4037 | 93 | { FloatBot, T_FLOAT, "float_top", false, Op_RegF, relocInfo::none }, // FloatTop |
coleenp@4037 | 94 | { FloatCon, T_FLOAT, "ftcon:", false, Op_RegF, relocInfo::none }, // FloatCon |
coleenp@4037 | 95 | { FloatTop, T_FLOAT, "float", false, Op_RegF, relocInfo::none }, // FloatBot |
coleenp@4037 | 96 | { DoubleBot, T_DOUBLE, "double_top", false, Op_RegD, relocInfo::none }, // DoubleTop |
coleenp@4037 | 97 | { DoubleCon, T_DOUBLE, "dblcon:", false, Op_RegD, relocInfo::none }, // DoubleCon |
coleenp@4037 | 98 | { DoubleTop, T_DOUBLE, "double", false, Op_RegD, relocInfo::none }, // DoubleBot |
coleenp@4037 | 99 | { Top, T_ILLEGAL, "bottom", false, 0, relocInfo::none } // Bottom |
duke@435 | 100 | }; |
duke@435 | 101 | |
duke@435 | 102 | // Map ideal registers (machine types) to ideal types |
duke@435 | 103 | const Type *Type::mreg2type[_last_machine_leaf]; |
duke@435 | 104 | |
duke@435 | 105 | // Map basic types to canonical Type* pointers. |
duke@435 | 106 | const Type* Type:: _const_basic_type[T_CONFLICT+1]; |
duke@435 | 107 | |
duke@435 | 108 | // Map basic types to constant-zero Types. |
duke@435 | 109 | const Type* Type:: _zero_type[T_CONFLICT+1]; |
duke@435 | 110 | |
duke@435 | 111 | // Map basic types to array-body alias types. |
duke@435 | 112 | const TypeAryPtr* TypeAryPtr::_array_body_type[T_CONFLICT+1]; |
duke@435 | 113 | |
duke@435 | 114 | //============================================================================= |
duke@435 | 115 | // Convenience common pre-built types. |
duke@435 | 116 | const Type *Type::ABIO; // State-of-machine only |
duke@435 | 117 | const Type *Type::BOTTOM; // All values |
duke@435 | 118 | const Type *Type::CONTROL; // Control only |
duke@435 | 119 | const Type *Type::DOUBLE; // All doubles |
duke@435 | 120 | const Type *Type::FLOAT; // All floats |
duke@435 | 121 | const Type *Type::HALF; // Placeholder half of doublewide type |
duke@435 | 122 | const Type *Type::MEMORY; // Abstract store only |
duke@435 | 123 | const Type *Type::RETURN_ADDRESS; |
duke@435 | 124 | const Type *Type::TOP; // No values in set |
duke@435 | 125 | |
duke@435 | 126 | //------------------------------get_const_type--------------------------- |
duke@435 | 127 | const Type* Type::get_const_type(ciType* type) { |
duke@435 | 128 | if (type == NULL) { |
duke@435 | 129 | return NULL; |
duke@435 | 130 | } else if (type->is_primitive_type()) { |
duke@435 | 131 | return get_const_basic_type(type->basic_type()); |
duke@435 | 132 | } else { |
duke@435 | 133 | return TypeOopPtr::make_from_klass(type->as_klass()); |
duke@435 | 134 | } |
duke@435 | 135 | } |
duke@435 | 136 | |
duke@435 | 137 | //---------------------------array_element_basic_type--------------------------------- |
duke@435 | 138 | // Mapping to the array element's basic type. |
duke@435 | 139 | BasicType Type::array_element_basic_type() const { |
duke@435 | 140 | BasicType bt = basic_type(); |
duke@435 | 141 | if (bt == T_INT) { |
duke@435 | 142 | if (this == TypeInt::INT) return T_INT; |
duke@435 | 143 | if (this == TypeInt::CHAR) return T_CHAR; |
duke@435 | 144 | if (this == TypeInt::BYTE) return T_BYTE; |
duke@435 | 145 | if (this == TypeInt::BOOL) return T_BOOLEAN; |
duke@435 | 146 | if (this == TypeInt::SHORT) return T_SHORT; |
duke@435 | 147 | return T_VOID; |
duke@435 | 148 | } |
duke@435 | 149 | return bt; |
duke@435 | 150 | } |
duke@435 | 151 | |
duke@435 | 152 | //---------------------------get_typeflow_type--------------------------------- |
duke@435 | 153 | // Import a type produced by ciTypeFlow. |
duke@435 | 154 | const Type* Type::get_typeflow_type(ciType* type) { |
duke@435 | 155 | switch (type->basic_type()) { |
duke@435 | 156 | |
duke@435 | 157 | case ciTypeFlow::StateVector::T_BOTTOM: |
duke@435 | 158 | assert(type == ciTypeFlow::StateVector::bottom_type(), ""); |
duke@435 | 159 | return Type::BOTTOM; |
duke@435 | 160 | |
duke@435 | 161 | case ciTypeFlow::StateVector::T_TOP: |
duke@435 | 162 | assert(type == ciTypeFlow::StateVector::top_type(), ""); |
duke@435 | 163 | return Type::TOP; |
duke@435 | 164 | |
duke@435 | 165 | case ciTypeFlow::StateVector::T_NULL: |
duke@435 | 166 | assert(type == ciTypeFlow::StateVector::null_type(), ""); |
duke@435 | 167 | return TypePtr::NULL_PTR; |
duke@435 | 168 | |
duke@435 | 169 | case ciTypeFlow::StateVector::T_LONG2: |
duke@435 | 170 | // The ciTypeFlow pass pushes a long, then the half. |
duke@435 | 171 | // We do the same. |
duke@435 | 172 | assert(type == ciTypeFlow::StateVector::long2_type(), ""); |
duke@435 | 173 | return TypeInt::TOP; |
duke@435 | 174 | |
duke@435 | 175 | case ciTypeFlow::StateVector::T_DOUBLE2: |
duke@435 | 176 | // The ciTypeFlow pass pushes double, then the half. |
duke@435 | 177 | // Our convention is the same. |
duke@435 | 178 | assert(type == ciTypeFlow::StateVector::double2_type(), ""); |
duke@435 | 179 | return Type::TOP; |
duke@435 | 180 | |
duke@435 | 181 | case T_ADDRESS: |
duke@435 | 182 | assert(type->is_return_address(), ""); |
duke@435 | 183 | return TypeRawPtr::make((address)(intptr_t)type->as_return_address()->bci()); |
duke@435 | 184 | |
duke@435 | 185 | default: |
duke@435 | 186 | // make sure we did not mix up the cases: |
duke@435 | 187 | assert(type != ciTypeFlow::StateVector::bottom_type(), ""); |
duke@435 | 188 | assert(type != ciTypeFlow::StateVector::top_type(), ""); |
duke@435 | 189 | assert(type != ciTypeFlow::StateVector::null_type(), ""); |
duke@435 | 190 | assert(type != ciTypeFlow::StateVector::long2_type(), ""); |
duke@435 | 191 | assert(type != ciTypeFlow::StateVector::double2_type(), ""); |
duke@435 | 192 | assert(!type->is_return_address(), ""); |
duke@435 | 193 | |
duke@435 | 194 | return Type::get_const_type(type); |
duke@435 | 195 | } |
duke@435 | 196 | } |
duke@435 | 197 | |
duke@435 | 198 | |
vlivanov@5658 | 199 | //-----------------------make_from_constant------------------------------------ |
vlivanov@5658 | 200 | const Type* Type::make_from_constant(ciConstant constant, |
vlivanov@5658 | 201 | bool require_constant, bool is_autobox_cache) { |
vlivanov@5658 | 202 | switch (constant.basic_type()) { |
vlivanov@5658 | 203 | case T_BOOLEAN: return TypeInt::make(constant.as_boolean()); |
vlivanov@5658 | 204 | case T_CHAR: return TypeInt::make(constant.as_char()); |
vlivanov@5658 | 205 | case T_BYTE: return TypeInt::make(constant.as_byte()); |
vlivanov@5658 | 206 | case T_SHORT: return TypeInt::make(constant.as_short()); |
vlivanov@5658 | 207 | case T_INT: return TypeInt::make(constant.as_int()); |
vlivanov@5658 | 208 | case T_LONG: return TypeLong::make(constant.as_long()); |
vlivanov@5658 | 209 | case T_FLOAT: return TypeF::make(constant.as_float()); |
vlivanov@5658 | 210 | case T_DOUBLE: return TypeD::make(constant.as_double()); |
vlivanov@5658 | 211 | case T_ARRAY: |
vlivanov@5658 | 212 | case T_OBJECT: |
vlivanov@5658 | 213 | { |
vlivanov@5658 | 214 | // cases: |
vlivanov@5658 | 215 | // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0) |
vlivanov@5658 | 216 | // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2) |
vlivanov@5658 | 217 | // An oop is not scavengable if it is in the perm gen. |
vlivanov@5658 | 218 | ciObject* oop_constant = constant.as_object(); |
vlivanov@5658 | 219 | if (oop_constant->is_null_object()) { |
vlivanov@5658 | 220 | return Type::get_zero_type(T_OBJECT); |
vlivanov@5658 | 221 | } else if (require_constant || oop_constant->should_be_constant()) { |
vlivanov@5658 | 222 | return TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache); |
vlivanov@5658 | 223 | } |
vlivanov@5658 | 224 | } |
vlivanov@5658 | 225 | } |
vlivanov@5658 | 226 | // Fall through to failure |
vlivanov@5658 | 227 | return NULL; |
vlivanov@5658 | 228 | } |
vlivanov@5658 | 229 | |
vlivanov@5658 | 230 | |
duke@435 | 231 | //------------------------------make------------------------------------------- |
duke@435 | 232 | // Create a simple Type, with default empty symbol sets. Then hashcons it |
duke@435 | 233 | // and look for an existing copy in the type dictionary. |
duke@435 | 234 | const Type *Type::make( enum TYPES t ) { |
duke@435 | 235 | return (new Type(t))->hashcons(); |
duke@435 | 236 | } |
kvn@658 | 237 | |
duke@435 | 238 | //------------------------------cmp-------------------------------------------- |
duke@435 | 239 | int Type::cmp( const Type *const t1, const Type *const t2 ) { |
duke@435 | 240 | if( t1->_base != t2->_base ) |
duke@435 | 241 | return 1; // Missed badly |
duke@435 | 242 | assert(t1 != t2 || t1->eq(t2), "eq must be reflexive"); |
duke@435 | 243 | return !t1->eq(t2); // Return ZERO if equal |
duke@435 | 244 | } |
duke@435 | 245 | |
roland@6313 | 246 | const Type* Type::maybe_remove_speculative(bool include_speculative) const { |
roland@6313 | 247 | if (!include_speculative) { |
roland@6313 | 248 | return remove_speculative(); |
roland@6313 | 249 | } |
roland@6313 | 250 | return this; |
roland@6313 | 251 | } |
roland@6313 | 252 | |
duke@435 | 253 | //------------------------------hash------------------------------------------- |
duke@435 | 254 | int Type::uhash( const Type *const t ) { |
duke@435 | 255 | return t->hash(); |
duke@435 | 256 | } |
duke@435 | 257 | |
kvn@1975 | 258 | #define SMALLINT ((juint)3) // a value too insignificant to consider widening |
kvn@1975 | 259 | |
duke@435 | 260 | //--------------------------Initialize_shared---------------------------------- |
duke@435 | 261 | void Type::Initialize_shared(Compile* current) { |
duke@435 | 262 | // This method does not need to be locked because the first system |
duke@435 | 263 | // compilations (stub compilations) occur serially. If they are |
duke@435 | 264 | // changed to proceed in parallel, then this section will need |
duke@435 | 265 | // locking. |
duke@435 | 266 | |
duke@435 | 267 | Arena* save = current->type_arena(); |
zgu@7074 | 268 | Arena* shared_type_arena = new (mtCompiler)Arena(mtCompiler); |
duke@435 | 269 | |
duke@435 | 270 | current->set_type_arena(shared_type_arena); |
duke@435 | 271 | _shared_type_dict = |
duke@435 | 272 | new (shared_type_arena) Dict( (CmpKey)Type::cmp, (Hash)Type::uhash, |
duke@435 | 273 | shared_type_arena, 128 ); |
duke@435 | 274 | current->set_type_dict(_shared_type_dict); |
duke@435 | 275 | |
duke@435 | 276 | // Make shared pre-built types. |
duke@435 | 277 | CONTROL = make(Control); // Control only |
duke@435 | 278 | TOP = make(Top); // No values in set |
duke@435 | 279 | MEMORY = make(Memory); // Abstract store only |
duke@435 | 280 | ABIO = make(Abio); // State-of-machine only |
duke@435 | 281 | RETURN_ADDRESS=make(Return_Address); |
duke@435 | 282 | FLOAT = make(FloatBot); // All floats |
duke@435 | 283 | DOUBLE = make(DoubleBot); // All doubles |
duke@435 | 284 | BOTTOM = make(Bottom); // Everything |
duke@435 | 285 | HALF = make(Half); // Placeholder half of doublewide type |
duke@435 | 286 | |
duke@435 | 287 | TypeF::ZERO = TypeF::make(0.0); // Float 0 (positive zero) |
duke@435 | 288 | TypeF::ONE = TypeF::make(1.0); // Float 1 |
duke@435 | 289 | |
duke@435 | 290 | TypeD::ZERO = TypeD::make(0.0); // Double 0 (positive zero) |
duke@435 | 291 | TypeD::ONE = TypeD::make(1.0); // Double 1 |
duke@435 | 292 | |
duke@435 | 293 | TypeInt::MINUS_1 = TypeInt::make(-1); // -1 |
duke@435 | 294 | TypeInt::ZERO = TypeInt::make( 0); // 0 |
duke@435 | 295 | TypeInt::ONE = TypeInt::make( 1); // 1 |
duke@435 | 296 | TypeInt::BOOL = TypeInt::make(0,1, WidenMin); // 0 or 1, FALSE or TRUE. |
duke@435 | 297 | TypeInt::CC = TypeInt::make(-1, 1, WidenMin); // -1, 0 or 1, condition codes |
duke@435 | 298 | TypeInt::CC_LT = TypeInt::make(-1,-1, WidenMin); // == TypeInt::MINUS_1 |
duke@435 | 299 | TypeInt::CC_GT = TypeInt::make( 1, 1, WidenMin); // == TypeInt::ONE |
duke@435 | 300 | TypeInt::CC_EQ = TypeInt::make( 0, 0, WidenMin); // == TypeInt::ZERO |
duke@435 | 301 | TypeInt::CC_LE = TypeInt::make(-1, 0, WidenMin); |
duke@435 | 302 | TypeInt::CC_GE = TypeInt::make( 0, 1, WidenMin); // == TypeInt::BOOL |
duke@435 | 303 | TypeInt::BYTE = TypeInt::make(-128,127, WidenMin); // Bytes |
twisti@1059 | 304 | TypeInt::UBYTE = TypeInt::make(0, 255, WidenMin); // Unsigned Bytes |
duke@435 | 305 | TypeInt::CHAR = TypeInt::make(0,65535, WidenMin); // Java chars |
duke@435 | 306 | TypeInt::SHORT = TypeInt::make(-32768,32767, WidenMin); // Java shorts |
duke@435 | 307 | TypeInt::POS = TypeInt::make(0,max_jint, WidenMin); // Non-neg values |
duke@435 | 308 | TypeInt::POS1 = TypeInt::make(1,max_jint, WidenMin); // Positive values |
duke@435 | 309 | TypeInt::INT = TypeInt::make(min_jint,max_jint, WidenMax); // 32-bit integers |
duke@435 | 310 | TypeInt::SYMINT = TypeInt::make(-max_jint,max_jint,WidenMin); // symmetric range |
rbackman@6375 | 311 | TypeInt::TYPE_DOMAIN = TypeInt::INT; |
duke@435 | 312 | // CmpL is overloaded both as the bytecode computation returning |
duke@435 | 313 | // a trinary (-1,0,+1) integer result AND as an efficient long |
duke@435 | 314 | // compare returning optimizer ideal-type flags. |
duke@435 | 315 | assert( TypeInt::CC_LT == TypeInt::MINUS_1, "types must match for CmpL to work" ); |
duke@435 | 316 | assert( TypeInt::CC_GT == TypeInt::ONE, "types must match for CmpL to work" ); |
duke@435 | 317 | assert( TypeInt::CC_EQ == TypeInt::ZERO, "types must match for CmpL to work" ); |
duke@435 | 318 | assert( TypeInt::CC_GE == TypeInt::BOOL, "types must match for CmpL to work" ); |
kvn@1975 | 319 | assert( (juint)(TypeInt::CC->_hi - TypeInt::CC->_lo) <= SMALLINT, "CC is truly small"); |
duke@435 | 320 | |
duke@435 | 321 | TypeLong::MINUS_1 = TypeLong::make(-1); // -1 |
duke@435 | 322 | TypeLong::ZERO = TypeLong::make( 0); // 0 |
duke@435 | 323 | TypeLong::ONE = TypeLong::make( 1); // 1 |
duke@435 | 324 | TypeLong::POS = TypeLong::make(0,max_jlong, WidenMin); // Non-neg values |
duke@435 | 325 | TypeLong::LONG = TypeLong::make(min_jlong,max_jlong,WidenMax); // 64-bit integers |
duke@435 | 326 | TypeLong::INT = TypeLong::make((jlong)min_jint,(jlong)max_jint,WidenMin); |
duke@435 | 327 | TypeLong::UINT = TypeLong::make(0,(jlong)max_juint,WidenMin); |
rbackman@6375 | 328 | TypeLong::TYPE_DOMAIN = TypeLong::LONG; |
duke@435 | 329 | |
duke@435 | 330 | const Type **fboth =(const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); |
duke@435 | 331 | fboth[0] = Type::CONTROL; |
duke@435 | 332 | fboth[1] = Type::CONTROL; |
duke@435 | 333 | TypeTuple::IFBOTH = TypeTuple::make( 2, fboth ); |
duke@435 | 334 | |
duke@435 | 335 | const Type **ffalse =(const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); |
duke@435 | 336 | ffalse[0] = Type::CONTROL; |
duke@435 | 337 | ffalse[1] = Type::TOP; |
duke@435 | 338 | TypeTuple::IFFALSE = TypeTuple::make( 2, ffalse ); |
duke@435 | 339 | |
duke@435 | 340 | const Type **fneither =(const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); |
duke@435 | 341 | fneither[0] = Type::TOP; |
duke@435 | 342 | fneither[1] = Type::TOP; |
duke@435 | 343 | TypeTuple::IFNEITHER = TypeTuple::make( 2, fneither ); |
duke@435 | 344 | |
duke@435 | 345 | const Type **ftrue =(const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); |
duke@435 | 346 | ftrue[0] = Type::TOP; |
duke@435 | 347 | ftrue[1] = Type::CONTROL; |
duke@435 | 348 | TypeTuple::IFTRUE = TypeTuple::make( 2, ftrue ); |
duke@435 | 349 | |
duke@435 | 350 | const Type **floop =(const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); |
duke@435 | 351 | floop[0] = Type::CONTROL; |
duke@435 | 352 | floop[1] = TypeInt::INT; |
duke@435 | 353 | TypeTuple::LOOPBODY = TypeTuple::make( 2, floop ); |
duke@435 | 354 | |
duke@435 | 355 | TypePtr::NULL_PTR= TypePtr::make( AnyPtr, TypePtr::Null, 0 ); |
duke@435 | 356 | TypePtr::NOTNULL = TypePtr::make( AnyPtr, TypePtr::NotNull, OffsetBot ); |
duke@435 | 357 | TypePtr::BOTTOM = TypePtr::make( AnyPtr, TypePtr::BotPTR, OffsetBot ); |
duke@435 | 358 | |
duke@435 | 359 | TypeRawPtr::BOTTOM = TypeRawPtr::make( TypePtr::BotPTR ); |
duke@435 | 360 | TypeRawPtr::NOTNULL= TypeRawPtr::make( TypePtr::NotNull ); |
duke@435 | 361 | |
duke@435 | 362 | const Type **fmembar = TypeTuple::fields(0); |
duke@435 | 363 | TypeTuple::MEMBAR = TypeTuple::make(TypeFunc::Parms+0, fmembar); |
duke@435 | 364 | |
duke@435 | 365 | const Type **fsc = (const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); |
duke@435 | 366 | fsc[0] = TypeInt::CC; |
duke@435 | 367 | fsc[1] = Type::MEMORY; |
duke@435 | 368 | TypeTuple::STORECONDITIONAL = TypeTuple::make(2, fsc); |
duke@435 | 369 | |
duke@435 | 370 | TypeInstPtr::NOTNULL = TypeInstPtr::make(TypePtr::NotNull, current->env()->Object_klass()); |
duke@435 | 371 | TypeInstPtr::BOTTOM = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass()); |
duke@435 | 372 | TypeInstPtr::MIRROR = TypeInstPtr::make(TypePtr::NotNull, current->env()->Class_klass()); |
duke@435 | 373 | TypeInstPtr::MARK = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), |
duke@435 | 374 | false, 0, oopDesc::mark_offset_in_bytes()); |
duke@435 | 375 | TypeInstPtr::KLASS = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), |
duke@435 | 376 | false, 0, oopDesc::klass_offset_in_bytes()); |
roland@5991 | 377 | TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot, TypeOopPtr::InstanceBot, NULL); |
duke@435 | 378 | |
coleenp@4037 | 379 | TypeMetadataPtr::BOTTOM = TypeMetadataPtr::make(TypePtr::BotPTR, NULL, OffsetBot); |
coleenp@4037 | 380 | |
coleenp@548 | 381 | TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR ); |
coleenp@548 | 382 | TypeNarrowOop::BOTTOM = TypeNarrowOop::make( TypeInstPtr::BOTTOM ); |
coleenp@548 | 383 | |
roland@4159 | 384 | TypeNarrowKlass::NULL_PTR = TypeNarrowKlass::make( TypePtr::NULL_PTR ); |
roland@4159 | 385 | |
coleenp@548 | 386 | mreg2type[Op_Node] = Type::BOTTOM; |
coleenp@548 | 387 | mreg2type[Op_Set ] = 0; |
coleenp@548 | 388 | mreg2type[Op_RegN] = TypeNarrowOop::BOTTOM; |
coleenp@548 | 389 | mreg2type[Op_RegI] = TypeInt::INT; |
coleenp@548 | 390 | mreg2type[Op_RegP] = TypePtr::BOTTOM; |
coleenp@548 | 391 | mreg2type[Op_RegF] = Type::FLOAT; |
coleenp@548 | 392 | mreg2type[Op_RegD] = Type::DOUBLE; |
coleenp@548 | 393 | mreg2type[Op_RegL] = TypeLong::LONG; |
coleenp@548 | 394 | mreg2type[Op_RegFlags] = TypeInt::CC; |
coleenp@548 | 395 | |
kvn@2116 | 396 | TypeAryPtr::RANGE = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), NULL /* current->env()->Object_klass() */, false, arrayOopDesc::length_offset_in_bytes()); |
kvn@598 | 397 | |
kvn@598 | 398 | TypeAryPtr::NARROWOOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeNarrowOop::BOTTOM, TypeInt::POS), NULL /*ciArrayKlass::make(o)*/, false, Type::OffsetBot); |
kvn@598 | 399 | |
kvn@598 | 400 | #ifdef _LP64 |
kvn@598 | 401 | if (UseCompressedOops) { |
coleenp@4037 | 402 | assert(TypeAryPtr::NARROWOOPS->is_ptr_to_narrowoop(), "array of narrow oops must be ptr to narrow oop"); |
kvn@598 | 403 | TypeAryPtr::OOPS = TypeAryPtr::NARROWOOPS; |
kvn@598 | 404 | } else |
kvn@598 | 405 | #endif |
kvn@598 | 406 | { |
kvn@598 | 407 | // There is no shared klass for Object[]. See note in TypeAryPtr::klass(). |
kvn@598 | 408 | TypeAryPtr::OOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/, false, Type::OffsetBot); |
kvn@598 | 409 | } |
duke@435 | 410 | TypeAryPtr::BYTES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::BYTE ,TypeInt::POS), ciTypeArrayKlass::make(T_BYTE), true, Type::OffsetBot); |
duke@435 | 411 | TypeAryPtr::SHORTS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::SHORT ,TypeInt::POS), ciTypeArrayKlass::make(T_SHORT), true, Type::OffsetBot); |
duke@435 | 412 | TypeAryPtr::CHARS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::CHAR ,TypeInt::POS), ciTypeArrayKlass::make(T_CHAR), true, Type::OffsetBot); |
duke@435 | 413 | TypeAryPtr::INTS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::INT ,TypeInt::POS), ciTypeArrayKlass::make(T_INT), true, Type::OffsetBot); |
duke@435 | 414 | TypeAryPtr::LONGS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeLong::LONG ,TypeInt::POS), ciTypeArrayKlass::make(T_LONG), true, Type::OffsetBot); |
duke@435 | 415 | TypeAryPtr::FLOATS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::FLOAT ,TypeInt::POS), ciTypeArrayKlass::make(T_FLOAT), true, Type::OffsetBot); |
duke@435 | 416 | TypeAryPtr::DOUBLES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::DOUBLE ,TypeInt::POS), ciTypeArrayKlass::make(T_DOUBLE), true, Type::OffsetBot); |
duke@435 | 417 | |
kvn@598 | 418 | // Nobody should ask _array_body_type[T_NARROWOOP]. Use NULL as assert. |
kvn@598 | 419 | TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL; |
duke@435 | 420 | TypeAryPtr::_array_body_type[T_OBJECT] = TypeAryPtr::OOPS; |
kvn@598 | 421 | TypeAryPtr::_array_body_type[T_ARRAY] = TypeAryPtr::OOPS; // arrays are stored in oop arrays |
duke@435 | 422 | TypeAryPtr::_array_body_type[T_BYTE] = TypeAryPtr::BYTES; |
duke@435 | 423 | TypeAryPtr::_array_body_type[T_BOOLEAN] = TypeAryPtr::BYTES; // boolean[] is a byte array |
duke@435 | 424 | TypeAryPtr::_array_body_type[T_SHORT] = TypeAryPtr::SHORTS; |
duke@435 | 425 | TypeAryPtr::_array_body_type[T_CHAR] = TypeAryPtr::CHARS; |
duke@435 | 426 | TypeAryPtr::_array_body_type[T_INT] = TypeAryPtr::INTS; |
duke@435 | 427 | TypeAryPtr::_array_body_type[T_LONG] = TypeAryPtr::LONGS; |
duke@435 | 428 | TypeAryPtr::_array_body_type[T_FLOAT] = TypeAryPtr::FLOATS; |
duke@435 | 429 | TypeAryPtr::_array_body_type[T_DOUBLE] = TypeAryPtr::DOUBLES; |
duke@435 | 430 | |
duke@435 | 431 | TypeKlassPtr::OBJECT = TypeKlassPtr::make( TypePtr::NotNull, current->env()->Object_klass(), 0 ); |
duke@435 | 432 | TypeKlassPtr::OBJECT_OR_NULL = TypeKlassPtr::make( TypePtr::BotPTR, current->env()->Object_klass(), 0 ); |
duke@435 | 433 | |
duke@435 | 434 | const Type **fi2c = TypeTuple::fields(2); |
coleenp@4037 | 435 | fi2c[TypeFunc::Parms+0] = TypeInstPtr::BOTTOM; // Method* |
duke@435 | 436 | fi2c[TypeFunc::Parms+1] = TypeRawPtr::BOTTOM; // argument pointer |
duke@435 | 437 | TypeTuple::START_I2C = TypeTuple::make(TypeFunc::Parms+2, fi2c); |
duke@435 | 438 | |
duke@435 | 439 | const Type **intpair = TypeTuple::fields(2); |
duke@435 | 440 | intpair[0] = TypeInt::INT; |
duke@435 | 441 | intpair[1] = TypeInt::INT; |
duke@435 | 442 | TypeTuple::INT_PAIR = TypeTuple::make(2, intpair); |
duke@435 | 443 | |
duke@435 | 444 | const Type **longpair = TypeTuple::fields(2); |
duke@435 | 445 | longpair[0] = TypeLong::LONG; |
duke@435 | 446 | longpair[1] = TypeLong::LONG; |
duke@435 | 447 | TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair); |
duke@435 | 448 | |
rbackman@5791 | 449 | const Type **intccpair = TypeTuple::fields(2); |
rbackman@5791 | 450 | intccpair[0] = TypeInt::INT; |
rbackman@5791 | 451 | intccpair[1] = TypeInt::CC; |
rbackman@5791 | 452 | TypeTuple::INT_CC_PAIR = TypeTuple::make(2, intccpair); |
rbackman@5791 | 453 | |
rbackman@5997 | 454 | const Type **longccpair = TypeTuple::fields(2); |
rbackman@5997 | 455 | longccpair[0] = TypeLong::LONG; |
rbackman@5997 | 456 | longccpair[1] = TypeInt::CC; |
rbackman@5997 | 457 | TypeTuple::LONG_CC_PAIR = TypeTuple::make(2, longccpair); |
rbackman@5997 | 458 | |
roland@4159 | 459 | _const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM; |
roland@4159 | 460 | _const_basic_type[T_NARROWKLASS] = Type::BOTTOM; |
roland@4159 | 461 | _const_basic_type[T_BOOLEAN] = TypeInt::BOOL; |
roland@4159 | 462 | _const_basic_type[T_CHAR] = TypeInt::CHAR; |
roland@4159 | 463 | _const_basic_type[T_BYTE] = TypeInt::BYTE; |
roland@4159 | 464 | _const_basic_type[T_SHORT] = TypeInt::SHORT; |
roland@4159 | 465 | _const_basic_type[T_INT] = TypeInt::INT; |
roland@4159 | 466 | _const_basic_type[T_LONG] = TypeLong::LONG; |
roland@4159 | 467 | _const_basic_type[T_FLOAT] = Type::FLOAT; |
roland@4159 | 468 | _const_basic_type[T_DOUBLE] = Type::DOUBLE; |
roland@4159 | 469 | _const_basic_type[T_OBJECT] = TypeInstPtr::BOTTOM; |
roland@4159 | 470 | _const_basic_type[T_ARRAY] = TypeInstPtr::BOTTOM; // there is no separate bottom for arrays |
roland@4159 | 471 | _const_basic_type[T_VOID] = TypePtr::NULL_PTR; // reflection represents void this way |
roland@4159 | 472 | _const_basic_type[T_ADDRESS] = TypeRawPtr::BOTTOM; // both interpreter return addresses & random raw ptrs |
roland@4159 | 473 | _const_basic_type[T_CONFLICT] = Type::BOTTOM; // why not? |
roland@4159 | 474 | |
roland@4159 | 475 | _zero_type[T_NARROWOOP] = TypeNarrowOop::NULL_PTR; |
roland@4159 | 476 | _zero_type[T_NARROWKLASS] = TypeNarrowKlass::NULL_PTR; |
roland@4159 | 477 | _zero_type[T_BOOLEAN] = TypeInt::ZERO; // false == 0 |
roland@4159 | 478 | _zero_type[T_CHAR] = TypeInt::ZERO; // '\0' == 0 |
roland@4159 | 479 | _zero_type[T_BYTE] = TypeInt::ZERO; // 0x00 == 0 |
roland@4159 | 480 | _zero_type[T_SHORT] = TypeInt::ZERO; // 0x0000 == 0 |
roland@4159 | 481 | _zero_type[T_INT] = TypeInt::ZERO; |
roland@4159 | 482 | _zero_type[T_LONG] = TypeLong::ZERO; |
roland@4159 | 483 | _zero_type[T_FLOAT] = TypeF::ZERO; |
roland@4159 | 484 | _zero_type[T_DOUBLE] = TypeD::ZERO; |
roland@4159 | 485 | _zero_type[T_OBJECT] = TypePtr::NULL_PTR; |
roland@4159 | 486 | _zero_type[T_ARRAY] = TypePtr::NULL_PTR; // null array is null oop |
roland@4159 | 487 | _zero_type[T_ADDRESS] = TypePtr::NULL_PTR; // raw pointers use the same null |
roland@4159 | 488 | _zero_type[T_VOID] = Type::TOP; // the only void value is no value at all |
duke@435 | 489 | |
duke@435 | 490 | // get_zero_type() should not happen for T_CONFLICT |
duke@435 | 491 | _zero_type[T_CONFLICT]= NULL; |
duke@435 | 492 | |
kvn@3882 | 493 | // Vector predefined types, it needs initialized _const_basic_type[]. |
kvn@3882 | 494 | if (Matcher::vector_size_supported(T_BYTE,4)) { |
kvn@3882 | 495 | TypeVect::VECTS = TypeVect::make(T_BYTE,4); |
kvn@3882 | 496 | } |
kvn@3882 | 497 | if (Matcher::vector_size_supported(T_FLOAT,2)) { |
kvn@3882 | 498 | TypeVect::VECTD = TypeVect::make(T_FLOAT,2); |
kvn@3882 | 499 | } |
kvn@3882 | 500 | if (Matcher::vector_size_supported(T_FLOAT,4)) { |
kvn@3882 | 501 | TypeVect::VECTX = TypeVect::make(T_FLOAT,4); |
kvn@3882 | 502 | } |
kvn@3882 | 503 | if (Matcher::vector_size_supported(T_FLOAT,8)) { |
kvn@3882 | 504 | TypeVect::VECTY = TypeVect::make(T_FLOAT,8); |
kvn@3882 | 505 | } |
kvn@3882 | 506 | mreg2type[Op_VecS] = TypeVect::VECTS; |
kvn@3882 | 507 | mreg2type[Op_VecD] = TypeVect::VECTD; |
kvn@3882 | 508 | mreg2type[Op_VecX] = TypeVect::VECTX; |
kvn@3882 | 509 | mreg2type[Op_VecY] = TypeVect::VECTY; |
kvn@3882 | 510 | |
duke@435 | 511 | // Restore working type arena. |
duke@435 | 512 | current->set_type_arena(save); |
duke@435 | 513 | current->set_type_dict(NULL); |
duke@435 | 514 | } |
duke@435 | 515 | |
duke@435 | 516 | //------------------------------Initialize------------------------------------- |
duke@435 | 517 | void Type::Initialize(Compile* current) { |
duke@435 | 518 | assert(current->type_arena() != NULL, "must have created type arena"); |
duke@435 | 519 | |
duke@435 | 520 | if (_shared_type_dict == NULL) { |
duke@435 | 521 | Initialize_shared(current); |
duke@435 | 522 | } |
duke@435 | 523 | |
duke@435 | 524 | Arena* type_arena = current->type_arena(); |
duke@435 | 525 | |
duke@435 | 526 | // Create the hash-cons'ing dictionary with top-level storage allocation |
duke@435 | 527 | Dict *tdic = new (type_arena) Dict( (CmpKey)Type::cmp,(Hash)Type::uhash, type_arena, 128 ); |
duke@435 | 528 | current->set_type_dict(tdic); |
duke@435 | 529 | |
duke@435 | 530 | // Transfer the shared types. |
duke@435 | 531 | DictI i(_shared_type_dict); |
duke@435 | 532 | for( ; i.test(); ++i ) { |
duke@435 | 533 | Type* t = (Type*)i._value; |
duke@435 | 534 | tdic->Insert(t,t); // New Type, insert into Type table |
duke@435 | 535 | } |
duke@435 | 536 | } |
duke@435 | 537 | |
duke@435 | 538 | //------------------------------hashcons--------------------------------------- |
duke@435 | 539 | // Do the hash-cons trick. If the Type already exists in the type table, |
duke@435 | 540 | // delete the current Type and return the existing Type. Otherwise stick the |
duke@435 | 541 | // current Type in the Type table. |
duke@435 | 542 | const Type *Type::hashcons(void) { |
duke@435 | 543 | debug_only(base()); // Check the assertion in Type::base(). |
duke@435 | 544 | // Look up the Type in the Type dictionary |
duke@435 | 545 | Dict *tdic = type_dict(); |
duke@435 | 546 | Type* old = (Type*)(tdic->Insert(this, this, false)); |
duke@435 | 547 | if( old ) { // Pre-existing Type? |
duke@435 | 548 | if( old != this ) // Yes, this guy is not the pre-existing? |
duke@435 | 549 | delete this; // Yes, Nuke this guy |
duke@435 | 550 | assert( old->_dual, "" ); |
duke@435 | 551 | return old; // Return pre-existing |
duke@435 | 552 | } |
duke@435 | 553 | |
duke@435 | 554 | // Every type has a dual (to make my lattice symmetric). |
duke@435 | 555 | // Since we just discovered a new Type, compute its dual right now. |
duke@435 | 556 | assert( !_dual, "" ); // No dual yet |
duke@435 | 557 | _dual = xdual(); // Compute the dual |
duke@435 | 558 | if( cmp(this,_dual)==0 ) { // Handle self-symmetric |
duke@435 | 559 | _dual = this; |
duke@435 | 560 | return this; |
duke@435 | 561 | } |
duke@435 | 562 | assert( !_dual->_dual, "" ); // No reverse dual yet |
duke@435 | 563 | assert( !(*tdic)[_dual], "" ); // Dual not in type system either |
duke@435 | 564 | // New Type, insert into Type table |
duke@435 | 565 | tdic->Insert((void*)_dual,(void*)_dual); |
duke@435 | 566 | ((Type*)_dual)->_dual = this; // Finish up being symmetric |
duke@435 | 567 | #ifdef ASSERT |
duke@435 | 568 | Type *dual_dual = (Type*)_dual->xdual(); |
duke@435 | 569 | assert( eq(dual_dual), "xdual(xdual()) should be identity" ); |
duke@435 | 570 | delete dual_dual; |
duke@435 | 571 | #endif |
duke@435 | 572 | return this; // Return new Type |
duke@435 | 573 | } |
duke@435 | 574 | |
duke@435 | 575 | //------------------------------eq--------------------------------------------- |
duke@435 | 576 | // Structural equality check for Type representations |
duke@435 | 577 | bool Type::eq( const Type * ) const { |
duke@435 | 578 | return true; // Nothing else can go wrong |
duke@435 | 579 | } |
duke@435 | 580 | |
duke@435 | 581 | //------------------------------hash------------------------------------------- |
duke@435 | 582 | // Type-specific hashing function. |
duke@435 | 583 | int Type::hash(void) const { |
duke@435 | 584 | return _base; |
duke@435 | 585 | } |
duke@435 | 586 | |
duke@435 | 587 | //------------------------------is_finite-------------------------------------- |
duke@435 | 588 | // Has a finite value |
duke@435 | 589 | bool Type::is_finite() const { |
duke@435 | 590 | return false; |
duke@435 | 591 | } |
duke@435 | 592 | |
duke@435 | 593 | //------------------------------is_nan----------------------------------------- |
duke@435 | 594 | // Is not a number (NaN) |
duke@435 | 595 | bool Type::is_nan() const { |
duke@435 | 596 | return false; |
duke@435 | 597 | } |
duke@435 | 598 | |
kvn@1255 | 599 | //----------------------interface_vs_oop--------------------------------------- |
kvn@1255 | 600 | #ifdef ASSERT |
roland@5991 | 601 | bool Type::interface_vs_oop_helper(const Type *t) const { |
kvn@1255 | 602 | bool result = false; |
kvn@1255 | 603 | |
kvn@1427 | 604 | const TypePtr* this_ptr = this->make_ptr(); // In case it is narrow_oop |
kvn@1427 | 605 | const TypePtr* t_ptr = t->make_ptr(); |
kvn@1427 | 606 | if( this_ptr == NULL || t_ptr == NULL ) |
kvn@1427 | 607 | return result; |
kvn@1427 | 608 | |
kvn@1427 | 609 | const TypeInstPtr* this_inst = this_ptr->isa_instptr(); |
kvn@1427 | 610 | const TypeInstPtr* t_inst = t_ptr->isa_instptr(); |
kvn@1255 | 611 | if( this_inst && this_inst->is_loaded() && t_inst && t_inst->is_loaded() ) { |
kvn@1255 | 612 | bool this_interface = this_inst->klass()->is_interface(); |
kvn@1255 | 613 | bool t_interface = t_inst->klass()->is_interface(); |
kvn@1255 | 614 | result = this_interface ^ t_interface; |
kvn@1255 | 615 | } |
kvn@1255 | 616 | |
kvn@1255 | 617 | return result; |
kvn@1255 | 618 | } |
roland@5991 | 619 | |
roland@5991 | 620 | bool Type::interface_vs_oop(const Type *t) const { |
roland@5991 | 621 | if (interface_vs_oop_helper(t)) { |
roland@5991 | 622 | return true; |
roland@5991 | 623 | } |
roland@5991 | 624 | // Now check the speculative parts as well |
roland@5991 | 625 | const TypeOopPtr* this_spec = isa_oopptr() != NULL ? isa_oopptr()->speculative() : NULL; |
roland@5991 | 626 | const TypeOopPtr* t_spec = t->isa_oopptr() != NULL ? t->isa_oopptr()->speculative() : NULL; |
roland@5991 | 627 | if (this_spec != NULL && t_spec != NULL) { |
roland@5991 | 628 | if (this_spec->interface_vs_oop_helper(t_spec)) { |
roland@5991 | 629 | return true; |
roland@5991 | 630 | } |
roland@5991 | 631 | return false; |
roland@5991 | 632 | } |
roland@5991 | 633 | if (this_spec != NULL && this_spec->interface_vs_oop_helper(t)) { |
roland@5991 | 634 | return true; |
roland@5991 | 635 | } |
roland@5991 | 636 | if (t_spec != NULL && interface_vs_oop_helper(t_spec)) { |
roland@5991 | 637 | return true; |
roland@5991 | 638 | } |
roland@5991 | 639 | return false; |
roland@5991 | 640 | } |
roland@5991 | 641 | |
kvn@1255 | 642 | #endif |
kvn@1255 | 643 | |
duke@435 | 644 | //------------------------------meet------------------------------------------- |
duke@435 | 645 | // Compute the MEET of two types. NOT virtual. It enforces that meet is |
duke@435 | 646 | // commutative and the lattice is symmetric. |
roland@6313 | 647 | const Type *Type::meet_helper(const Type *t, bool include_speculative) const { |
coleenp@548 | 648 | if (isa_narrowoop() && t->isa_narrowoop()) { |
roland@6313 | 649 | const Type* result = make_ptr()->meet_helper(t->make_ptr(), include_speculative); |
kvn@656 | 650 | return result->make_narrowoop(); |
coleenp@548 | 651 | } |
roland@4159 | 652 | if (isa_narrowklass() && t->isa_narrowklass()) { |
roland@6313 | 653 | const Type* result = make_ptr()->meet_helper(t->make_ptr(), include_speculative); |
roland@4159 | 654 | return result->make_narrowklass(); |
roland@4159 | 655 | } |
coleenp@548 | 656 | |
roland@6313 | 657 | const Type *this_t = maybe_remove_speculative(include_speculative); |
roland@6313 | 658 | t = t->maybe_remove_speculative(include_speculative); |
roland@6313 | 659 | |
roland@6313 | 660 | const Type *mt = this_t->xmeet(t); |
coleenp@548 | 661 | if (isa_narrowoop() || t->isa_narrowoop()) return mt; |
roland@4159 | 662 | if (isa_narrowklass() || t->isa_narrowklass()) return mt; |
duke@435 | 663 | #ifdef ASSERT |
roland@6313 | 664 | assert(mt == t->xmeet(this_t), "meet not commutative"); |
duke@435 | 665 | const Type* dual_join = mt->_dual; |
duke@435 | 666 | const Type *t2t = dual_join->xmeet(t->_dual); |
roland@6313 | 667 | const Type *t2this = dual_join->xmeet(this_t->_dual); |
duke@435 | 668 | |
duke@435 | 669 | // Interface meet Oop is Not Symmetric: |
duke@435 | 670 | // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull |
duke@435 | 671 | // Interface:NotNull meet Oop:NotNull == java/lang/Object:NotNull |
kvn@1255 | 672 | |
roland@6313 | 673 | if( !interface_vs_oop(t) && (t2t != t->_dual || t2this != this_t->_dual) ) { |
duke@435 | 674 | tty->print_cr("=== Meet Not Symmetric ==="); |
roland@6313 | 675 | tty->print("t = "); t->dump(); tty->cr(); |
roland@6313 | 676 | tty->print("this= "); this_t->dump(); tty->cr(); |
roland@6313 | 677 | tty->print("mt=(t meet this)= "); mt->dump(); tty->cr(); |
roland@6313 | 678 | |
roland@6313 | 679 | tty->print("t_dual= "); t->_dual->dump(); tty->cr(); |
roland@6313 | 680 | tty->print("this_dual= "); this_t->_dual->dump(); tty->cr(); |
roland@6313 | 681 | tty->print("mt_dual= "); mt->_dual->dump(); tty->cr(); |
roland@6313 | 682 | |
roland@6313 | 683 | tty->print("mt_dual meet t_dual= "); t2t ->dump(); tty->cr(); |
roland@6313 | 684 | tty->print("mt_dual meet this_dual= "); t2this ->dump(); tty->cr(); |
duke@435 | 685 | |
duke@435 | 686 | fatal("meet not symmetric" ); |
duke@435 | 687 | } |
duke@435 | 688 | #endif |
duke@435 | 689 | return mt; |
duke@435 | 690 | } |
duke@435 | 691 | |
duke@435 | 692 | //------------------------------xmeet------------------------------------------ |
duke@435 | 693 | // Compute the MEET of two types. It returns a new Type object. |
duke@435 | 694 | const Type *Type::xmeet( const Type *t ) const { |
duke@435 | 695 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 696 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 697 | |
duke@435 | 698 | // Meeting TOP with anything? |
duke@435 | 699 | if( _base == Top ) return t; |
duke@435 | 700 | |
duke@435 | 701 | // Meeting BOTTOM with anything? |
duke@435 | 702 | if( _base == Bottom ) return BOTTOM; |
duke@435 | 703 | |
duke@435 | 704 | // Current "this->_base" is one of: Bad, Multi, Control, Top, |
duke@435 | 705 | // Abio, Abstore, Floatxxx, Doublexxx, Bottom, lastype. |
duke@435 | 706 | switch (t->base()) { // Switch on original type |
duke@435 | 707 | |
duke@435 | 708 | // Cut in half the number of cases I must handle. Only need cases for when |
duke@435 | 709 | // the given enum "t->type" is less than or equal to the local enum "type". |
duke@435 | 710 | case FloatCon: |
duke@435 | 711 | case DoubleCon: |
duke@435 | 712 | case Int: |
duke@435 | 713 | case Long: |
duke@435 | 714 | return t->xmeet(this); |
duke@435 | 715 | |
duke@435 | 716 | case OopPtr: |
duke@435 | 717 | return t->xmeet(this); |
duke@435 | 718 | |
duke@435 | 719 | case InstPtr: |
duke@435 | 720 | return t->xmeet(this); |
duke@435 | 721 | |
coleenp@4037 | 722 | case MetadataPtr: |
duke@435 | 723 | case KlassPtr: |
duke@435 | 724 | return t->xmeet(this); |
duke@435 | 725 | |
duke@435 | 726 | case AryPtr: |
duke@435 | 727 | return t->xmeet(this); |
duke@435 | 728 | |
coleenp@548 | 729 | case NarrowOop: |
coleenp@548 | 730 | return t->xmeet(this); |
coleenp@548 | 731 | |
roland@4159 | 732 | case NarrowKlass: |
roland@4159 | 733 | return t->xmeet(this); |
roland@4159 | 734 | |
duke@435 | 735 | case Bad: // Type check |
duke@435 | 736 | default: // Bogus type not in lattice |
duke@435 | 737 | typerr(t); |
duke@435 | 738 | return Type::BOTTOM; |
duke@435 | 739 | |
duke@435 | 740 | case Bottom: // Ye Olde Default |
duke@435 | 741 | return t; |
duke@435 | 742 | |
duke@435 | 743 | case FloatTop: |
duke@435 | 744 | if( _base == FloatTop ) return this; |
duke@435 | 745 | case FloatBot: // Float |
duke@435 | 746 | if( _base == FloatBot || _base == FloatTop ) return FLOAT; |
duke@435 | 747 | if( _base == DoubleTop || _base == DoubleBot ) return Type::BOTTOM; |
duke@435 | 748 | typerr(t); |
duke@435 | 749 | return Type::BOTTOM; |
duke@435 | 750 | |
duke@435 | 751 | case DoubleTop: |
duke@435 | 752 | if( _base == DoubleTop ) return this; |
duke@435 | 753 | case DoubleBot: // Double |
duke@435 | 754 | if( _base == DoubleBot || _base == DoubleTop ) return DOUBLE; |
duke@435 | 755 | if( _base == FloatTop || _base == FloatBot ) return Type::BOTTOM; |
duke@435 | 756 | typerr(t); |
duke@435 | 757 | return Type::BOTTOM; |
duke@435 | 758 | |
duke@435 | 759 | // These next few cases must match exactly or it is a compile-time error. |
duke@435 | 760 | case Control: // Control of code |
duke@435 | 761 | case Abio: // State of world outside of program |
duke@435 | 762 | case Memory: |
duke@435 | 763 | if( _base == t->_base ) return this; |
duke@435 | 764 | typerr(t); |
duke@435 | 765 | return Type::BOTTOM; |
duke@435 | 766 | |
duke@435 | 767 | case Top: // Top of the lattice |
duke@435 | 768 | return this; |
duke@435 | 769 | } |
duke@435 | 770 | |
duke@435 | 771 | // The type is unchanged |
duke@435 | 772 | return this; |
duke@435 | 773 | } |
duke@435 | 774 | |
duke@435 | 775 | //-----------------------------filter------------------------------------------ |
roland@6313 | 776 | const Type *Type::filter_helper(const Type *kills, bool include_speculative) const { |
roland@6313 | 777 | const Type* ft = join_helper(kills, include_speculative); |
duke@435 | 778 | if (ft->empty()) |
duke@435 | 779 | return Type::TOP; // Canonical empty value |
duke@435 | 780 | return ft; |
duke@435 | 781 | } |
duke@435 | 782 | |
duke@435 | 783 | //------------------------------xdual------------------------------------------ |
duke@435 | 784 | // Compute dual right now. |
duke@435 | 785 | const Type::TYPES Type::dual_type[Type::lastype] = { |
duke@435 | 786 | Bad, // Bad |
duke@435 | 787 | Control, // Control |
duke@435 | 788 | Bottom, // Top |
duke@435 | 789 | Bad, // Int - handled in v-call |
duke@435 | 790 | Bad, // Long - handled in v-call |
duke@435 | 791 | Half, // Half |
coleenp@548 | 792 | Bad, // NarrowOop - handled in v-call |
roland@4159 | 793 | Bad, // NarrowKlass - handled in v-call |
duke@435 | 794 | |
duke@435 | 795 | Bad, // Tuple - handled in v-call |
duke@435 | 796 | Bad, // Array - handled in v-call |
kvn@3882 | 797 | Bad, // VectorS - handled in v-call |
kvn@3882 | 798 | Bad, // VectorD - handled in v-call |
kvn@3882 | 799 | Bad, // VectorX - handled in v-call |
kvn@3882 | 800 | Bad, // VectorY - handled in v-call |
duke@435 | 801 | |
duke@435 | 802 | Bad, // AnyPtr - handled in v-call |
duke@435 | 803 | Bad, // RawPtr - handled in v-call |
duke@435 | 804 | Bad, // OopPtr - handled in v-call |
duke@435 | 805 | Bad, // InstPtr - handled in v-call |
duke@435 | 806 | Bad, // AryPtr - handled in v-call |
coleenp@4037 | 807 | |
coleenp@4037 | 808 | Bad, // MetadataPtr - handled in v-call |
duke@435 | 809 | Bad, // KlassPtr - handled in v-call |
duke@435 | 810 | |
duke@435 | 811 | Bad, // Function - handled in v-call |
duke@435 | 812 | Abio, // Abio |
duke@435 | 813 | Return_Address,// Return_Address |
duke@435 | 814 | Memory, // Memory |
duke@435 | 815 | FloatBot, // FloatTop |
duke@435 | 816 | FloatCon, // FloatCon |
duke@435 | 817 | FloatTop, // FloatBot |
duke@435 | 818 | DoubleBot, // DoubleTop |
duke@435 | 819 | DoubleCon, // DoubleCon |
duke@435 | 820 | DoubleTop, // DoubleBot |
duke@435 | 821 | Top // Bottom |
duke@435 | 822 | }; |
duke@435 | 823 | |
duke@435 | 824 | const Type *Type::xdual() const { |
duke@435 | 825 | // Note: the base() accessor asserts the sanity of _base. |
coleenp@4037 | 826 | assert(_type_info[base()].dual_type != Bad, "implement with v-call"); |
coleenp@4037 | 827 | return new Type(_type_info[_base].dual_type); |
duke@435 | 828 | } |
duke@435 | 829 | |
duke@435 | 830 | //------------------------------has_memory------------------------------------- |
duke@435 | 831 | bool Type::has_memory() const { |
duke@435 | 832 | Type::TYPES tx = base(); |
duke@435 | 833 | if (tx == Memory) return true; |
duke@435 | 834 | if (tx == Tuple) { |
duke@435 | 835 | const TypeTuple *t = is_tuple(); |
duke@435 | 836 | for (uint i=0; i < t->cnt(); i++) { |
duke@435 | 837 | tx = t->field_at(i)->base(); |
duke@435 | 838 | if (tx == Memory) return true; |
duke@435 | 839 | } |
duke@435 | 840 | } |
duke@435 | 841 | return false; |
duke@435 | 842 | } |
duke@435 | 843 | |
duke@435 | 844 | #ifndef PRODUCT |
duke@435 | 845 | //------------------------------dump2------------------------------------------ |
duke@435 | 846 | void Type::dump2( Dict &d, uint depth, outputStream *st ) const { |
drchase@6680 | 847 | st->print("%s", _type_info[_base].msg); |
duke@435 | 848 | } |
duke@435 | 849 | |
duke@435 | 850 | //------------------------------dump------------------------------------------- |
duke@435 | 851 | void Type::dump_on(outputStream *st) const { |
duke@435 | 852 | ResourceMark rm; |
duke@435 | 853 | Dict d(cmpkey,hashkey); // Stop recursive type dumping |
duke@435 | 854 | dump2(d,1, st); |
kvn@598 | 855 | if (is_ptr_to_narrowoop()) { |
coleenp@548 | 856 | st->print(" [narrow]"); |
roland@4159 | 857 | } else if (is_ptr_to_narrowklass()) { |
roland@4159 | 858 | st->print(" [narrowklass]"); |
coleenp@548 | 859 | } |
duke@435 | 860 | } |
duke@435 | 861 | #endif |
duke@435 | 862 | |
duke@435 | 863 | //------------------------------singleton-------------------------------------- |
duke@435 | 864 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 865 | // constants (Ldi nodes). Singletons are integer, float or double constants. |
duke@435 | 866 | bool Type::singleton(void) const { |
duke@435 | 867 | return _base == Top || _base == Half; |
duke@435 | 868 | } |
duke@435 | 869 | |
duke@435 | 870 | //------------------------------empty------------------------------------------ |
duke@435 | 871 | // TRUE if Type is a type with no values, FALSE otherwise. |
duke@435 | 872 | bool Type::empty(void) const { |
duke@435 | 873 | switch (_base) { |
duke@435 | 874 | case DoubleTop: |
duke@435 | 875 | case FloatTop: |
duke@435 | 876 | case Top: |
duke@435 | 877 | return true; |
duke@435 | 878 | |
duke@435 | 879 | case Half: |
duke@435 | 880 | case Abio: |
duke@435 | 881 | case Return_Address: |
duke@435 | 882 | case Memory: |
duke@435 | 883 | case Bottom: |
duke@435 | 884 | case FloatBot: |
duke@435 | 885 | case DoubleBot: |
duke@435 | 886 | return false; // never a singleton, therefore never empty |
duke@435 | 887 | } |
duke@435 | 888 | |
duke@435 | 889 | ShouldNotReachHere(); |
duke@435 | 890 | return false; |
duke@435 | 891 | } |
duke@435 | 892 | |
duke@435 | 893 | //------------------------------dump_stats------------------------------------- |
duke@435 | 894 | // Dump collected statistics to stderr |
duke@435 | 895 | #ifndef PRODUCT |
duke@435 | 896 | void Type::dump_stats() { |
duke@435 | 897 | tty->print("Types made: %d\n", type_dict()->Size()); |
duke@435 | 898 | } |
duke@435 | 899 | #endif |
duke@435 | 900 | |
duke@435 | 901 | //------------------------------typerr----------------------------------------- |
duke@435 | 902 | void Type::typerr( const Type *t ) const { |
duke@435 | 903 | #ifndef PRODUCT |
duke@435 | 904 | tty->print("\nError mixing types: "); |
duke@435 | 905 | dump(); |
duke@435 | 906 | tty->print(" and "); |
duke@435 | 907 | t->dump(); |
duke@435 | 908 | tty->print("\n"); |
duke@435 | 909 | #endif |
duke@435 | 910 | ShouldNotReachHere(); |
duke@435 | 911 | } |
duke@435 | 912 | |
duke@435 | 913 | |
duke@435 | 914 | //============================================================================= |
duke@435 | 915 | // Convenience common pre-built types. |
duke@435 | 916 | const TypeF *TypeF::ZERO; // Floating point zero |
duke@435 | 917 | const TypeF *TypeF::ONE; // Floating point one |
duke@435 | 918 | |
duke@435 | 919 | //------------------------------make------------------------------------------- |
duke@435 | 920 | // Create a float constant |
duke@435 | 921 | const TypeF *TypeF::make(float f) { |
duke@435 | 922 | return (TypeF*)(new TypeF(f))->hashcons(); |
duke@435 | 923 | } |
duke@435 | 924 | |
duke@435 | 925 | //------------------------------meet------------------------------------------- |
duke@435 | 926 | // Compute the MEET of two types. It returns a new Type object. |
duke@435 | 927 | const Type *TypeF::xmeet( const Type *t ) const { |
duke@435 | 928 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 929 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 930 | |
duke@435 | 931 | // Current "this->_base" is FloatCon |
duke@435 | 932 | switch (t->base()) { // Switch on original type |
duke@435 | 933 | case AnyPtr: // Mixing with oops happens when javac |
duke@435 | 934 | case RawPtr: // reuses local variables |
duke@435 | 935 | case OopPtr: |
duke@435 | 936 | case InstPtr: |
coleenp@4037 | 937 | case AryPtr: |
coleenp@4037 | 938 | case MetadataPtr: |
duke@435 | 939 | case KlassPtr: |
kvn@728 | 940 | case NarrowOop: |
roland@4159 | 941 | case NarrowKlass: |
duke@435 | 942 | case Int: |
duke@435 | 943 | case Long: |
duke@435 | 944 | case DoubleTop: |
duke@435 | 945 | case DoubleCon: |
duke@435 | 946 | case DoubleBot: |
duke@435 | 947 | case Bottom: // Ye Olde Default |
duke@435 | 948 | return Type::BOTTOM; |
duke@435 | 949 | |
duke@435 | 950 | case FloatBot: |
duke@435 | 951 | return t; |
duke@435 | 952 | |
duke@435 | 953 | default: // All else is a mistake |
duke@435 | 954 | typerr(t); |
duke@435 | 955 | |
duke@435 | 956 | case FloatCon: // Float-constant vs Float-constant? |
duke@435 | 957 | if( jint_cast(_f) != jint_cast(t->getf()) ) // unequal constants? |
duke@435 | 958 | // must compare bitwise as positive zero, negative zero and NaN have |
duke@435 | 959 | // all the same representation in C++ |
duke@435 | 960 | return FLOAT; // Return generic float |
duke@435 | 961 | // Equal constants |
duke@435 | 962 | case Top: |
duke@435 | 963 | case FloatTop: |
duke@435 | 964 | break; // Return the float constant |
duke@435 | 965 | } |
duke@435 | 966 | return this; // Return the float constant |
duke@435 | 967 | } |
duke@435 | 968 | |
duke@435 | 969 | //------------------------------xdual------------------------------------------ |
duke@435 | 970 | // Dual: symmetric |
duke@435 | 971 | const Type *TypeF::xdual() const { |
duke@435 | 972 | return this; |
duke@435 | 973 | } |
duke@435 | 974 | |
duke@435 | 975 | //------------------------------eq--------------------------------------------- |
duke@435 | 976 | // Structural equality check for Type representations |
duke@435 | 977 | bool TypeF::eq( const Type *t ) const { |
duke@435 | 978 | if( g_isnan(_f) || |
duke@435 | 979 | g_isnan(t->getf()) ) { |
duke@435 | 980 | // One or both are NANs. If both are NANs return true, else false. |
duke@435 | 981 | return (g_isnan(_f) && g_isnan(t->getf())); |
duke@435 | 982 | } |
duke@435 | 983 | if (_f == t->getf()) { |
duke@435 | 984 | // (NaN is impossible at this point, since it is not equal even to itself) |
duke@435 | 985 | if (_f == 0.0) { |
duke@435 | 986 | // difference between positive and negative zero |
duke@435 | 987 | if (jint_cast(_f) != jint_cast(t->getf())) return false; |
duke@435 | 988 | } |
duke@435 | 989 | return true; |
duke@435 | 990 | } |
duke@435 | 991 | return false; |
duke@435 | 992 | } |
duke@435 | 993 | |
duke@435 | 994 | //------------------------------hash------------------------------------------- |
duke@435 | 995 | // Type-specific hashing function. |
duke@435 | 996 | int TypeF::hash(void) const { |
duke@435 | 997 | return *(int*)(&_f); |
duke@435 | 998 | } |
duke@435 | 999 | |
duke@435 | 1000 | //------------------------------is_finite-------------------------------------- |
duke@435 | 1001 | // Has a finite value |
duke@435 | 1002 | bool TypeF::is_finite() const { |
duke@435 | 1003 | return g_isfinite(getf()) != 0; |
duke@435 | 1004 | } |
duke@435 | 1005 | |
duke@435 | 1006 | //------------------------------is_nan----------------------------------------- |
duke@435 | 1007 | // Is not a number (NaN) |
duke@435 | 1008 | bool TypeF::is_nan() const { |
duke@435 | 1009 | return g_isnan(getf()) != 0; |
duke@435 | 1010 | } |
duke@435 | 1011 | |
duke@435 | 1012 | //------------------------------dump2------------------------------------------ |
duke@435 | 1013 | // Dump float constant Type |
duke@435 | 1014 | #ifndef PRODUCT |
duke@435 | 1015 | void TypeF::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 1016 | Type::dump2(d,depth, st); |
duke@435 | 1017 | st->print("%f", _f); |
duke@435 | 1018 | } |
duke@435 | 1019 | #endif |
duke@435 | 1020 | |
duke@435 | 1021 | //------------------------------singleton-------------------------------------- |
duke@435 | 1022 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 1023 | // constants (Ldi nodes). Singletons are integer, float or double constants |
duke@435 | 1024 | // or a single symbol. |
duke@435 | 1025 | bool TypeF::singleton(void) const { |
duke@435 | 1026 | return true; // Always a singleton |
duke@435 | 1027 | } |
duke@435 | 1028 | |
duke@435 | 1029 | bool TypeF::empty(void) const { |
duke@435 | 1030 | return false; // always exactly a singleton |
duke@435 | 1031 | } |
duke@435 | 1032 | |
duke@435 | 1033 | //============================================================================= |
duke@435 | 1034 | // Convenience common pre-built types. |
duke@435 | 1035 | const TypeD *TypeD::ZERO; // Floating point zero |
duke@435 | 1036 | const TypeD *TypeD::ONE; // Floating point one |
duke@435 | 1037 | |
duke@435 | 1038 | //------------------------------make------------------------------------------- |
duke@435 | 1039 | const TypeD *TypeD::make(double d) { |
duke@435 | 1040 | return (TypeD*)(new TypeD(d))->hashcons(); |
duke@435 | 1041 | } |
duke@435 | 1042 | |
duke@435 | 1043 | //------------------------------meet------------------------------------------- |
duke@435 | 1044 | // Compute the MEET of two types. It returns a new Type object. |
duke@435 | 1045 | const Type *TypeD::xmeet( const Type *t ) const { |
duke@435 | 1046 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 1047 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 1048 | |
duke@435 | 1049 | // Current "this->_base" is DoubleCon |
duke@435 | 1050 | switch (t->base()) { // Switch on original type |
duke@435 | 1051 | case AnyPtr: // Mixing with oops happens when javac |
duke@435 | 1052 | case RawPtr: // reuses local variables |
duke@435 | 1053 | case OopPtr: |
duke@435 | 1054 | case InstPtr: |
coleenp@4037 | 1055 | case AryPtr: |
coleenp@4037 | 1056 | case MetadataPtr: |
duke@435 | 1057 | case KlassPtr: |
never@618 | 1058 | case NarrowOop: |
roland@4159 | 1059 | case NarrowKlass: |
duke@435 | 1060 | case Int: |
duke@435 | 1061 | case Long: |
duke@435 | 1062 | case FloatTop: |
duke@435 | 1063 | case FloatCon: |
duke@435 | 1064 | case FloatBot: |
duke@435 | 1065 | case Bottom: // Ye Olde Default |
duke@435 | 1066 | return Type::BOTTOM; |
duke@435 | 1067 | |
duke@435 | 1068 | case DoubleBot: |
duke@435 | 1069 | return t; |
duke@435 | 1070 | |
duke@435 | 1071 | default: // All else is a mistake |
duke@435 | 1072 | typerr(t); |
duke@435 | 1073 | |
duke@435 | 1074 | case DoubleCon: // Double-constant vs Double-constant? |
duke@435 | 1075 | if( jlong_cast(_d) != jlong_cast(t->getd()) ) // unequal constants? (see comment in TypeF::xmeet) |
duke@435 | 1076 | return DOUBLE; // Return generic double |
duke@435 | 1077 | case Top: |
duke@435 | 1078 | case DoubleTop: |
duke@435 | 1079 | break; |
duke@435 | 1080 | } |
duke@435 | 1081 | return this; // Return the double constant |
duke@435 | 1082 | } |
duke@435 | 1083 | |
duke@435 | 1084 | //------------------------------xdual------------------------------------------ |
duke@435 | 1085 | // Dual: symmetric |
duke@435 | 1086 | const Type *TypeD::xdual() const { |
duke@435 | 1087 | return this; |
duke@435 | 1088 | } |
duke@435 | 1089 | |
duke@435 | 1090 | //------------------------------eq--------------------------------------------- |
duke@435 | 1091 | // Structural equality check for Type representations |
duke@435 | 1092 | bool TypeD::eq( const Type *t ) const { |
duke@435 | 1093 | if( g_isnan(_d) || |
duke@435 | 1094 | g_isnan(t->getd()) ) { |
duke@435 | 1095 | // One or both are NANs. If both are NANs return true, else false. |
duke@435 | 1096 | return (g_isnan(_d) && g_isnan(t->getd())); |
duke@435 | 1097 | } |
duke@435 | 1098 | if (_d == t->getd()) { |
duke@435 | 1099 | // (NaN is impossible at this point, since it is not equal even to itself) |
duke@435 | 1100 | if (_d == 0.0) { |
duke@435 | 1101 | // difference between positive and negative zero |
duke@435 | 1102 | if (jlong_cast(_d) != jlong_cast(t->getd())) return false; |
duke@435 | 1103 | } |
duke@435 | 1104 | return true; |
duke@435 | 1105 | } |
duke@435 | 1106 | return false; |
duke@435 | 1107 | } |
duke@435 | 1108 | |
duke@435 | 1109 | //------------------------------hash------------------------------------------- |
duke@435 | 1110 | // Type-specific hashing function. |
duke@435 | 1111 | int TypeD::hash(void) const { |
duke@435 | 1112 | return *(int*)(&_d); |
duke@435 | 1113 | } |
duke@435 | 1114 | |
duke@435 | 1115 | //------------------------------is_finite-------------------------------------- |
duke@435 | 1116 | // Has a finite value |
duke@435 | 1117 | bool TypeD::is_finite() const { |
duke@435 | 1118 | return g_isfinite(getd()) != 0; |
duke@435 | 1119 | } |
duke@435 | 1120 | |
duke@435 | 1121 | //------------------------------is_nan----------------------------------------- |
duke@435 | 1122 | // Is not a number (NaN) |
duke@435 | 1123 | bool TypeD::is_nan() const { |
duke@435 | 1124 | return g_isnan(getd()) != 0; |
duke@435 | 1125 | } |
duke@435 | 1126 | |
duke@435 | 1127 | //------------------------------dump2------------------------------------------ |
duke@435 | 1128 | // Dump double constant Type |
duke@435 | 1129 | #ifndef PRODUCT |
duke@435 | 1130 | void TypeD::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 1131 | Type::dump2(d,depth,st); |
duke@435 | 1132 | st->print("%f", _d); |
duke@435 | 1133 | } |
duke@435 | 1134 | #endif |
duke@435 | 1135 | |
duke@435 | 1136 | //------------------------------singleton-------------------------------------- |
duke@435 | 1137 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 1138 | // constants (Ldi nodes). Singletons are integer, float or double constants |
duke@435 | 1139 | // or a single symbol. |
duke@435 | 1140 | bool TypeD::singleton(void) const { |
duke@435 | 1141 | return true; // Always a singleton |
duke@435 | 1142 | } |
duke@435 | 1143 | |
duke@435 | 1144 | bool TypeD::empty(void) const { |
duke@435 | 1145 | return false; // always exactly a singleton |
duke@435 | 1146 | } |
duke@435 | 1147 | |
duke@435 | 1148 | //============================================================================= |
duke@435 | 1149 | // Convience common pre-built types. |
duke@435 | 1150 | const TypeInt *TypeInt::MINUS_1;// -1 |
duke@435 | 1151 | const TypeInt *TypeInt::ZERO; // 0 |
duke@435 | 1152 | const TypeInt *TypeInt::ONE; // 1 |
duke@435 | 1153 | const TypeInt *TypeInt::BOOL; // 0 or 1, FALSE or TRUE. |
duke@435 | 1154 | const TypeInt *TypeInt::CC; // -1,0 or 1, condition codes |
duke@435 | 1155 | const TypeInt *TypeInt::CC_LT; // [-1] == MINUS_1 |
duke@435 | 1156 | const TypeInt *TypeInt::CC_GT; // [1] == ONE |
duke@435 | 1157 | const TypeInt *TypeInt::CC_EQ; // [0] == ZERO |
duke@435 | 1158 | const TypeInt *TypeInt::CC_LE; // [-1,0] |
duke@435 | 1159 | const TypeInt *TypeInt::CC_GE; // [0,1] == BOOL (!) |
duke@435 | 1160 | const TypeInt *TypeInt::BYTE; // Bytes, -128 to 127 |
twisti@1059 | 1161 | const TypeInt *TypeInt::UBYTE; // Unsigned Bytes, 0 to 255 |
duke@435 | 1162 | const TypeInt *TypeInt::CHAR; // Java chars, 0-65535 |
duke@435 | 1163 | const TypeInt *TypeInt::SHORT; // Java shorts, -32768-32767 |
duke@435 | 1164 | const TypeInt *TypeInt::POS; // Positive 32-bit integers or zero |
duke@435 | 1165 | const TypeInt *TypeInt::POS1; // Positive 32-bit integers |
duke@435 | 1166 | const TypeInt *TypeInt::INT; // 32-bit integers |
duke@435 | 1167 | const TypeInt *TypeInt::SYMINT; // symmetric range [-max_jint..max_jint] |
rbackman@6375 | 1168 | const TypeInt *TypeInt::TYPE_DOMAIN; // alias for TypeInt::INT |
duke@435 | 1169 | |
duke@435 | 1170 | //------------------------------TypeInt---------------------------------------- |
duke@435 | 1171 | TypeInt::TypeInt( jint lo, jint hi, int w ) : Type(Int), _lo(lo), _hi(hi), _widen(w) { |
duke@435 | 1172 | } |
duke@435 | 1173 | |
duke@435 | 1174 | //------------------------------make------------------------------------------- |
duke@435 | 1175 | const TypeInt *TypeInt::make( jint lo ) { |
duke@435 | 1176 | return (TypeInt*)(new TypeInt(lo,lo,WidenMin))->hashcons(); |
duke@435 | 1177 | } |
duke@435 | 1178 | |
kvn@1975 | 1179 | static int normalize_int_widen( jint lo, jint hi, int w ) { |
duke@435 | 1180 | // Certain normalizations keep us sane when comparing types. |
duke@435 | 1181 | // The 'SMALLINT' covers constants and also CC and its relatives. |
duke@435 | 1182 | if (lo <= hi) { |
kvn@1975 | 1183 | if ((juint)(hi - lo) <= SMALLINT) w = Type::WidenMin; |
kvn@1975 | 1184 | if ((juint)(hi - lo) >= max_juint) w = Type::WidenMax; // TypeInt::INT |
kvn@1975 | 1185 | } else { |
kvn@1975 | 1186 | if ((juint)(lo - hi) <= SMALLINT) w = Type::WidenMin; |
kvn@1975 | 1187 | if ((juint)(lo - hi) >= max_juint) w = Type::WidenMin; // dual TypeInt::INT |
duke@435 | 1188 | } |
kvn@1975 | 1189 | return w; |
kvn@1975 | 1190 | } |
kvn@1975 | 1191 | |
kvn@1975 | 1192 | const TypeInt *TypeInt::make( jint lo, jint hi, int w ) { |
kvn@1975 | 1193 | w = normalize_int_widen(lo, hi, w); |
duke@435 | 1194 | return (TypeInt*)(new TypeInt(lo,hi,w))->hashcons(); |
duke@435 | 1195 | } |
duke@435 | 1196 | |
duke@435 | 1197 | //------------------------------meet------------------------------------------- |
duke@435 | 1198 | // Compute the MEET of two types. It returns a new Type representation object |
duke@435 | 1199 | // with reference count equal to the number of Types pointing at it. |
duke@435 | 1200 | // Caller should wrap a Types around it. |
duke@435 | 1201 | const Type *TypeInt::xmeet( const Type *t ) const { |
duke@435 | 1202 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 1203 | if( this == t ) return this; // Meeting same type? |
duke@435 | 1204 | |
duke@435 | 1205 | // Currently "this->_base" is a TypeInt |
duke@435 | 1206 | switch (t->base()) { // Switch on original type |
duke@435 | 1207 | case AnyPtr: // Mixing with oops happens when javac |
duke@435 | 1208 | case RawPtr: // reuses local variables |
duke@435 | 1209 | case OopPtr: |
duke@435 | 1210 | case InstPtr: |
coleenp@4037 | 1211 | case AryPtr: |
coleenp@4037 | 1212 | case MetadataPtr: |
duke@435 | 1213 | case KlassPtr: |
never@618 | 1214 | case NarrowOop: |
roland@4159 | 1215 | case NarrowKlass: |
duke@435 | 1216 | case Long: |
duke@435 | 1217 | case FloatTop: |
duke@435 | 1218 | case FloatCon: |
duke@435 | 1219 | case FloatBot: |
duke@435 | 1220 | case DoubleTop: |
duke@435 | 1221 | case DoubleCon: |
duke@435 | 1222 | case DoubleBot: |
duke@435 | 1223 | case Bottom: // Ye Olde Default |
duke@435 | 1224 | return Type::BOTTOM; |
duke@435 | 1225 | default: // All else is a mistake |
duke@435 | 1226 | typerr(t); |
duke@435 | 1227 | case Top: // No change |
duke@435 | 1228 | return this; |
duke@435 | 1229 | case Int: // Int vs Int? |
duke@435 | 1230 | break; |
duke@435 | 1231 | } |
duke@435 | 1232 | |
duke@435 | 1233 | // Expand covered set |
duke@435 | 1234 | const TypeInt *r = t->is_int(); |
kvn@1975 | 1235 | return make( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) ); |
duke@435 | 1236 | } |
duke@435 | 1237 | |
duke@435 | 1238 | //------------------------------xdual------------------------------------------ |
duke@435 | 1239 | // Dual: reverse hi & lo; flip widen |
duke@435 | 1240 | const Type *TypeInt::xdual() const { |
kvn@1975 | 1241 | int w = normalize_int_widen(_hi,_lo, WidenMax-_widen); |
kvn@1975 | 1242 | return new TypeInt(_hi,_lo,w); |
duke@435 | 1243 | } |
duke@435 | 1244 | |
duke@435 | 1245 | //------------------------------widen------------------------------------------ |
duke@435 | 1246 | // Only happens for optimistic top-down optimizations. |
never@1444 | 1247 | const Type *TypeInt::widen( const Type *old, const Type* limit ) const { |
duke@435 | 1248 | // Coming from TOP or such; no widening |
duke@435 | 1249 | if( old->base() != Int ) return this; |
duke@435 | 1250 | const TypeInt *ot = old->is_int(); |
duke@435 | 1251 | |
duke@435 | 1252 | // If new guy is equal to old guy, no widening |
duke@435 | 1253 | if( _lo == ot->_lo && _hi == ot->_hi ) |
duke@435 | 1254 | return old; |
duke@435 | 1255 | |
duke@435 | 1256 | // If new guy contains old, then we widened |
duke@435 | 1257 | if( _lo <= ot->_lo && _hi >= ot->_hi ) { |
duke@435 | 1258 | // New contains old |
duke@435 | 1259 | // If new guy is already wider than old, no widening |
duke@435 | 1260 | if( _widen > ot->_widen ) return this; |
duke@435 | 1261 | // If old guy was a constant, do not bother |
duke@435 | 1262 | if (ot->_lo == ot->_hi) return this; |
duke@435 | 1263 | // Now widen new guy. |
duke@435 | 1264 | // Check for widening too far |
duke@435 | 1265 | if (_widen == WidenMax) { |
never@1444 | 1266 | int max = max_jint; |
never@1444 | 1267 | int min = min_jint; |
never@1444 | 1268 | if (limit->isa_int()) { |
never@1444 | 1269 | max = limit->is_int()->_hi; |
never@1444 | 1270 | min = limit->is_int()->_lo; |
never@1444 | 1271 | } |
never@1444 | 1272 | if (min < _lo && _hi < max) { |
duke@435 | 1273 | // If neither endpoint is extremal yet, push out the endpoint |
duke@435 | 1274 | // which is closer to its respective limit. |
duke@435 | 1275 | if (_lo >= 0 || // easy common case |
never@1444 | 1276 | (juint)(_lo - min) >= (juint)(max - _hi)) { |
duke@435 | 1277 | // Try to widen to an unsigned range type of 31 bits: |
never@1444 | 1278 | return make(_lo, max, WidenMax); |
duke@435 | 1279 | } else { |
never@1444 | 1280 | return make(min, _hi, WidenMax); |
duke@435 | 1281 | } |
duke@435 | 1282 | } |
duke@435 | 1283 | return TypeInt::INT; |
duke@435 | 1284 | } |
duke@435 | 1285 | // Returned widened new guy |
duke@435 | 1286 | return make(_lo,_hi,_widen+1); |
duke@435 | 1287 | } |
duke@435 | 1288 | |
duke@435 | 1289 | // If old guy contains new, then we probably widened too far & dropped to |
duke@435 | 1290 | // bottom. Return the wider fellow. |
duke@435 | 1291 | if ( ot->_lo <= _lo && ot->_hi >= _hi ) |
duke@435 | 1292 | return old; |
duke@435 | 1293 | |
duke@435 | 1294 | //fatal("Integer value range is not subset"); |
duke@435 | 1295 | //return this; |
duke@435 | 1296 | return TypeInt::INT; |
duke@435 | 1297 | } |
duke@435 | 1298 | |
duke@435 | 1299 | //------------------------------narrow--------------------------------------- |
duke@435 | 1300 | // Only happens for pessimistic optimizations. |
duke@435 | 1301 | const Type *TypeInt::narrow( const Type *old ) const { |
duke@435 | 1302 | if (_lo >= _hi) return this; // already narrow enough |
duke@435 | 1303 | if (old == NULL) return this; |
duke@435 | 1304 | const TypeInt* ot = old->isa_int(); |
duke@435 | 1305 | if (ot == NULL) return this; |
duke@435 | 1306 | jint olo = ot->_lo; |
duke@435 | 1307 | jint ohi = ot->_hi; |
duke@435 | 1308 | |
duke@435 | 1309 | // If new guy is equal to old guy, no narrowing |
duke@435 | 1310 | if (_lo == olo && _hi == ohi) return old; |
duke@435 | 1311 | |
duke@435 | 1312 | // If old guy was maximum range, allow the narrowing |
duke@435 | 1313 | if (olo == min_jint && ohi == max_jint) return this; |
duke@435 | 1314 | |
duke@435 | 1315 | if (_lo < olo || _hi > ohi) |
duke@435 | 1316 | return this; // doesn't narrow; pretty wierd |
duke@435 | 1317 | |
duke@435 | 1318 | // The new type narrows the old type, so look for a "death march". |
duke@435 | 1319 | // See comments on PhaseTransform::saturate. |
duke@435 | 1320 | juint nrange = _hi - _lo; |
duke@435 | 1321 | juint orange = ohi - olo; |
duke@435 | 1322 | if (nrange < max_juint - 1 && nrange > (orange >> 1) + (SMALLINT*2)) { |
duke@435 | 1323 | // Use the new type only if the range shrinks a lot. |
duke@435 | 1324 | // We do not want the optimizer computing 2^31 point by point. |
duke@435 | 1325 | return old; |
duke@435 | 1326 | } |
duke@435 | 1327 | |
duke@435 | 1328 | return this; |
duke@435 | 1329 | } |
duke@435 | 1330 | |
duke@435 | 1331 | //-----------------------------filter------------------------------------------ |
roland@6313 | 1332 | const Type *TypeInt::filter_helper(const Type *kills, bool include_speculative) const { |
roland@6313 | 1333 | const TypeInt* ft = join_helper(kills, include_speculative)->isa_int(); |
kvn@1975 | 1334 | if (ft == NULL || ft->empty()) |
duke@435 | 1335 | return Type::TOP; // Canonical empty value |
duke@435 | 1336 | if (ft->_widen < this->_widen) { |
duke@435 | 1337 | // Do not allow the value of kill->_widen to affect the outcome. |
duke@435 | 1338 | // The widen bits must be allowed to run freely through the graph. |
duke@435 | 1339 | ft = TypeInt::make(ft->_lo, ft->_hi, this->_widen); |
duke@435 | 1340 | } |
duke@435 | 1341 | return ft; |
duke@435 | 1342 | } |
duke@435 | 1343 | |
duke@435 | 1344 | //------------------------------eq--------------------------------------------- |
duke@435 | 1345 | // Structural equality check for Type representations |
duke@435 | 1346 | bool TypeInt::eq( const Type *t ) const { |
duke@435 | 1347 | const TypeInt *r = t->is_int(); // Handy access |
duke@435 | 1348 | return r->_lo == _lo && r->_hi == _hi && r->_widen == _widen; |
duke@435 | 1349 | } |
duke@435 | 1350 | |
duke@435 | 1351 | //------------------------------hash------------------------------------------- |
duke@435 | 1352 | // Type-specific hashing function. |
duke@435 | 1353 | int TypeInt::hash(void) const { |
duke@435 | 1354 | return _lo+_hi+_widen+(int)Type::Int; |
duke@435 | 1355 | } |
duke@435 | 1356 | |
duke@435 | 1357 | //------------------------------is_finite-------------------------------------- |
duke@435 | 1358 | // Has a finite value |
duke@435 | 1359 | bool TypeInt::is_finite() const { |
duke@435 | 1360 | return true; |
duke@435 | 1361 | } |
duke@435 | 1362 | |
duke@435 | 1363 | //------------------------------dump2------------------------------------------ |
duke@435 | 1364 | // Dump TypeInt |
duke@435 | 1365 | #ifndef PRODUCT |
duke@435 | 1366 | static const char* intname(char* buf, jint n) { |
duke@435 | 1367 | if (n == min_jint) |
duke@435 | 1368 | return "min"; |
duke@435 | 1369 | else if (n < min_jint + 10000) |
duke@435 | 1370 | sprintf(buf, "min+" INT32_FORMAT, n - min_jint); |
duke@435 | 1371 | else if (n == max_jint) |
duke@435 | 1372 | return "max"; |
duke@435 | 1373 | else if (n > max_jint - 10000) |
duke@435 | 1374 | sprintf(buf, "max-" INT32_FORMAT, max_jint - n); |
duke@435 | 1375 | else |
duke@435 | 1376 | sprintf(buf, INT32_FORMAT, n); |
duke@435 | 1377 | return buf; |
duke@435 | 1378 | } |
duke@435 | 1379 | |
duke@435 | 1380 | void TypeInt::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 1381 | char buf[40], buf2[40]; |
duke@435 | 1382 | if (_lo == min_jint && _hi == max_jint) |
duke@435 | 1383 | st->print("int"); |
duke@435 | 1384 | else if (is_con()) |
duke@435 | 1385 | st->print("int:%s", intname(buf, get_con())); |
duke@435 | 1386 | else if (_lo == BOOL->_lo && _hi == BOOL->_hi) |
duke@435 | 1387 | st->print("bool"); |
duke@435 | 1388 | else if (_lo == BYTE->_lo && _hi == BYTE->_hi) |
duke@435 | 1389 | st->print("byte"); |
duke@435 | 1390 | else if (_lo == CHAR->_lo && _hi == CHAR->_hi) |
duke@435 | 1391 | st->print("char"); |
duke@435 | 1392 | else if (_lo == SHORT->_lo && _hi == SHORT->_hi) |
duke@435 | 1393 | st->print("short"); |
duke@435 | 1394 | else if (_hi == max_jint) |
duke@435 | 1395 | st->print("int:>=%s", intname(buf, _lo)); |
duke@435 | 1396 | else if (_lo == min_jint) |
duke@435 | 1397 | st->print("int:<=%s", intname(buf, _hi)); |
duke@435 | 1398 | else |
duke@435 | 1399 | st->print("int:%s..%s", intname(buf, _lo), intname(buf2, _hi)); |
duke@435 | 1400 | |
duke@435 | 1401 | if (_widen != 0 && this != TypeInt::INT) |
duke@435 | 1402 | st->print(":%.*s", _widen, "wwww"); |
duke@435 | 1403 | } |
duke@435 | 1404 | #endif |
duke@435 | 1405 | |
duke@435 | 1406 | //------------------------------singleton-------------------------------------- |
duke@435 | 1407 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 1408 | // constants. |
duke@435 | 1409 | bool TypeInt::singleton(void) const { |
duke@435 | 1410 | return _lo >= _hi; |
duke@435 | 1411 | } |
duke@435 | 1412 | |
duke@435 | 1413 | bool TypeInt::empty(void) const { |
duke@435 | 1414 | return _lo > _hi; |
duke@435 | 1415 | } |
duke@435 | 1416 | |
duke@435 | 1417 | //============================================================================= |
duke@435 | 1418 | // Convenience common pre-built types. |
duke@435 | 1419 | const TypeLong *TypeLong::MINUS_1;// -1 |
duke@435 | 1420 | const TypeLong *TypeLong::ZERO; // 0 |
duke@435 | 1421 | const TypeLong *TypeLong::ONE; // 1 |
duke@435 | 1422 | const TypeLong *TypeLong::POS; // >=0 |
duke@435 | 1423 | const TypeLong *TypeLong::LONG; // 64-bit integers |
duke@435 | 1424 | const TypeLong *TypeLong::INT; // 32-bit subrange |
duke@435 | 1425 | const TypeLong *TypeLong::UINT; // 32-bit unsigned subrange |
rbackman@6375 | 1426 | const TypeLong *TypeLong::TYPE_DOMAIN; // alias for TypeLong::LONG |
duke@435 | 1427 | |
duke@435 | 1428 | //------------------------------TypeLong--------------------------------------- |
duke@435 | 1429 | TypeLong::TypeLong( jlong lo, jlong hi, int w ) : Type(Long), _lo(lo), _hi(hi), _widen(w) { |
duke@435 | 1430 | } |
duke@435 | 1431 | |
duke@435 | 1432 | //------------------------------make------------------------------------------- |
duke@435 | 1433 | const TypeLong *TypeLong::make( jlong lo ) { |
duke@435 | 1434 | return (TypeLong*)(new TypeLong(lo,lo,WidenMin))->hashcons(); |
duke@435 | 1435 | } |
duke@435 | 1436 | |
kvn@1975 | 1437 | static int normalize_long_widen( jlong lo, jlong hi, int w ) { |
kvn@1975 | 1438 | // Certain normalizations keep us sane when comparing types. |
kvn@1975 | 1439 | // The 'SMALLINT' covers constants. |
kvn@1975 | 1440 | if (lo <= hi) { |
kvn@1975 | 1441 | if ((julong)(hi - lo) <= SMALLINT) w = Type::WidenMin; |
kvn@1975 | 1442 | if ((julong)(hi - lo) >= max_julong) w = Type::WidenMax; // TypeLong::LONG |
kvn@1975 | 1443 | } else { |
kvn@1975 | 1444 | if ((julong)(lo - hi) <= SMALLINT) w = Type::WidenMin; |
kvn@1975 | 1445 | if ((julong)(lo - hi) >= max_julong) w = Type::WidenMin; // dual TypeLong::LONG |
kvn@1975 | 1446 | } |
kvn@1975 | 1447 | return w; |
kvn@1975 | 1448 | } |
kvn@1975 | 1449 | |
duke@435 | 1450 | const TypeLong *TypeLong::make( jlong lo, jlong hi, int w ) { |
kvn@1975 | 1451 | w = normalize_long_widen(lo, hi, w); |
duke@435 | 1452 | return (TypeLong*)(new TypeLong(lo,hi,w))->hashcons(); |
duke@435 | 1453 | } |
duke@435 | 1454 | |
duke@435 | 1455 | |
duke@435 | 1456 | //------------------------------meet------------------------------------------- |
duke@435 | 1457 | // Compute the MEET of two types. It returns a new Type representation object |
duke@435 | 1458 | // with reference count equal to the number of Types pointing at it. |
duke@435 | 1459 | // Caller should wrap a Types around it. |
duke@435 | 1460 | const Type *TypeLong::xmeet( const Type *t ) const { |
duke@435 | 1461 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 1462 | if( this == t ) return this; // Meeting same type? |
duke@435 | 1463 | |
duke@435 | 1464 | // Currently "this->_base" is a TypeLong |
duke@435 | 1465 | switch (t->base()) { // Switch on original type |
duke@435 | 1466 | case AnyPtr: // Mixing with oops happens when javac |
duke@435 | 1467 | case RawPtr: // reuses local variables |
duke@435 | 1468 | case OopPtr: |
duke@435 | 1469 | case InstPtr: |
coleenp@4037 | 1470 | case AryPtr: |
coleenp@4037 | 1471 | case MetadataPtr: |
duke@435 | 1472 | case KlassPtr: |
never@618 | 1473 | case NarrowOop: |
roland@4159 | 1474 | case NarrowKlass: |
duke@435 | 1475 | case Int: |
duke@435 | 1476 | case FloatTop: |
duke@435 | 1477 | case FloatCon: |
duke@435 | 1478 | case FloatBot: |
duke@435 | 1479 | case DoubleTop: |
duke@435 | 1480 | case DoubleCon: |
duke@435 | 1481 | case DoubleBot: |
duke@435 | 1482 | case Bottom: // Ye Olde Default |
duke@435 | 1483 | return Type::BOTTOM; |
duke@435 | 1484 | default: // All else is a mistake |
duke@435 | 1485 | typerr(t); |
duke@435 | 1486 | case Top: // No change |
duke@435 | 1487 | return this; |
duke@435 | 1488 | case Long: // Long vs Long? |
duke@435 | 1489 | break; |
duke@435 | 1490 | } |
duke@435 | 1491 | |
duke@435 | 1492 | // Expand covered set |
duke@435 | 1493 | const TypeLong *r = t->is_long(); // Turn into a TypeLong |
kvn@1975 | 1494 | return make( MIN2(_lo,r->_lo), MAX2(_hi,r->_hi), MAX2(_widen,r->_widen) ); |
duke@435 | 1495 | } |
duke@435 | 1496 | |
duke@435 | 1497 | //------------------------------xdual------------------------------------------ |
duke@435 | 1498 | // Dual: reverse hi & lo; flip widen |
duke@435 | 1499 | const Type *TypeLong::xdual() const { |
kvn@1975 | 1500 | int w = normalize_long_widen(_hi,_lo, WidenMax-_widen); |
kvn@1975 | 1501 | return new TypeLong(_hi,_lo,w); |
duke@435 | 1502 | } |
duke@435 | 1503 | |
duke@435 | 1504 | //------------------------------widen------------------------------------------ |
duke@435 | 1505 | // Only happens for optimistic top-down optimizations. |
never@1444 | 1506 | const Type *TypeLong::widen( const Type *old, const Type* limit ) const { |
duke@435 | 1507 | // Coming from TOP or such; no widening |
duke@435 | 1508 | if( old->base() != Long ) return this; |
duke@435 | 1509 | const TypeLong *ot = old->is_long(); |
duke@435 | 1510 | |
duke@435 | 1511 | // If new guy is equal to old guy, no widening |
duke@435 | 1512 | if( _lo == ot->_lo && _hi == ot->_hi ) |
duke@435 | 1513 | return old; |
duke@435 | 1514 | |
duke@435 | 1515 | // If new guy contains old, then we widened |
duke@435 | 1516 | if( _lo <= ot->_lo && _hi >= ot->_hi ) { |
duke@435 | 1517 | // New contains old |
duke@435 | 1518 | // If new guy is already wider than old, no widening |
duke@435 | 1519 | if( _widen > ot->_widen ) return this; |
duke@435 | 1520 | // If old guy was a constant, do not bother |
duke@435 | 1521 | if (ot->_lo == ot->_hi) return this; |
duke@435 | 1522 | // Now widen new guy. |
duke@435 | 1523 | // Check for widening too far |
duke@435 | 1524 | if (_widen == WidenMax) { |
never@1444 | 1525 | jlong max = max_jlong; |
never@1444 | 1526 | jlong min = min_jlong; |
never@1444 | 1527 | if (limit->isa_long()) { |
never@1444 | 1528 | max = limit->is_long()->_hi; |
never@1444 | 1529 | min = limit->is_long()->_lo; |
never@1444 | 1530 | } |
never@1444 | 1531 | if (min < _lo && _hi < max) { |
duke@435 | 1532 | // If neither endpoint is extremal yet, push out the endpoint |
duke@435 | 1533 | // which is closer to its respective limit. |
duke@435 | 1534 | if (_lo >= 0 || // easy common case |
never@1444 | 1535 | (julong)(_lo - min) >= (julong)(max - _hi)) { |
duke@435 | 1536 | // Try to widen to an unsigned range type of 32/63 bits: |
never@1444 | 1537 | if (max >= max_juint && _hi < max_juint) |
duke@435 | 1538 | return make(_lo, max_juint, WidenMax); |
duke@435 | 1539 | else |
never@1444 | 1540 | return make(_lo, max, WidenMax); |
duke@435 | 1541 | } else { |
never@1444 | 1542 | return make(min, _hi, WidenMax); |
duke@435 | 1543 | } |
duke@435 | 1544 | } |
duke@435 | 1545 | return TypeLong::LONG; |
duke@435 | 1546 | } |
duke@435 | 1547 | // Returned widened new guy |
duke@435 | 1548 | return make(_lo,_hi,_widen+1); |
duke@435 | 1549 | } |
duke@435 | 1550 | |
duke@435 | 1551 | // If old guy contains new, then we probably widened too far & dropped to |
duke@435 | 1552 | // bottom. Return the wider fellow. |
duke@435 | 1553 | if ( ot->_lo <= _lo && ot->_hi >= _hi ) |
duke@435 | 1554 | return old; |
duke@435 | 1555 | |
duke@435 | 1556 | // fatal("Long value range is not subset"); |
duke@435 | 1557 | // return this; |
duke@435 | 1558 | return TypeLong::LONG; |
duke@435 | 1559 | } |
duke@435 | 1560 | |
duke@435 | 1561 | //------------------------------narrow---------------------------------------- |
duke@435 | 1562 | // Only happens for pessimistic optimizations. |
duke@435 | 1563 | const Type *TypeLong::narrow( const Type *old ) const { |
duke@435 | 1564 | if (_lo >= _hi) return this; // already narrow enough |
duke@435 | 1565 | if (old == NULL) return this; |
duke@435 | 1566 | const TypeLong* ot = old->isa_long(); |
duke@435 | 1567 | if (ot == NULL) return this; |
duke@435 | 1568 | jlong olo = ot->_lo; |
duke@435 | 1569 | jlong ohi = ot->_hi; |
duke@435 | 1570 | |
duke@435 | 1571 | // If new guy is equal to old guy, no narrowing |
duke@435 | 1572 | if (_lo == olo && _hi == ohi) return old; |
duke@435 | 1573 | |
duke@435 | 1574 | // If old guy was maximum range, allow the narrowing |
duke@435 | 1575 | if (olo == min_jlong && ohi == max_jlong) return this; |
duke@435 | 1576 | |
duke@435 | 1577 | if (_lo < olo || _hi > ohi) |
duke@435 | 1578 | return this; // doesn't narrow; pretty wierd |
duke@435 | 1579 | |
duke@435 | 1580 | // The new type narrows the old type, so look for a "death march". |
duke@435 | 1581 | // See comments on PhaseTransform::saturate. |
duke@435 | 1582 | julong nrange = _hi - _lo; |
duke@435 | 1583 | julong orange = ohi - olo; |
duke@435 | 1584 | if (nrange < max_julong - 1 && nrange > (orange >> 1) + (SMALLINT*2)) { |
duke@435 | 1585 | // Use the new type only if the range shrinks a lot. |
duke@435 | 1586 | // We do not want the optimizer computing 2^31 point by point. |
duke@435 | 1587 | return old; |
duke@435 | 1588 | } |
duke@435 | 1589 | |
duke@435 | 1590 | return this; |
duke@435 | 1591 | } |
duke@435 | 1592 | |
duke@435 | 1593 | //-----------------------------filter------------------------------------------ |
roland@6313 | 1594 | const Type *TypeLong::filter_helper(const Type *kills, bool include_speculative) const { |
roland@6313 | 1595 | const TypeLong* ft = join_helper(kills, include_speculative)->isa_long(); |
kvn@1975 | 1596 | if (ft == NULL || ft->empty()) |
duke@435 | 1597 | return Type::TOP; // Canonical empty value |
duke@435 | 1598 | if (ft->_widen < this->_widen) { |
duke@435 | 1599 | // Do not allow the value of kill->_widen to affect the outcome. |
duke@435 | 1600 | // The widen bits must be allowed to run freely through the graph. |
duke@435 | 1601 | ft = TypeLong::make(ft->_lo, ft->_hi, this->_widen); |
duke@435 | 1602 | } |
duke@435 | 1603 | return ft; |
duke@435 | 1604 | } |
duke@435 | 1605 | |
duke@435 | 1606 | //------------------------------eq--------------------------------------------- |
duke@435 | 1607 | // Structural equality check for Type representations |
duke@435 | 1608 | bool TypeLong::eq( const Type *t ) const { |
duke@435 | 1609 | const TypeLong *r = t->is_long(); // Handy access |
duke@435 | 1610 | return r->_lo == _lo && r->_hi == _hi && r->_widen == _widen; |
duke@435 | 1611 | } |
duke@435 | 1612 | |
duke@435 | 1613 | //------------------------------hash------------------------------------------- |
duke@435 | 1614 | // Type-specific hashing function. |
duke@435 | 1615 | int TypeLong::hash(void) const { |
duke@435 | 1616 | return (int)(_lo+_hi+_widen+(int)Type::Long); |
duke@435 | 1617 | } |
duke@435 | 1618 | |
duke@435 | 1619 | //------------------------------is_finite-------------------------------------- |
duke@435 | 1620 | // Has a finite value |
duke@435 | 1621 | bool TypeLong::is_finite() const { |
duke@435 | 1622 | return true; |
duke@435 | 1623 | } |
duke@435 | 1624 | |
duke@435 | 1625 | //------------------------------dump2------------------------------------------ |
duke@435 | 1626 | // Dump TypeLong |
duke@435 | 1627 | #ifndef PRODUCT |
duke@435 | 1628 | static const char* longnamenear(jlong x, const char* xname, char* buf, jlong n) { |
duke@435 | 1629 | if (n > x) { |
duke@435 | 1630 | if (n >= x + 10000) return NULL; |
hseigel@4465 | 1631 | sprintf(buf, "%s+" JLONG_FORMAT, xname, n - x); |
duke@435 | 1632 | } else if (n < x) { |
duke@435 | 1633 | if (n <= x - 10000) return NULL; |
hseigel@4465 | 1634 | sprintf(buf, "%s-" JLONG_FORMAT, xname, x - n); |
duke@435 | 1635 | } else { |
duke@435 | 1636 | return xname; |
duke@435 | 1637 | } |
duke@435 | 1638 | return buf; |
duke@435 | 1639 | } |
duke@435 | 1640 | |
duke@435 | 1641 | static const char* longname(char* buf, jlong n) { |
duke@435 | 1642 | const char* str; |
duke@435 | 1643 | if (n == min_jlong) |
duke@435 | 1644 | return "min"; |
duke@435 | 1645 | else if (n < min_jlong + 10000) |
hseigel@4465 | 1646 | sprintf(buf, "min+" JLONG_FORMAT, n - min_jlong); |
duke@435 | 1647 | else if (n == max_jlong) |
duke@435 | 1648 | return "max"; |
duke@435 | 1649 | else if (n > max_jlong - 10000) |
hseigel@4465 | 1650 | sprintf(buf, "max-" JLONG_FORMAT, max_jlong - n); |
duke@435 | 1651 | else if ((str = longnamenear(max_juint, "maxuint", buf, n)) != NULL) |
duke@435 | 1652 | return str; |
duke@435 | 1653 | else if ((str = longnamenear(max_jint, "maxint", buf, n)) != NULL) |
duke@435 | 1654 | return str; |
duke@435 | 1655 | else if ((str = longnamenear(min_jint, "minint", buf, n)) != NULL) |
duke@435 | 1656 | return str; |
duke@435 | 1657 | else |
hseigel@4465 | 1658 | sprintf(buf, JLONG_FORMAT, n); |
duke@435 | 1659 | return buf; |
duke@435 | 1660 | } |
duke@435 | 1661 | |
duke@435 | 1662 | void TypeLong::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 1663 | char buf[80], buf2[80]; |
duke@435 | 1664 | if (_lo == min_jlong && _hi == max_jlong) |
duke@435 | 1665 | st->print("long"); |
duke@435 | 1666 | else if (is_con()) |
duke@435 | 1667 | st->print("long:%s", longname(buf, get_con())); |
duke@435 | 1668 | else if (_hi == max_jlong) |
duke@435 | 1669 | st->print("long:>=%s", longname(buf, _lo)); |
duke@435 | 1670 | else if (_lo == min_jlong) |
duke@435 | 1671 | st->print("long:<=%s", longname(buf, _hi)); |
duke@435 | 1672 | else |
duke@435 | 1673 | st->print("long:%s..%s", longname(buf, _lo), longname(buf2, _hi)); |
duke@435 | 1674 | |
duke@435 | 1675 | if (_widen != 0 && this != TypeLong::LONG) |
duke@435 | 1676 | st->print(":%.*s", _widen, "wwww"); |
duke@435 | 1677 | } |
duke@435 | 1678 | #endif |
duke@435 | 1679 | |
duke@435 | 1680 | //------------------------------singleton-------------------------------------- |
duke@435 | 1681 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 1682 | // constants |
duke@435 | 1683 | bool TypeLong::singleton(void) const { |
duke@435 | 1684 | return _lo >= _hi; |
duke@435 | 1685 | } |
duke@435 | 1686 | |
duke@435 | 1687 | bool TypeLong::empty(void) const { |
duke@435 | 1688 | return _lo > _hi; |
duke@435 | 1689 | } |
duke@435 | 1690 | |
duke@435 | 1691 | //============================================================================= |
duke@435 | 1692 | // Convenience common pre-built types. |
duke@435 | 1693 | const TypeTuple *TypeTuple::IFBOTH; // Return both arms of IF as reachable |
duke@435 | 1694 | const TypeTuple *TypeTuple::IFFALSE; |
duke@435 | 1695 | const TypeTuple *TypeTuple::IFTRUE; |
duke@435 | 1696 | const TypeTuple *TypeTuple::IFNEITHER; |
duke@435 | 1697 | const TypeTuple *TypeTuple::LOOPBODY; |
duke@435 | 1698 | const TypeTuple *TypeTuple::MEMBAR; |
duke@435 | 1699 | const TypeTuple *TypeTuple::STORECONDITIONAL; |
duke@435 | 1700 | const TypeTuple *TypeTuple::START_I2C; |
duke@435 | 1701 | const TypeTuple *TypeTuple::INT_PAIR; |
duke@435 | 1702 | const TypeTuple *TypeTuple::LONG_PAIR; |
rbackman@5791 | 1703 | const TypeTuple *TypeTuple::INT_CC_PAIR; |
rbackman@5997 | 1704 | const TypeTuple *TypeTuple::LONG_CC_PAIR; |
duke@435 | 1705 | |
duke@435 | 1706 | |
duke@435 | 1707 | //------------------------------make------------------------------------------- |
duke@435 | 1708 | // Make a TypeTuple from the range of a method signature |
duke@435 | 1709 | const TypeTuple *TypeTuple::make_range(ciSignature* sig) { |
duke@435 | 1710 | ciType* return_type = sig->return_type(); |
duke@435 | 1711 | uint total_fields = TypeFunc::Parms + return_type->size(); |
duke@435 | 1712 | const Type **field_array = fields(total_fields); |
duke@435 | 1713 | switch (return_type->basic_type()) { |
duke@435 | 1714 | case T_LONG: |
duke@435 | 1715 | field_array[TypeFunc::Parms] = TypeLong::LONG; |
duke@435 | 1716 | field_array[TypeFunc::Parms+1] = Type::HALF; |
duke@435 | 1717 | break; |
duke@435 | 1718 | case T_DOUBLE: |
duke@435 | 1719 | field_array[TypeFunc::Parms] = Type::DOUBLE; |
duke@435 | 1720 | field_array[TypeFunc::Parms+1] = Type::HALF; |
duke@435 | 1721 | break; |
duke@435 | 1722 | case T_OBJECT: |
duke@435 | 1723 | case T_ARRAY: |
duke@435 | 1724 | case T_BOOLEAN: |
duke@435 | 1725 | case T_CHAR: |
duke@435 | 1726 | case T_FLOAT: |
duke@435 | 1727 | case T_BYTE: |
duke@435 | 1728 | case T_SHORT: |
duke@435 | 1729 | case T_INT: |
duke@435 | 1730 | field_array[TypeFunc::Parms] = get_const_type(return_type); |
duke@435 | 1731 | break; |
duke@435 | 1732 | case T_VOID: |
duke@435 | 1733 | break; |
duke@435 | 1734 | default: |
duke@435 | 1735 | ShouldNotReachHere(); |
duke@435 | 1736 | } |
duke@435 | 1737 | return (TypeTuple*)(new TypeTuple(total_fields,field_array))->hashcons(); |
duke@435 | 1738 | } |
duke@435 | 1739 | |
duke@435 | 1740 | // Make a TypeTuple from the domain of a method signature |
duke@435 | 1741 | const TypeTuple *TypeTuple::make_domain(ciInstanceKlass* recv, ciSignature* sig) { |
duke@435 | 1742 | uint total_fields = TypeFunc::Parms + sig->size(); |
duke@435 | 1743 | |
duke@435 | 1744 | uint pos = TypeFunc::Parms; |
duke@435 | 1745 | const Type **field_array; |
duke@435 | 1746 | if (recv != NULL) { |
duke@435 | 1747 | total_fields++; |
duke@435 | 1748 | field_array = fields(total_fields); |
duke@435 | 1749 | // Use get_const_type here because it respects UseUniqueSubclasses: |
roland@6313 | 1750 | field_array[pos++] = get_const_type(recv)->join_speculative(TypePtr::NOTNULL); |
duke@435 | 1751 | } else { |
duke@435 | 1752 | field_array = fields(total_fields); |
duke@435 | 1753 | } |
duke@435 | 1754 | |
duke@435 | 1755 | int i = 0; |
duke@435 | 1756 | while (pos < total_fields) { |
duke@435 | 1757 | ciType* type = sig->type_at(i); |
duke@435 | 1758 | |
duke@435 | 1759 | switch (type->basic_type()) { |
duke@435 | 1760 | case T_LONG: |
duke@435 | 1761 | field_array[pos++] = TypeLong::LONG; |
duke@435 | 1762 | field_array[pos++] = Type::HALF; |
duke@435 | 1763 | break; |
duke@435 | 1764 | case T_DOUBLE: |
duke@435 | 1765 | field_array[pos++] = Type::DOUBLE; |
duke@435 | 1766 | field_array[pos++] = Type::HALF; |
duke@435 | 1767 | break; |
duke@435 | 1768 | case T_OBJECT: |
duke@435 | 1769 | case T_ARRAY: |
duke@435 | 1770 | case T_BOOLEAN: |
duke@435 | 1771 | case T_CHAR: |
duke@435 | 1772 | case T_FLOAT: |
duke@435 | 1773 | case T_BYTE: |
duke@435 | 1774 | case T_SHORT: |
duke@435 | 1775 | case T_INT: |
duke@435 | 1776 | field_array[pos++] = get_const_type(type); |
duke@435 | 1777 | break; |
duke@435 | 1778 | default: |
duke@435 | 1779 | ShouldNotReachHere(); |
duke@435 | 1780 | } |
duke@435 | 1781 | i++; |
duke@435 | 1782 | } |
duke@435 | 1783 | return (TypeTuple*)(new TypeTuple(total_fields,field_array))->hashcons(); |
duke@435 | 1784 | } |
duke@435 | 1785 | |
duke@435 | 1786 | const TypeTuple *TypeTuple::make( uint cnt, const Type **fields ) { |
duke@435 | 1787 | return (TypeTuple*)(new TypeTuple(cnt,fields))->hashcons(); |
duke@435 | 1788 | } |
duke@435 | 1789 | |
duke@435 | 1790 | //------------------------------fields----------------------------------------- |
duke@435 | 1791 | // Subroutine call type with space allocated for argument types |
duke@435 | 1792 | const Type **TypeTuple::fields( uint arg_cnt ) { |
duke@435 | 1793 | const Type **flds = (const Type **)(Compile::current()->type_arena()->Amalloc_4((TypeFunc::Parms+arg_cnt)*sizeof(Type*) )); |
duke@435 | 1794 | flds[TypeFunc::Control ] = Type::CONTROL; |
duke@435 | 1795 | flds[TypeFunc::I_O ] = Type::ABIO; |
duke@435 | 1796 | flds[TypeFunc::Memory ] = Type::MEMORY; |
duke@435 | 1797 | flds[TypeFunc::FramePtr ] = TypeRawPtr::BOTTOM; |
duke@435 | 1798 | flds[TypeFunc::ReturnAdr] = Type::RETURN_ADDRESS; |
duke@435 | 1799 | |
duke@435 | 1800 | return flds; |
duke@435 | 1801 | } |
duke@435 | 1802 | |
duke@435 | 1803 | //------------------------------meet------------------------------------------- |
duke@435 | 1804 | // Compute the MEET of two types. It returns a new Type object. |
duke@435 | 1805 | const Type *TypeTuple::xmeet( const Type *t ) const { |
duke@435 | 1806 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 1807 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 1808 | |
duke@435 | 1809 | // Current "this->_base" is Tuple |
duke@435 | 1810 | switch (t->base()) { // switch on original type |
duke@435 | 1811 | |
duke@435 | 1812 | case Bottom: // Ye Olde Default |
duke@435 | 1813 | return t; |
duke@435 | 1814 | |
duke@435 | 1815 | default: // All else is a mistake |
duke@435 | 1816 | typerr(t); |
duke@435 | 1817 | |
duke@435 | 1818 | case Tuple: { // Meeting 2 signatures? |
duke@435 | 1819 | const TypeTuple *x = t->is_tuple(); |
duke@435 | 1820 | assert( _cnt == x->_cnt, "" ); |
duke@435 | 1821 | const Type **fields = (const Type **)(Compile::current()->type_arena()->Amalloc_4( _cnt*sizeof(Type*) )); |
duke@435 | 1822 | for( uint i=0; i<_cnt; i++ ) |
duke@435 | 1823 | fields[i] = field_at(i)->xmeet( x->field_at(i) ); |
duke@435 | 1824 | return TypeTuple::make(_cnt,fields); |
duke@435 | 1825 | } |
duke@435 | 1826 | case Top: |
duke@435 | 1827 | break; |
duke@435 | 1828 | } |
duke@435 | 1829 | return this; // Return the double constant |
duke@435 | 1830 | } |
duke@435 | 1831 | |
duke@435 | 1832 | //------------------------------xdual------------------------------------------ |
duke@435 | 1833 | // Dual: compute field-by-field dual |
duke@435 | 1834 | const Type *TypeTuple::xdual() const { |
duke@435 | 1835 | const Type **fields = (const Type **)(Compile::current()->type_arena()->Amalloc_4( _cnt*sizeof(Type*) )); |
duke@435 | 1836 | for( uint i=0; i<_cnt; i++ ) |
duke@435 | 1837 | fields[i] = _fields[i]->dual(); |
duke@435 | 1838 | return new TypeTuple(_cnt,fields); |
duke@435 | 1839 | } |
duke@435 | 1840 | |
duke@435 | 1841 | //------------------------------eq--------------------------------------------- |
duke@435 | 1842 | // Structural equality check for Type representations |
duke@435 | 1843 | bool TypeTuple::eq( const Type *t ) const { |
duke@435 | 1844 | const TypeTuple *s = (const TypeTuple *)t; |
duke@435 | 1845 | if (_cnt != s->_cnt) return false; // Unequal field counts |
duke@435 | 1846 | for (uint i = 0; i < _cnt; i++) |
duke@435 | 1847 | if (field_at(i) != s->field_at(i)) // POINTER COMPARE! NO RECURSION! |
duke@435 | 1848 | return false; // Missed |
duke@435 | 1849 | return true; |
duke@435 | 1850 | } |
duke@435 | 1851 | |
duke@435 | 1852 | //------------------------------hash------------------------------------------- |
duke@435 | 1853 | // Type-specific hashing function. |
duke@435 | 1854 | int TypeTuple::hash(void) const { |
duke@435 | 1855 | intptr_t sum = _cnt; |
duke@435 | 1856 | for( uint i=0; i<_cnt; i++ ) |
duke@435 | 1857 | sum += (intptr_t)_fields[i]; // Hash on pointers directly |
duke@435 | 1858 | return sum; |
duke@435 | 1859 | } |
duke@435 | 1860 | |
duke@435 | 1861 | //------------------------------dump2------------------------------------------ |
duke@435 | 1862 | // Dump signature Type |
duke@435 | 1863 | #ifndef PRODUCT |
duke@435 | 1864 | void TypeTuple::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 1865 | st->print("{"); |
duke@435 | 1866 | if( !depth || d[this] ) { // Check for recursive print |
duke@435 | 1867 | st->print("...}"); |
duke@435 | 1868 | return; |
duke@435 | 1869 | } |
duke@435 | 1870 | d.Insert((void*)this, (void*)this); // Stop recursion |
duke@435 | 1871 | if( _cnt ) { |
duke@435 | 1872 | uint i; |
duke@435 | 1873 | for( i=0; i<_cnt-1; i++ ) { |
duke@435 | 1874 | st->print("%d:", i); |
duke@435 | 1875 | _fields[i]->dump2(d, depth-1, st); |
duke@435 | 1876 | st->print(", "); |
duke@435 | 1877 | } |
duke@435 | 1878 | st->print("%d:", i); |
duke@435 | 1879 | _fields[i]->dump2(d, depth-1, st); |
duke@435 | 1880 | } |
duke@435 | 1881 | st->print("}"); |
duke@435 | 1882 | } |
duke@435 | 1883 | #endif |
duke@435 | 1884 | |
duke@435 | 1885 | //------------------------------singleton-------------------------------------- |
duke@435 | 1886 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 1887 | // constants (Ldi nodes). Singletons are integer, float or double constants |
duke@435 | 1888 | // or a single symbol. |
duke@435 | 1889 | bool TypeTuple::singleton(void) const { |
duke@435 | 1890 | return false; // Never a singleton |
duke@435 | 1891 | } |
duke@435 | 1892 | |
duke@435 | 1893 | bool TypeTuple::empty(void) const { |
duke@435 | 1894 | for( uint i=0; i<_cnt; i++ ) { |
duke@435 | 1895 | if (_fields[i]->empty()) return true; |
duke@435 | 1896 | } |
duke@435 | 1897 | return false; |
duke@435 | 1898 | } |
duke@435 | 1899 | |
duke@435 | 1900 | //============================================================================= |
duke@435 | 1901 | // Convenience common pre-built types. |
duke@435 | 1902 | |
duke@435 | 1903 | inline const TypeInt* normalize_array_size(const TypeInt* size) { |
duke@435 | 1904 | // Certain normalizations keep us sane when comparing types. |
duke@435 | 1905 | // We do not want arrayOop variables to differ only by the wideness |
duke@435 | 1906 | // of their index types. Pick minimum wideness, since that is the |
duke@435 | 1907 | // forced wideness of small ranges anyway. |
duke@435 | 1908 | if (size->_widen != Type::WidenMin) |
duke@435 | 1909 | return TypeInt::make(size->_lo, size->_hi, Type::WidenMin); |
duke@435 | 1910 | else |
duke@435 | 1911 | return size; |
duke@435 | 1912 | } |
duke@435 | 1913 | |
duke@435 | 1914 | //------------------------------make------------------------------------------- |
vlivanov@5658 | 1915 | const TypeAry* TypeAry::make(const Type* elem, const TypeInt* size, bool stable) { |
coleenp@548 | 1916 | if (UseCompressedOops && elem->isa_oopptr()) { |
kvn@656 | 1917 | elem = elem->make_narrowoop(); |
coleenp@548 | 1918 | } |
duke@435 | 1919 | size = normalize_array_size(size); |
vlivanov@5658 | 1920 | return (TypeAry*)(new TypeAry(elem,size,stable))->hashcons(); |
duke@435 | 1921 | } |
duke@435 | 1922 | |
duke@435 | 1923 | //------------------------------meet------------------------------------------- |
duke@435 | 1924 | // Compute the MEET of two types. It returns a new Type object. |
duke@435 | 1925 | const Type *TypeAry::xmeet( const Type *t ) const { |
duke@435 | 1926 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 1927 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 1928 | |
duke@435 | 1929 | // Current "this->_base" is Ary |
duke@435 | 1930 | switch (t->base()) { // switch on original type |
duke@435 | 1931 | |
duke@435 | 1932 | case Bottom: // Ye Olde Default |
duke@435 | 1933 | return t; |
duke@435 | 1934 | |
duke@435 | 1935 | default: // All else is a mistake |
duke@435 | 1936 | typerr(t); |
duke@435 | 1937 | |
duke@435 | 1938 | case Array: { // Meeting 2 arrays? |
duke@435 | 1939 | const TypeAry *a = t->is_ary(); |
roland@6313 | 1940 | return TypeAry::make(_elem->meet_speculative(a->_elem), |
vlivanov@5658 | 1941 | _size->xmeet(a->_size)->is_int(), |
vlivanov@5658 | 1942 | _stable & a->_stable); |
duke@435 | 1943 | } |
duke@435 | 1944 | case Top: |
duke@435 | 1945 | break; |
duke@435 | 1946 | } |
duke@435 | 1947 | return this; // Return the double constant |
duke@435 | 1948 | } |
duke@435 | 1949 | |
duke@435 | 1950 | //------------------------------xdual------------------------------------------ |
duke@435 | 1951 | // Dual: compute field-by-field dual |
duke@435 | 1952 | const Type *TypeAry::xdual() const { |
duke@435 | 1953 | const TypeInt* size_dual = _size->dual()->is_int(); |
duke@435 | 1954 | size_dual = normalize_array_size(size_dual); |
vlivanov@5658 | 1955 | return new TypeAry(_elem->dual(), size_dual, !_stable); |
duke@435 | 1956 | } |
duke@435 | 1957 | |
duke@435 | 1958 | //------------------------------eq--------------------------------------------- |
duke@435 | 1959 | // Structural equality check for Type representations |
duke@435 | 1960 | bool TypeAry::eq( const Type *t ) const { |
duke@435 | 1961 | const TypeAry *a = (const TypeAry*)t; |
duke@435 | 1962 | return _elem == a->_elem && |
vlivanov@5658 | 1963 | _stable == a->_stable && |
duke@435 | 1964 | _size == a->_size; |
duke@435 | 1965 | } |
duke@435 | 1966 | |
duke@435 | 1967 | //------------------------------hash------------------------------------------- |
duke@435 | 1968 | // Type-specific hashing function. |
duke@435 | 1969 | int TypeAry::hash(void) const { |
vlivanov@5658 | 1970 | return (intptr_t)_elem + (intptr_t)_size + (_stable ? 43 : 0); |
duke@435 | 1971 | } |
duke@435 | 1972 | |
roland@6313 | 1973 | /** |
roland@6313 | 1974 | * Return same type without a speculative part in the element |
roland@6313 | 1975 | */ |
roland@6313 | 1976 | const Type* TypeAry::remove_speculative() const { |
roland@6313 | 1977 | return make(_elem->remove_speculative(), _size, _stable); |
roland@6313 | 1978 | } |
roland@6313 | 1979 | |
kvn@1255 | 1980 | //----------------------interface_vs_oop--------------------------------------- |
kvn@1255 | 1981 | #ifdef ASSERT |
kvn@1255 | 1982 | bool TypeAry::interface_vs_oop(const Type *t) const { |
kvn@1255 | 1983 | const TypeAry* t_ary = t->is_ary(); |
kvn@1255 | 1984 | if (t_ary) { |
kvn@1255 | 1985 | return _elem->interface_vs_oop(t_ary->_elem); |
kvn@1255 | 1986 | } |
kvn@1255 | 1987 | return false; |
kvn@1255 | 1988 | } |
kvn@1255 | 1989 | #endif |
kvn@1255 | 1990 | |
duke@435 | 1991 | //------------------------------dump2------------------------------------------ |
duke@435 | 1992 | #ifndef PRODUCT |
duke@435 | 1993 | void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const { |
vlivanov@5658 | 1994 | if (_stable) st->print("stable:"); |
duke@435 | 1995 | _elem->dump2(d, depth, st); |
duke@435 | 1996 | st->print("["); |
duke@435 | 1997 | _size->dump2(d, depth, st); |
duke@435 | 1998 | st->print("]"); |
duke@435 | 1999 | } |
duke@435 | 2000 | #endif |
duke@435 | 2001 | |
duke@435 | 2002 | //------------------------------singleton-------------------------------------- |
duke@435 | 2003 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 2004 | // constants (Ldi nodes). Singletons are integer, float or double constants |
duke@435 | 2005 | // or a single symbol. |
duke@435 | 2006 | bool TypeAry::singleton(void) const { |
duke@435 | 2007 | return false; // Never a singleton |
duke@435 | 2008 | } |
duke@435 | 2009 | |
duke@435 | 2010 | bool TypeAry::empty(void) const { |
duke@435 | 2011 | return _elem->empty() || _size->empty(); |
duke@435 | 2012 | } |
duke@435 | 2013 | |
duke@435 | 2014 | //--------------------------ary_must_be_exact---------------------------------- |
duke@435 | 2015 | bool TypeAry::ary_must_be_exact() const { |
duke@435 | 2016 | if (!UseExactTypes) return false; |
duke@435 | 2017 | // This logic looks at the element type of an array, and returns true |
duke@435 | 2018 | // if the element type is either a primitive or a final instance class. |
duke@435 | 2019 | // In such cases, an array built on this ary must have no subclasses. |
duke@435 | 2020 | if (_elem == BOTTOM) return false; // general array not exact |
duke@435 | 2021 | if (_elem == TOP ) return false; // inverted general array not exact |
coleenp@548 | 2022 | const TypeOopPtr* toop = NULL; |
kvn@656 | 2023 | if (UseCompressedOops && _elem->isa_narrowoop()) { |
kvn@656 | 2024 | toop = _elem->make_ptr()->isa_oopptr(); |
coleenp@548 | 2025 | } else { |
coleenp@548 | 2026 | toop = _elem->isa_oopptr(); |
coleenp@548 | 2027 | } |
duke@435 | 2028 | if (!toop) return true; // a primitive type, like int |
duke@435 | 2029 | ciKlass* tklass = toop->klass(); |
duke@435 | 2030 | if (tklass == NULL) return false; // unloaded class |
duke@435 | 2031 | if (!tklass->is_loaded()) return false; // unloaded class |
coleenp@548 | 2032 | const TypeInstPtr* tinst; |
coleenp@548 | 2033 | if (_elem->isa_narrowoop()) |
kvn@656 | 2034 | tinst = _elem->make_ptr()->isa_instptr(); |
coleenp@548 | 2035 | else |
coleenp@548 | 2036 | tinst = _elem->isa_instptr(); |
kvn@656 | 2037 | if (tinst) |
kvn@656 | 2038 | return tklass->as_instance_klass()->is_final(); |
coleenp@548 | 2039 | const TypeAryPtr* tap; |
coleenp@548 | 2040 | if (_elem->isa_narrowoop()) |
kvn@656 | 2041 | tap = _elem->make_ptr()->isa_aryptr(); |
coleenp@548 | 2042 | else |
coleenp@548 | 2043 | tap = _elem->isa_aryptr(); |
kvn@656 | 2044 | if (tap) |
kvn@656 | 2045 | return tap->ary()->ary_must_be_exact(); |
duke@435 | 2046 | return false; |
duke@435 | 2047 | } |
duke@435 | 2048 | |
kvn@3882 | 2049 | //==============================TypeVect======================================= |
kvn@3882 | 2050 | // Convenience common pre-built types. |
kvn@3882 | 2051 | const TypeVect *TypeVect::VECTS = NULL; // 32-bit vectors |
kvn@3882 | 2052 | const TypeVect *TypeVect::VECTD = NULL; // 64-bit vectors |
kvn@3882 | 2053 | const TypeVect *TypeVect::VECTX = NULL; // 128-bit vectors |
kvn@3882 | 2054 | const TypeVect *TypeVect::VECTY = NULL; // 256-bit vectors |
kvn@3882 | 2055 | |
kvn@3882 | 2056 | //------------------------------make------------------------------------------- |
kvn@3882 | 2057 | const TypeVect* TypeVect::make(const Type *elem, uint length) { |
kvn@3882 | 2058 | BasicType elem_bt = elem->array_element_basic_type(); |
kvn@3882 | 2059 | assert(is_java_primitive(elem_bt), "only primitive types in vector"); |
kvn@3882 | 2060 | assert(length > 1 && is_power_of_2(length), "vector length is power of 2"); |
kvn@3882 | 2061 | assert(Matcher::vector_size_supported(elem_bt, length), "length in range"); |
kvn@3882 | 2062 | int size = length * type2aelembytes(elem_bt); |
kvn@3882 | 2063 | switch (Matcher::vector_ideal_reg(size)) { |
kvn@3882 | 2064 | case Op_VecS: |
kvn@3882 | 2065 | return (TypeVect*)(new TypeVectS(elem, length))->hashcons(); |
goetz@6487 | 2066 | case Op_RegL: |
kvn@3882 | 2067 | case Op_VecD: |
kvn@3882 | 2068 | case Op_RegD: |
kvn@3882 | 2069 | return (TypeVect*)(new TypeVectD(elem, length))->hashcons(); |
kvn@3882 | 2070 | case Op_VecX: |
kvn@3882 | 2071 | return (TypeVect*)(new TypeVectX(elem, length))->hashcons(); |
kvn@3882 | 2072 | case Op_VecY: |
kvn@3882 | 2073 | return (TypeVect*)(new TypeVectY(elem, length))->hashcons(); |
kvn@3882 | 2074 | } |
kvn@3882 | 2075 | ShouldNotReachHere(); |
kvn@3882 | 2076 | return NULL; |
kvn@3882 | 2077 | } |
kvn@3882 | 2078 | |
kvn@3882 | 2079 | //------------------------------meet------------------------------------------- |
kvn@3882 | 2080 | // Compute the MEET of two types. It returns a new Type object. |
kvn@3882 | 2081 | const Type *TypeVect::xmeet( const Type *t ) const { |
kvn@3882 | 2082 | // Perform a fast test for common case; meeting the same types together. |
kvn@3882 | 2083 | if( this == t ) return this; // Meeting same type-rep? |
kvn@3882 | 2084 | |
kvn@3882 | 2085 | // Current "this->_base" is Vector |
kvn@3882 | 2086 | switch (t->base()) { // switch on original type |
kvn@3882 | 2087 | |
kvn@3882 | 2088 | case Bottom: // Ye Olde Default |
kvn@3882 | 2089 | return t; |
kvn@3882 | 2090 | |
kvn@3882 | 2091 | default: // All else is a mistake |
kvn@3882 | 2092 | typerr(t); |
kvn@3882 | 2093 | |
kvn@3882 | 2094 | case VectorS: |
kvn@3882 | 2095 | case VectorD: |
kvn@3882 | 2096 | case VectorX: |
kvn@3882 | 2097 | case VectorY: { // Meeting 2 vectors? |
kvn@3882 | 2098 | const TypeVect* v = t->is_vect(); |
kvn@3882 | 2099 | assert( base() == v->base(), ""); |
kvn@3882 | 2100 | assert(length() == v->length(), ""); |
kvn@3882 | 2101 | assert(element_basic_type() == v->element_basic_type(), ""); |
kvn@3882 | 2102 | return TypeVect::make(_elem->xmeet(v->_elem), _length); |
kvn@3882 | 2103 | } |
kvn@3882 | 2104 | case Top: |
kvn@3882 | 2105 | break; |
kvn@3882 | 2106 | } |
kvn@3882 | 2107 | return this; |
kvn@3882 | 2108 | } |
kvn@3882 | 2109 | |
kvn@3882 | 2110 | //------------------------------xdual------------------------------------------ |
kvn@3882 | 2111 | // Dual: compute field-by-field dual |
kvn@3882 | 2112 | const Type *TypeVect::xdual() const { |
kvn@3882 | 2113 | return new TypeVect(base(), _elem->dual(), _length); |
kvn@3882 | 2114 | } |
kvn@3882 | 2115 | |
kvn@3882 | 2116 | //------------------------------eq--------------------------------------------- |
kvn@3882 | 2117 | // Structural equality check for Type representations |
kvn@3882 | 2118 | bool TypeVect::eq(const Type *t) const { |
kvn@3882 | 2119 | const TypeVect *v = t->is_vect(); |
kvn@3882 | 2120 | return (_elem == v->_elem) && (_length == v->_length); |
kvn@3882 | 2121 | } |
kvn@3882 | 2122 | |
kvn@3882 | 2123 | //------------------------------hash------------------------------------------- |
kvn@3882 | 2124 | // Type-specific hashing function. |
kvn@3882 | 2125 | int TypeVect::hash(void) const { |
kvn@3882 | 2126 | return (intptr_t)_elem + (intptr_t)_length; |
kvn@3882 | 2127 | } |
kvn@3882 | 2128 | |
kvn@3882 | 2129 | //------------------------------singleton-------------------------------------- |
kvn@3882 | 2130 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
kvn@3882 | 2131 | // constants (Ldi nodes). Vector is singleton if all elements are the same |
kvn@3882 | 2132 | // constant value (when vector is created with Replicate code). |
kvn@3882 | 2133 | bool TypeVect::singleton(void) const { |
kvn@3882 | 2134 | // There is no Con node for vectors yet. |
kvn@3882 | 2135 | // return _elem->singleton(); |
kvn@3882 | 2136 | return false; |
kvn@3882 | 2137 | } |
kvn@3882 | 2138 | |
kvn@3882 | 2139 | bool TypeVect::empty(void) const { |
kvn@3882 | 2140 | return _elem->empty(); |
kvn@3882 | 2141 | } |
kvn@3882 | 2142 | |
kvn@3882 | 2143 | //------------------------------dump2------------------------------------------ |
kvn@3882 | 2144 | #ifndef PRODUCT |
kvn@3882 | 2145 | void TypeVect::dump2(Dict &d, uint depth, outputStream *st) const { |
kvn@3882 | 2146 | switch (base()) { |
kvn@3882 | 2147 | case VectorS: |
kvn@3882 | 2148 | st->print("vectors["); break; |
kvn@3882 | 2149 | case VectorD: |
kvn@3882 | 2150 | st->print("vectord["); break; |
kvn@3882 | 2151 | case VectorX: |
kvn@3882 | 2152 | st->print("vectorx["); break; |
kvn@3882 | 2153 | case VectorY: |
kvn@3882 | 2154 | st->print("vectory["); break; |
kvn@3882 | 2155 | default: |
kvn@3882 | 2156 | ShouldNotReachHere(); |
kvn@3882 | 2157 | } |
kvn@3882 | 2158 | st->print("%d]:{", _length); |
kvn@3882 | 2159 | _elem->dump2(d, depth, st); |
kvn@3882 | 2160 | st->print("}"); |
kvn@3882 | 2161 | } |
kvn@3882 | 2162 | #endif |
kvn@3882 | 2163 | |
kvn@3882 | 2164 | |
duke@435 | 2165 | //============================================================================= |
duke@435 | 2166 | // Convenience common pre-built types. |
duke@435 | 2167 | const TypePtr *TypePtr::NULL_PTR; |
duke@435 | 2168 | const TypePtr *TypePtr::NOTNULL; |
duke@435 | 2169 | const TypePtr *TypePtr::BOTTOM; |
duke@435 | 2170 | |
duke@435 | 2171 | //------------------------------meet------------------------------------------- |
duke@435 | 2172 | // Meet over the PTR enum |
duke@435 | 2173 | const TypePtr::PTR TypePtr::ptr_meet[TypePtr::lastPTR][TypePtr::lastPTR] = { |
duke@435 | 2174 | // TopPTR, AnyNull, Constant, Null, NotNull, BotPTR, |
duke@435 | 2175 | { /* Top */ TopPTR, AnyNull, Constant, Null, NotNull, BotPTR,}, |
duke@435 | 2176 | { /* AnyNull */ AnyNull, AnyNull, Constant, BotPTR, NotNull, BotPTR,}, |
duke@435 | 2177 | { /* Constant*/ Constant, Constant, Constant, BotPTR, NotNull, BotPTR,}, |
duke@435 | 2178 | { /* Null */ Null, BotPTR, BotPTR, Null, BotPTR, BotPTR,}, |
duke@435 | 2179 | { /* NotNull */ NotNull, NotNull, NotNull, BotPTR, NotNull, BotPTR,}, |
duke@435 | 2180 | { /* BotPTR */ BotPTR, BotPTR, BotPTR, BotPTR, BotPTR, BotPTR,} |
duke@435 | 2181 | }; |
duke@435 | 2182 | |
duke@435 | 2183 | //------------------------------make------------------------------------------- |
duke@435 | 2184 | const TypePtr *TypePtr::make( TYPES t, enum PTR ptr, int offset ) { |
duke@435 | 2185 | return (TypePtr*)(new TypePtr(t,ptr,offset))->hashcons(); |
duke@435 | 2186 | } |
duke@435 | 2187 | |
duke@435 | 2188 | //------------------------------cast_to_ptr_type------------------------------- |
duke@435 | 2189 | const Type *TypePtr::cast_to_ptr_type(PTR ptr) const { |
duke@435 | 2190 | assert(_base == AnyPtr, "subclass must override cast_to_ptr_type"); |
duke@435 | 2191 | if( ptr == _ptr ) return this; |
duke@435 | 2192 | return make(_base, ptr, _offset); |
duke@435 | 2193 | } |
duke@435 | 2194 | |
duke@435 | 2195 | //------------------------------get_con---------------------------------------- |
duke@435 | 2196 | intptr_t TypePtr::get_con() const { |
duke@435 | 2197 | assert( _ptr == Null, "" ); |
duke@435 | 2198 | return _offset; |
duke@435 | 2199 | } |
duke@435 | 2200 | |
duke@435 | 2201 | //------------------------------meet------------------------------------------- |
duke@435 | 2202 | // Compute the MEET of two types. It returns a new Type object. |
duke@435 | 2203 | const Type *TypePtr::xmeet( const Type *t ) const { |
duke@435 | 2204 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 2205 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 2206 | |
duke@435 | 2207 | // Current "this->_base" is AnyPtr |
duke@435 | 2208 | switch (t->base()) { // switch on original type |
duke@435 | 2209 | case Int: // Mixing ints & oops happens when javac |
duke@435 | 2210 | case Long: // reuses local variables |
duke@435 | 2211 | case FloatTop: |
duke@435 | 2212 | case FloatCon: |
duke@435 | 2213 | case FloatBot: |
duke@435 | 2214 | case DoubleTop: |
duke@435 | 2215 | case DoubleCon: |
duke@435 | 2216 | case DoubleBot: |
coleenp@548 | 2217 | case NarrowOop: |
roland@4159 | 2218 | case NarrowKlass: |
duke@435 | 2219 | case Bottom: // Ye Olde Default |
duke@435 | 2220 | return Type::BOTTOM; |
duke@435 | 2221 | case Top: |
duke@435 | 2222 | return this; |
duke@435 | 2223 | |
duke@435 | 2224 | case AnyPtr: { // Meeting to AnyPtrs |
duke@435 | 2225 | const TypePtr *tp = t->is_ptr(); |
duke@435 | 2226 | return make( AnyPtr, meet_ptr(tp->ptr()), meet_offset(tp->offset()) ); |
duke@435 | 2227 | } |
duke@435 | 2228 | case RawPtr: // For these, flip the call around to cut down |
duke@435 | 2229 | case OopPtr: |
duke@435 | 2230 | case InstPtr: // on the cases I have to handle. |
coleenp@4037 | 2231 | case AryPtr: |
coleenp@4037 | 2232 | case MetadataPtr: |
duke@435 | 2233 | case KlassPtr: |
duke@435 | 2234 | return t->xmeet(this); // Call in reverse direction |
duke@435 | 2235 | default: // All else is a mistake |
duke@435 | 2236 | typerr(t); |
duke@435 | 2237 | |
duke@435 | 2238 | } |
duke@435 | 2239 | return this; |
duke@435 | 2240 | } |
duke@435 | 2241 | |
duke@435 | 2242 | //------------------------------meet_offset------------------------------------ |
duke@435 | 2243 | int TypePtr::meet_offset( int offset ) const { |
duke@435 | 2244 | // Either is 'TOP' offset? Return the other offset! |
duke@435 | 2245 | if( _offset == OffsetTop ) return offset; |
duke@435 | 2246 | if( offset == OffsetTop ) return _offset; |
duke@435 | 2247 | // If either is different, return 'BOTTOM' offset |
duke@435 | 2248 | if( _offset != offset ) return OffsetBot; |
duke@435 | 2249 | return _offset; |
duke@435 | 2250 | } |
duke@435 | 2251 | |
duke@435 | 2252 | //------------------------------dual_offset------------------------------------ |
duke@435 | 2253 | int TypePtr::dual_offset( ) const { |
duke@435 | 2254 | if( _offset == OffsetTop ) return OffsetBot;// Map 'TOP' into 'BOTTOM' |
duke@435 | 2255 | if( _offset == OffsetBot ) return OffsetTop;// Map 'BOTTOM' into 'TOP' |
duke@435 | 2256 | return _offset; // Map everything else into self |
duke@435 | 2257 | } |
duke@435 | 2258 | |
duke@435 | 2259 | //------------------------------xdual------------------------------------------ |
duke@435 | 2260 | // Dual: compute field-by-field dual |
duke@435 | 2261 | const TypePtr::PTR TypePtr::ptr_dual[TypePtr::lastPTR] = { |
duke@435 | 2262 | BotPTR, NotNull, Constant, Null, AnyNull, TopPTR |
duke@435 | 2263 | }; |
duke@435 | 2264 | const Type *TypePtr::xdual() const { |
duke@435 | 2265 | return new TypePtr( AnyPtr, dual_ptr(), dual_offset() ); |
duke@435 | 2266 | } |
duke@435 | 2267 | |
kvn@741 | 2268 | //------------------------------xadd_offset------------------------------------ |
kvn@741 | 2269 | int TypePtr::xadd_offset( intptr_t offset ) const { |
kvn@741 | 2270 | // Adding to 'TOP' offset? Return 'TOP'! |
kvn@741 | 2271 | if( _offset == OffsetTop || offset == OffsetTop ) return OffsetTop; |
kvn@741 | 2272 | // Adding to 'BOTTOM' offset? Return 'BOTTOM'! |
kvn@741 | 2273 | if( _offset == OffsetBot || offset == OffsetBot ) return OffsetBot; |
kvn@741 | 2274 | // Addition overflows or "accidentally" equals to OffsetTop? Return 'BOTTOM'! |
kvn@741 | 2275 | offset += (intptr_t)_offset; |
kvn@741 | 2276 | if (offset != (int)offset || offset == OffsetTop) return OffsetBot; |
kvn@741 | 2277 | |
kvn@741 | 2278 | // assert( _offset >= 0 && _offset+offset >= 0, "" ); |
kvn@741 | 2279 | // It is possible to construct a negative offset during PhaseCCP |
kvn@741 | 2280 | |
kvn@741 | 2281 | return (int)offset; // Sum valid offsets |
kvn@741 | 2282 | } |
kvn@741 | 2283 | |
duke@435 | 2284 | //------------------------------add_offset------------------------------------- |
kvn@741 | 2285 | const TypePtr *TypePtr::add_offset( intptr_t offset ) const { |
kvn@741 | 2286 | return make( AnyPtr, _ptr, xadd_offset(offset) ); |
duke@435 | 2287 | } |
duke@435 | 2288 | |
duke@435 | 2289 | //------------------------------eq--------------------------------------------- |
duke@435 | 2290 | // Structural equality check for Type representations |
duke@435 | 2291 | bool TypePtr::eq( const Type *t ) const { |
duke@435 | 2292 | const TypePtr *a = (const TypePtr*)t; |
duke@435 | 2293 | return _ptr == a->ptr() && _offset == a->offset(); |
duke@435 | 2294 | } |
duke@435 | 2295 | |
duke@435 | 2296 | //------------------------------hash------------------------------------------- |
duke@435 | 2297 | // Type-specific hashing function. |
duke@435 | 2298 | int TypePtr::hash(void) const { |
duke@435 | 2299 | return _ptr + _offset; |
duke@435 | 2300 | } |
duke@435 | 2301 | |
duke@435 | 2302 | //------------------------------dump2------------------------------------------ |
duke@435 | 2303 | const char *const TypePtr::ptr_msg[TypePtr::lastPTR] = { |
duke@435 | 2304 | "TopPTR","AnyNull","Constant","NULL","NotNull","BotPTR" |
duke@435 | 2305 | }; |
duke@435 | 2306 | |
duke@435 | 2307 | #ifndef PRODUCT |
duke@435 | 2308 | void TypePtr::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 2309 | if( _ptr == Null ) st->print("NULL"); |
duke@435 | 2310 | else st->print("%s *", ptr_msg[_ptr]); |
duke@435 | 2311 | if( _offset == OffsetTop ) st->print("+top"); |
duke@435 | 2312 | else if( _offset == OffsetBot ) st->print("+bot"); |
duke@435 | 2313 | else if( _offset ) st->print("+%d", _offset); |
duke@435 | 2314 | } |
duke@435 | 2315 | #endif |
duke@435 | 2316 | |
duke@435 | 2317 | //------------------------------singleton-------------------------------------- |
duke@435 | 2318 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 2319 | // constants |
duke@435 | 2320 | bool TypePtr::singleton(void) const { |
duke@435 | 2321 | // TopPTR, Null, AnyNull, Constant are all singletons |
duke@435 | 2322 | return (_offset != OffsetBot) && !below_centerline(_ptr); |
duke@435 | 2323 | } |
duke@435 | 2324 | |
duke@435 | 2325 | bool TypePtr::empty(void) const { |
duke@435 | 2326 | return (_offset == OffsetTop) || above_centerline(_ptr); |
duke@435 | 2327 | } |
duke@435 | 2328 | |
duke@435 | 2329 | //============================================================================= |
duke@435 | 2330 | // Convenience common pre-built types. |
duke@435 | 2331 | const TypeRawPtr *TypeRawPtr::BOTTOM; |
duke@435 | 2332 | const TypeRawPtr *TypeRawPtr::NOTNULL; |
duke@435 | 2333 | |
duke@435 | 2334 | //------------------------------make------------------------------------------- |
duke@435 | 2335 | const TypeRawPtr *TypeRawPtr::make( enum PTR ptr ) { |
duke@435 | 2336 | assert( ptr != Constant, "what is the constant?" ); |
duke@435 | 2337 | assert( ptr != Null, "Use TypePtr for NULL" ); |
duke@435 | 2338 | return (TypeRawPtr*)(new TypeRawPtr(ptr,0))->hashcons(); |
duke@435 | 2339 | } |
duke@435 | 2340 | |
duke@435 | 2341 | const TypeRawPtr *TypeRawPtr::make( address bits ) { |
duke@435 | 2342 | assert( bits, "Use TypePtr for NULL" ); |
duke@435 | 2343 | return (TypeRawPtr*)(new TypeRawPtr(Constant,bits))->hashcons(); |
duke@435 | 2344 | } |
duke@435 | 2345 | |
duke@435 | 2346 | //------------------------------cast_to_ptr_type------------------------------- |
duke@435 | 2347 | const Type *TypeRawPtr::cast_to_ptr_type(PTR ptr) const { |
duke@435 | 2348 | assert( ptr != Constant, "what is the constant?" ); |
duke@435 | 2349 | assert( ptr != Null, "Use TypePtr for NULL" ); |
duke@435 | 2350 | assert( _bits==0, "Why cast a constant address?"); |
duke@435 | 2351 | if( ptr == _ptr ) return this; |
duke@435 | 2352 | return make(ptr); |
duke@435 | 2353 | } |
duke@435 | 2354 | |
duke@435 | 2355 | //------------------------------get_con---------------------------------------- |
duke@435 | 2356 | intptr_t TypeRawPtr::get_con() const { |
duke@435 | 2357 | assert( _ptr == Null || _ptr == Constant, "" ); |
duke@435 | 2358 | return (intptr_t)_bits; |
duke@435 | 2359 | } |
duke@435 | 2360 | |
duke@435 | 2361 | //------------------------------meet------------------------------------------- |
duke@435 | 2362 | // Compute the MEET of two types. It returns a new Type object. |
duke@435 | 2363 | const Type *TypeRawPtr::xmeet( const Type *t ) const { |
duke@435 | 2364 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 2365 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 2366 | |
duke@435 | 2367 | // Current "this->_base" is RawPtr |
duke@435 | 2368 | switch( t->base() ) { // switch on original type |
duke@435 | 2369 | case Bottom: // Ye Olde Default |
duke@435 | 2370 | return t; |
duke@435 | 2371 | case Top: |
duke@435 | 2372 | return this; |
duke@435 | 2373 | case AnyPtr: // Meeting to AnyPtrs |
duke@435 | 2374 | break; |
duke@435 | 2375 | case RawPtr: { // might be top, bot, any/not or constant |
duke@435 | 2376 | enum PTR tptr = t->is_ptr()->ptr(); |
duke@435 | 2377 | enum PTR ptr = meet_ptr( tptr ); |
duke@435 | 2378 | if( ptr == Constant ) { // Cannot be equal constants, so... |
duke@435 | 2379 | if( tptr == Constant && _ptr != Constant) return t; |
duke@435 | 2380 | if( _ptr == Constant && tptr != Constant) return this; |
duke@435 | 2381 | ptr = NotNull; // Fall down in lattice |
duke@435 | 2382 | } |
duke@435 | 2383 | return make( ptr ); |
duke@435 | 2384 | } |
duke@435 | 2385 | |
duke@435 | 2386 | case OopPtr: |
duke@435 | 2387 | case InstPtr: |
coleenp@4037 | 2388 | case AryPtr: |
coleenp@4037 | 2389 | case MetadataPtr: |
duke@435 | 2390 | case KlassPtr: |
duke@435 | 2391 | return TypePtr::BOTTOM; // Oop meet raw is not well defined |
duke@435 | 2392 | default: // All else is a mistake |
duke@435 | 2393 | typerr(t); |
duke@435 | 2394 | } |
duke@435 | 2395 | |
duke@435 | 2396 | // Found an AnyPtr type vs self-RawPtr type |
duke@435 | 2397 | const TypePtr *tp = t->is_ptr(); |
duke@435 | 2398 | switch (tp->ptr()) { |
duke@435 | 2399 | case TypePtr::TopPTR: return this; |
duke@435 | 2400 | case TypePtr::BotPTR: return t; |
duke@435 | 2401 | case TypePtr::Null: |
duke@435 | 2402 | if( _ptr == TypePtr::TopPTR ) return t; |
duke@435 | 2403 | return TypeRawPtr::BOTTOM; |
duke@435 | 2404 | case TypePtr::NotNull: return TypePtr::make( AnyPtr, meet_ptr(TypePtr::NotNull), tp->meet_offset(0) ); |
duke@435 | 2405 | case TypePtr::AnyNull: |
duke@435 | 2406 | if( _ptr == TypePtr::Constant) return this; |
duke@435 | 2407 | return make( meet_ptr(TypePtr::AnyNull) ); |
duke@435 | 2408 | default: ShouldNotReachHere(); |
duke@435 | 2409 | } |
duke@435 | 2410 | return this; |
duke@435 | 2411 | } |
duke@435 | 2412 | |
duke@435 | 2413 | //------------------------------xdual------------------------------------------ |
duke@435 | 2414 | // Dual: compute field-by-field dual |
duke@435 | 2415 | const Type *TypeRawPtr::xdual() const { |
duke@435 | 2416 | return new TypeRawPtr( dual_ptr(), _bits ); |
duke@435 | 2417 | } |
duke@435 | 2418 | |
duke@435 | 2419 | //------------------------------add_offset------------------------------------- |
kvn@741 | 2420 | const TypePtr *TypeRawPtr::add_offset( intptr_t offset ) const { |
duke@435 | 2421 | if( offset == OffsetTop ) return BOTTOM; // Undefined offset-> undefined pointer |
duke@435 | 2422 | if( offset == OffsetBot ) return BOTTOM; // Unknown offset-> unknown pointer |
duke@435 | 2423 | if( offset == 0 ) return this; // No change |
duke@435 | 2424 | switch (_ptr) { |
duke@435 | 2425 | case TypePtr::TopPTR: |
duke@435 | 2426 | case TypePtr::BotPTR: |
duke@435 | 2427 | case TypePtr::NotNull: |
duke@435 | 2428 | return this; |
duke@435 | 2429 | case TypePtr::Null: |
kvn@2435 | 2430 | case TypePtr::Constant: { |
kvn@2435 | 2431 | address bits = _bits+offset; |
kvn@2435 | 2432 | if ( bits == 0 ) return TypePtr::NULL_PTR; |
kvn@2435 | 2433 | return make( bits ); |
kvn@2435 | 2434 | } |
duke@435 | 2435 | default: ShouldNotReachHere(); |
duke@435 | 2436 | } |
duke@435 | 2437 | return NULL; // Lint noise |
duke@435 | 2438 | } |
duke@435 | 2439 | |
duke@435 | 2440 | //------------------------------eq--------------------------------------------- |
duke@435 | 2441 | // Structural equality check for Type representations |
duke@435 | 2442 | bool TypeRawPtr::eq( const Type *t ) const { |
duke@435 | 2443 | const TypeRawPtr *a = (const TypeRawPtr*)t; |
duke@435 | 2444 | return _bits == a->_bits && TypePtr::eq(t); |
duke@435 | 2445 | } |
duke@435 | 2446 | |
duke@435 | 2447 | //------------------------------hash------------------------------------------- |
duke@435 | 2448 | // Type-specific hashing function. |
duke@435 | 2449 | int TypeRawPtr::hash(void) const { |
duke@435 | 2450 | return (intptr_t)_bits + TypePtr::hash(); |
duke@435 | 2451 | } |
duke@435 | 2452 | |
duke@435 | 2453 | //------------------------------dump2------------------------------------------ |
duke@435 | 2454 | #ifndef PRODUCT |
duke@435 | 2455 | void TypeRawPtr::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 2456 | if( _ptr == Constant ) |
duke@435 | 2457 | st->print(INTPTR_FORMAT, _bits); |
duke@435 | 2458 | else |
duke@435 | 2459 | st->print("rawptr:%s", ptr_msg[_ptr]); |
duke@435 | 2460 | } |
duke@435 | 2461 | #endif |
duke@435 | 2462 | |
duke@435 | 2463 | //============================================================================= |
duke@435 | 2464 | // Convenience common pre-built type. |
duke@435 | 2465 | const TypeOopPtr *TypeOopPtr::BOTTOM; |
duke@435 | 2466 | |
kvn@598 | 2467 | //------------------------------TypeOopPtr------------------------------------- |
roland@6380 | 2468 | TypeOopPtr::TypeOopPtr(TYPES t, PTR ptr, ciKlass* k, bool xk, ciObject* o, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth) |
kvn@598 | 2469 | : TypePtr(t, ptr, offset), |
kvn@598 | 2470 | _const_oop(o), _klass(k), |
kvn@598 | 2471 | _klass_is_exact(xk), |
kvn@598 | 2472 | _is_ptr_to_narrowoop(false), |
roland@4159 | 2473 | _is_ptr_to_narrowklass(false), |
kvn@5110 | 2474 | _is_ptr_to_boxed_value(false), |
roland@5991 | 2475 | _instance_id(instance_id), |
roland@6380 | 2476 | _speculative(speculative), |
roland@6380 | 2477 | _inline_depth(inline_depth){ |
kvn@5110 | 2478 | if (Compile::current()->eliminate_boxing() && (t == InstPtr) && |
kvn@5110 | 2479 | (offset > 0) && xk && (k != 0) && k->is_instance_klass()) { |
kvn@5110 | 2480 | _is_ptr_to_boxed_value = k->as_instance_klass()->is_boxed_value_offset(offset); |
kvn@5110 | 2481 | } |
kvn@598 | 2482 | #ifdef _LP64 |
roland@4159 | 2483 | if (_offset != 0) { |
coleenp@4037 | 2484 | if (_offset == oopDesc::klass_offset_in_bytes()) { |
ehelin@5694 | 2485 | _is_ptr_to_narrowklass = UseCompressedClassPointers; |
coleenp@4037 | 2486 | } else if (klass() == NULL) { |
coleenp@4037 | 2487 | // Array with unknown body type |
kvn@598 | 2488 | assert(this->isa_aryptr(), "only arrays without klass"); |
roland@4159 | 2489 | _is_ptr_to_narrowoop = UseCompressedOops; |
kvn@598 | 2490 | } else if (this->isa_aryptr()) { |
roland@4159 | 2491 | _is_ptr_to_narrowoop = (UseCompressedOops && klass()->is_obj_array_klass() && |
kvn@598 | 2492 | _offset != arrayOopDesc::length_offset_in_bytes()); |
kvn@598 | 2493 | } else if (klass()->is_instance_klass()) { |
kvn@598 | 2494 | ciInstanceKlass* ik = klass()->as_instance_klass(); |
kvn@598 | 2495 | ciField* field = NULL; |
kvn@598 | 2496 | if (this->isa_klassptr()) { |
never@2658 | 2497 | // Perm objects don't use compressed references |
kvn@598 | 2498 | } else if (_offset == OffsetBot || _offset == OffsetTop) { |
kvn@598 | 2499 | // unsafe access |
roland@4159 | 2500 | _is_ptr_to_narrowoop = UseCompressedOops; |
kvn@598 | 2501 | } else { // exclude unsafe ops |
kvn@598 | 2502 | assert(this->isa_instptr(), "must be an instance ptr."); |
never@2658 | 2503 | |
never@2658 | 2504 | if (klass() == ciEnv::current()->Class_klass() && |
never@2658 | 2505 | (_offset == java_lang_Class::klass_offset_in_bytes() || |
never@2658 | 2506 | _offset == java_lang_Class::array_klass_offset_in_bytes())) { |
never@2658 | 2507 | // Special hidden fields from the Class. |
never@2658 | 2508 | assert(this->isa_instptr(), "must be an instance ptr."); |
coleenp@4037 | 2509 | _is_ptr_to_narrowoop = false; |
never@2658 | 2510 | } else if (klass() == ciEnv::current()->Class_klass() && |
coleenp@4047 | 2511 | _offset >= InstanceMirrorKlass::offset_of_static_fields()) { |
never@2658 | 2512 | // Static fields |
never@2658 | 2513 | assert(o != NULL, "must be constant"); |
never@2658 | 2514 | ciInstanceKlass* k = o->as_instance()->java_lang_Class_klass()->as_instance_klass(); |
never@2658 | 2515 | ciField* field = k->get_field_by_offset(_offset, true); |
never@2658 | 2516 | assert(field != NULL, "missing field"); |
kvn@598 | 2517 | BasicType basic_elem_type = field->layout_type(); |
roland@4159 | 2518 | _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT || |
roland@4159 | 2519 | basic_elem_type == T_ARRAY); |
kvn@598 | 2520 | } else { |
never@2658 | 2521 | // Instance fields which contains a compressed oop references. |
never@2658 | 2522 | field = ik->get_field_by_offset(_offset, false); |
never@2658 | 2523 | if (field != NULL) { |
never@2658 | 2524 | BasicType basic_elem_type = field->layout_type(); |
roland@4159 | 2525 | _is_ptr_to_narrowoop = UseCompressedOops && (basic_elem_type == T_OBJECT || |
roland@4159 | 2526 | basic_elem_type == T_ARRAY); |
never@2658 | 2527 | } else if (klass()->equals(ciEnv::current()->Object_klass())) { |
never@2658 | 2528 | // Compile::find_alias_type() cast exactness on all types to verify |
never@2658 | 2529 | // that it does not affect alias type. |
roland@4159 | 2530 | _is_ptr_to_narrowoop = UseCompressedOops; |
never@2658 | 2531 | } else { |
never@2658 | 2532 | // Type for the copy start in LibraryCallKit::inline_native_clone(). |
roland@4159 | 2533 | _is_ptr_to_narrowoop = UseCompressedOops; |
never@2658 | 2534 | } |
kvn@598 | 2535 | } |
kvn@598 | 2536 | } |
kvn@598 | 2537 | } |
kvn@598 | 2538 | } |
kvn@598 | 2539 | #endif |
kvn@598 | 2540 | } |
kvn@598 | 2541 | |
duke@435 | 2542 | //------------------------------make------------------------------------------- |
duke@435 | 2543 | const TypeOopPtr *TypeOopPtr::make(PTR ptr, |
roland@6380 | 2544 | int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth) { |
duke@435 | 2545 | assert(ptr != Constant, "no constant generic pointers"); |
coleenp@4037 | 2546 | ciKlass* k = Compile::current()->env()->Object_klass(); |
duke@435 | 2547 | bool xk = false; |
duke@435 | 2548 | ciObject* o = NULL; |
roland@6380 | 2549 | return (TypeOopPtr*)(new TypeOopPtr(OopPtr, ptr, k, xk, o, offset, instance_id, speculative, inline_depth))->hashcons(); |
duke@435 | 2550 | } |
duke@435 | 2551 | |
duke@435 | 2552 | |
duke@435 | 2553 | //------------------------------cast_to_ptr_type------------------------------- |
duke@435 | 2554 | const Type *TypeOopPtr::cast_to_ptr_type(PTR ptr) const { |
duke@435 | 2555 | assert(_base == OopPtr, "subclass must override cast_to_ptr_type"); |
duke@435 | 2556 | if( ptr == _ptr ) return this; |
roland@6380 | 2557 | return make(ptr, _offset, _instance_id, _speculative, _inline_depth); |
duke@435 | 2558 | } |
duke@435 | 2559 | |
kvn@682 | 2560 | //-----------------------------cast_to_instance_id---------------------------- |
kvn@658 | 2561 | const TypeOopPtr *TypeOopPtr::cast_to_instance_id(int instance_id) const { |
duke@435 | 2562 | // There are no instances of a general oop. |
duke@435 | 2563 | // Return self unchanged. |
duke@435 | 2564 | return this; |
duke@435 | 2565 | } |
duke@435 | 2566 | |
duke@435 | 2567 | //-----------------------------cast_to_exactness------------------------------- |
duke@435 | 2568 | const Type *TypeOopPtr::cast_to_exactness(bool klass_is_exact) const { |
duke@435 | 2569 | // There is no such thing as an exact general oop. |
duke@435 | 2570 | // Return self unchanged. |
duke@435 | 2571 | return this; |
duke@435 | 2572 | } |
duke@435 | 2573 | |
duke@435 | 2574 | |
duke@435 | 2575 | //------------------------------as_klass_type---------------------------------- |
duke@435 | 2576 | // Return the klass type corresponding to this instance or array type. |
duke@435 | 2577 | // It is the type that is loaded from an object of this type. |
duke@435 | 2578 | const TypeKlassPtr* TypeOopPtr::as_klass_type() const { |
duke@435 | 2579 | ciKlass* k = klass(); |
duke@435 | 2580 | bool xk = klass_is_exact(); |
coleenp@4037 | 2581 | if (k == NULL) |
duke@435 | 2582 | return TypeKlassPtr::OBJECT; |
duke@435 | 2583 | else |
duke@435 | 2584 | return TypeKlassPtr::make(xk? Constant: NotNull, k, 0); |
duke@435 | 2585 | } |
duke@435 | 2586 | |
roland@5991 | 2587 | const Type *TypeOopPtr::xmeet(const Type *t) const { |
roland@5991 | 2588 | const Type* res = xmeet_helper(t); |
roland@5991 | 2589 | if (res->isa_oopptr() == NULL) { |
roland@5991 | 2590 | return res; |
roland@5991 | 2591 | } |
roland@5991 | 2592 | |
roland@6313 | 2593 | const TypeOopPtr* res_oopptr = res->is_oopptr(); |
roland@6313 | 2594 | if (res_oopptr->speculative() != NULL) { |
roland@5991 | 2595 | // type->speculative() == NULL means that speculation is no better |
roland@5991 | 2596 | // than type, i.e. type->speculative() == type. So there are 2 |
roland@5991 | 2597 | // ways to represent the fact that we have no useful speculative |
roland@5991 | 2598 | // data and we should use a single one to be able to test for |
roland@5991 | 2599 | // equality between types. Check whether type->speculative() == |
roland@5991 | 2600 | // type and set speculative to NULL if it is the case. |
roland@5991 | 2601 | if (res_oopptr->remove_speculative() == res_oopptr->speculative()) { |
roland@5991 | 2602 | return res_oopptr->remove_speculative(); |
roland@5991 | 2603 | } |
roland@5991 | 2604 | } |
roland@5991 | 2605 | |
roland@5991 | 2606 | return res; |
roland@5991 | 2607 | } |
duke@435 | 2608 | |
duke@435 | 2609 | //------------------------------meet------------------------------------------- |
duke@435 | 2610 | // Compute the MEET of two types. It returns a new Type object. |
roland@5991 | 2611 | const Type *TypeOopPtr::xmeet_helper(const Type *t) const { |
duke@435 | 2612 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 2613 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 2614 | |
duke@435 | 2615 | // Current "this->_base" is OopPtr |
duke@435 | 2616 | switch (t->base()) { // switch on original type |
duke@435 | 2617 | |
duke@435 | 2618 | case Int: // Mixing ints & oops happens when javac |
duke@435 | 2619 | case Long: // reuses local variables |
duke@435 | 2620 | case FloatTop: |
duke@435 | 2621 | case FloatCon: |
duke@435 | 2622 | case FloatBot: |
duke@435 | 2623 | case DoubleTop: |
duke@435 | 2624 | case DoubleCon: |
duke@435 | 2625 | case DoubleBot: |
kvn@728 | 2626 | case NarrowOop: |
roland@4159 | 2627 | case NarrowKlass: |
duke@435 | 2628 | case Bottom: // Ye Olde Default |
duke@435 | 2629 | return Type::BOTTOM; |
duke@435 | 2630 | case Top: |
duke@435 | 2631 | return this; |
duke@435 | 2632 | |
duke@435 | 2633 | default: // All else is a mistake |
duke@435 | 2634 | typerr(t); |
duke@435 | 2635 | |
duke@435 | 2636 | case RawPtr: |
coleenp@4037 | 2637 | case MetadataPtr: |
coleenp@4037 | 2638 | case KlassPtr: |
duke@435 | 2639 | return TypePtr::BOTTOM; // Oop meet raw is not well defined |
duke@435 | 2640 | |
duke@435 | 2641 | case AnyPtr: { |
duke@435 | 2642 | // Found an AnyPtr type vs self-OopPtr type |
duke@435 | 2643 | const TypePtr *tp = t->is_ptr(); |
duke@435 | 2644 | int offset = meet_offset(tp->offset()); |
duke@435 | 2645 | PTR ptr = meet_ptr(tp->ptr()); |
duke@435 | 2646 | switch (tp->ptr()) { |
duke@435 | 2647 | case Null: |
duke@435 | 2648 | if (ptr == Null) return TypePtr::make(AnyPtr, ptr, offset); |
duke@435 | 2649 | // else fall through: |
duke@435 | 2650 | case TopPTR: |
kvn@1427 | 2651 | case AnyNull: { |
kvn@1427 | 2652 | int instance_id = meet_instance_id(InstanceTop); |
roland@5991 | 2653 | const TypeOopPtr* speculative = _speculative; |
roland@6380 | 2654 | return make(ptr, offset, instance_id, speculative, _inline_depth); |
kvn@1427 | 2655 | } |
duke@435 | 2656 | case BotPTR: |
duke@435 | 2657 | case NotNull: |
duke@435 | 2658 | return TypePtr::make(AnyPtr, ptr, offset); |
duke@435 | 2659 | default: typerr(t); |
duke@435 | 2660 | } |
duke@435 | 2661 | } |
duke@435 | 2662 | |
duke@435 | 2663 | case OopPtr: { // Meeting to other OopPtrs |
duke@435 | 2664 | const TypeOopPtr *tp = t->is_oopptr(); |
kvn@1393 | 2665 | int instance_id = meet_instance_id(tp->instance_id()); |
roland@6313 | 2666 | const TypeOopPtr* speculative = xmeet_speculative(tp); |
roland@6380 | 2667 | int depth = meet_inline_depth(tp->inline_depth()); |
roland@6380 | 2668 | return make(meet_ptr(tp->ptr()), meet_offset(tp->offset()), instance_id, speculative, depth); |
duke@435 | 2669 | } |
duke@435 | 2670 | |
duke@435 | 2671 | case InstPtr: // For these, flip the call around to cut down |
duke@435 | 2672 | case AryPtr: |
duke@435 | 2673 | return t->xmeet(this); // Call in reverse direction |
duke@435 | 2674 | |
duke@435 | 2675 | } // End of switch |
duke@435 | 2676 | return this; // Return the double constant |
duke@435 | 2677 | } |
duke@435 | 2678 | |
duke@435 | 2679 | |
duke@435 | 2680 | //------------------------------xdual------------------------------------------ |
duke@435 | 2681 | // Dual of a pure heap pointer. No relevant klass or oop information. |
duke@435 | 2682 | const Type *TypeOopPtr::xdual() const { |
coleenp@4037 | 2683 | assert(klass() == Compile::current()->env()->Object_klass(), "no klasses here"); |
duke@435 | 2684 | assert(const_oop() == NULL, "no constants here"); |
roland@6380 | 2685 | return new TypeOopPtr(_base, dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative(), dual_inline_depth()); |
duke@435 | 2686 | } |
duke@435 | 2687 | |
duke@435 | 2688 | //--------------------------make_from_klass_common----------------------------- |
duke@435 | 2689 | // Computes the element-type given a klass. |
duke@435 | 2690 | const TypeOopPtr* TypeOopPtr::make_from_klass_common(ciKlass *klass, bool klass_change, bool try_for_exact) { |
duke@435 | 2691 | if (klass->is_instance_klass()) { |
duke@435 | 2692 | Compile* C = Compile::current(); |
duke@435 | 2693 | Dependencies* deps = C->dependencies(); |
duke@435 | 2694 | assert((deps != NULL) == (C->method() != NULL && C->method()->code_size() > 0), "sanity"); |
duke@435 | 2695 | // Element is an instance |
duke@435 | 2696 | bool klass_is_exact = false; |
duke@435 | 2697 | if (klass->is_loaded()) { |
duke@435 | 2698 | // Try to set klass_is_exact. |
duke@435 | 2699 | ciInstanceKlass* ik = klass->as_instance_klass(); |
duke@435 | 2700 | klass_is_exact = ik->is_final(); |
duke@435 | 2701 | if (!klass_is_exact && klass_change |
duke@435 | 2702 | && deps != NULL && UseUniqueSubclasses) { |
duke@435 | 2703 | ciInstanceKlass* sub = ik->unique_concrete_subklass(); |
duke@435 | 2704 | if (sub != NULL) { |
duke@435 | 2705 | deps->assert_abstract_with_unique_concrete_subtype(ik, sub); |
duke@435 | 2706 | klass = ik = sub; |
duke@435 | 2707 | klass_is_exact = sub->is_final(); |
duke@435 | 2708 | } |
duke@435 | 2709 | } |
duke@435 | 2710 | if (!klass_is_exact && try_for_exact |
duke@435 | 2711 | && deps != NULL && UseExactTypes) { |
duke@435 | 2712 | if (!ik->is_interface() && !ik->has_subklass()) { |
duke@435 | 2713 | // Add a dependence; if concrete subclass added we need to recompile |
duke@435 | 2714 | deps->assert_leaf_type(ik); |
duke@435 | 2715 | klass_is_exact = true; |
duke@435 | 2716 | } |
duke@435 | 2717 | } |
duke@435 | 2718 | } |
duke@435 | 2719 | return TypeInstPtr::make(TypePtr::BotPTR, klass, klass_is_exact, NULL, 0); |
duke@435 | 2720 | } else if (klass->is_obj_array_klass()) { |
duke@435 | 2721 | // Element is an object array. Recursively call ourself. |
duke@435 | 2722 | const TypeOopPtr *etype = TypeOopPtr::make_from_klass_common(klass->as_obj_array_klass()->element_klass(), false, try_for_exact); |
duke@435 | 2723 | bool xk = etype->klass_is_exact(); |
duke@435 | 2724 | const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS); |
duke@435 | 2725 | // We used to pass NotNull in here, asserting that the sub-arrays |
duke@435 | 2726 | // are all not-null. This is not true in generally, as code can |
duke@435 | 2727 | // slam NULLs down in the subarrays. |
duke@435 | 2728 | const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::BotPTR, arr0, klass, xk, 0); |
duke@435 | 2729 | return arr; |
duke@435 | 2730 | } else if (klass->is_type_array_klass()) { |
duke@435 | 2731 | // Element is an typeArray |
duke@435 | 2732 | const Type* etype = get_const_basic_type(klass->as_type_array_klass()->element_type()); |
duke@435 | 2733 | const TypeAry* arr0 = TypeAry::make(etype, TypeInt::POS); |
duke@435 | 2734 | // We used to pass NotNull in here, asserting that the array pointer |
duke@435 | 2735 | // is not-null. That was not true in general. |
duke@435 | 2736 | const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::BotPTR, arr0, klass, true, 0); |
duke@435 | 2737 | return arr; |
duke@435 | 2738 | } else { |
duke@435 | 2739 | ShouldNotReachHere(); |
duke@435 | 2740 | return NULL; |
duke@435 | 2741 | } |
duke@435 | 2742 | } |
duke@435 | 2743 | |
duke@435 | 2744 | //------------------------------make_from_constant----------------------------- |
duke@435 | 2745 | // Make a java pointer from an oop constant |
kvn@5110 | 2746 | const TypeOopPtr* TypeOopPtr::make_from_constant(ciObject* o, |
kvn@5110 | 2747 | bool require_constant, |
kvn@5110 | 2748 | bool is_autobox_cache) { |
kvn@5110 | 2749 | assert(!o->is_null_object(), "null object not yet handled here."); |
kvn@5110 | 2750 | ciKlass* klass = o->klass(); |
kvn@5110 | 2751 | if (klass->is_instance_klass()) { |
kvn@5110 | 2752 | // Element is an instance |
kvn@5110 | 2753 | if (require_constant) { |
kvn@5110 | 2754 | if (!o->can_be_constant()) return NULL; |
kvn@5110 | 2755 | } else if (!o->should_be_constant()) { |
kvn@5110 | 2756 | return TypeInstPtr::make(TypePtr::NotNull, klass, true, NULL, 0); |
kvn@5110 | 2757 | } |
kvn@5110 | 2758 | return TypeInstPtr::make(o); |
kvn@5110 | 2759 | } else if (klass->is_obj_array_klass()) { |
kvn@5110 | 2760 | // Element is an object array. Recursively call ourself. |
kvn@5110 | 2761 | const TypeOopPtr *etype = |
coleenp@4037 | 2762 | TypeOopPtr::make_from_klass_raw(klass->as_obj_array_klass()->element_klass()); |
kvn@5110 | 2763 | if (is_autobox_cache) { |
kvn@5110 | 2764 | // The pointers in the autobox arrays are always non-null. |
kvn@5110 | 2765 | etype = etype->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr(); |
kvn@5110 | 2766 | } |
kvn@5110 | 2767 | const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length())); |
kvn@5110 | 2768 | // We used to pass NotNull in here, asserting that the sub-arrays |
kvn@5110 | 2769 | // are all not-null. This is not true in generally, as code can |
kvn@5110 | 2770 | // slam NULLs down in the subarrays. |
kvn@5110 | 2771 | if (require_constant) { |
kvn@5110 | 2772 | if (!o->can_be_constant()) return NULL; |
kvn@5110 | 2773 | } else if (!o->should_be_constant()) { |
kvn@5110 | 2774 | return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0); |
kvn@5110 | 2775 | } |
roland@6380 | 2776 | const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0, InstanceBot, NULL, InlineDepthBottom, is_autobox_cache); |
coleenp@4037 | 2777 | return arr; |
kvn@5110 | 2778 | } else if (klass->is_type_array_klass()) { |
kvn@5110 | 2779 | // Element is an typeArray |
coleenp@4037 | 2780 | const Type* etype = |
coleenp@4037 | 2781 | (Type*)get_const_basic_type(klass->as_type_array_klass()->element_type()); |
kvn@5110 | 2782 | const TypeAry* arr0 = TypeAry::make(etype, TypeInt::make(o->as_array()->length())); |
kvn@5110 | 2783 | // We used to pass NotNull in here, asserting that the array pointer |
kvn@5110 | 2784 | // is not-null. That was not true in general. |
kvn@5110 | 2785 | if (require_constant) { |
kvn@5110 | 2786 | if (!o->can_be_constant()) return NULL; |
kvn@5110 | 2787 | } else if (!o->should_be_constant()) { |
kvn@5110 | 2788 | return TypeAryPtr::make(TypePtr::NotNull, arr0, klass, true, 0); |
kvn@5110 | 2789 | } |
coleenp@4037 | 2790 | const TypeAryPtr* arr = TypeAryPtr::make(TypePtr::Constant, o, arr0, klass, true, 0); |
coleenp@4037 | 2791 | return arr; |
duke@435 | 2792 | } |
duke@435 | 2793 | |
twisti@3885 | 2794 | fatal("unhandled object type"); |
duke@435 | 2795 | return NULL; |
duke@435 | 2796 | } |
duke@435 | 2797 | |
duke@435 | 2798 | //------------------------------get_con---------------------------------------- |
duke@435 | 2799 | intptr_t TypeOopPtr::get_con() const { |
duke@435 | 2800 | assert( _ptr == Null || _ptr == Constant, "" ); |
duke@435 | 2801 | assert( _offset >= 0, "" ); |
duke@435 | 2802 | |
duke@435 | 2803 | if (_offset != 0) { |
duke@435 | 2804 | // After being ported to the compiler interface, the compiler no longer |
duke@435 | 2805 | // directly manipulates the addresses of oops. Rather, it only has a pointer |
duke@435 | 2806 | // to a handle at compile time. This handle is embedded in the generated |
duke@435 | 2807 | // code and dereferenced at the time the nmethod is made. Until that time, |
duke@435 | 2808 | // it is not reasonable to do arithmetic with the addresses of oops (we don't |
duke@435 | 2809 | // have access to the addresses!). This does not seem to currently happen, |
twisti@1040 | 2810 | // but this assertion here is to help prevent its occurence. |
duke@435 | 2811 | tty->print_cr("Found oop constant with non-zero offset"); |
duke@435 | 2812 | ShouldNotReachHere(); |
duke@435 | 2813 | } |
duke@435 | 2814 | |
jrose@1424 | 2815 | return (intptr_t)const_oop()->constant_encoding(); |
duke@435 | 2816 | } |
duke@435 | 2817 | |
duke@435 | 2818 | |
duke@435 | 2819 | //-----------------------------filter------------------------------------------ |
duke@435 | 2820 | // Do not allow interface-vs.-noninterface joins to collapse to top. |
roland@6313 | 2821 | const Type *TypeOopPtr::filter_helper(const Type *kills, bool include_speculative) const { |
roland@6313 | 2822 | |
roland@6313 | 2823 | const Type* ft = join_helper(kills, include_speculative); |
duke@435 | 2824 | const TypeInstPtr* ftip = ft->isa_instptr(); |
duke@435 | 2825 | const TypeInstPtr* ktip = kills->isa_instptr(); |
duke@435 | 2826 | |
duke@435 | 2827 | if (ft->empty()) { |
duke@435 | 2828 | // Check for evil case of 'this' being a class and 'kills' expecting an |
duke@435 | 2829 | // interface. This can happen because the bytecodes do not contain |
duke@435 | 2830 | // enough type info to distinguish a Java-level interface variable |
duke@435 | 2831 | // from a Java-level object variable. If we meet 2 classes which |
duke@435 | 2832 | // both implement interface I, but their meet is at 'j/l/O' which |
duke@435 | 2833 | // doesn't implement I, we have no way to tell if the result should |
duke@435 | 2834 | // be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows |
duke@435 | 2835 | // into a Phi which "knows" it's an Interface type we'll have to |
duke@435 | 2836 | // uplift the type. |
duke@435 | 2837 | if (!empty() && ktip != NULL && ktip->is_loaded() && ktip->klass()->is_interface()) |
duke@435 | 2838 | return kills; // Uplift to interface |
duke@435 | 2839 | |
duke@435 | 2840 | return Type::TOP; // Canonical empty value |
duke@435 | 2841 | } |
duke@435 | 2842 | |
duke@435 | 2843 | // If we have an interface-typed Phi or cast and we narrow to a class type, |
duke@435 | 2844 | // the join should report back the class. However, if we have a J/L/Object |
duke@435 | 2845 | // class-typed Phi and an interface flows in, it's possible that the meet & |
duke@435 | 2846 | // join report an interface back out. This isn't possible but happens |
duke@435 | 2847 | // because the type system doesn't interact well with interfaces. |
duke@435 | 2848 | if (ftip != NULL && ktip != NULL && |
duke@435 | 2849 | ftip->is_loaded() && ftip->klass()->is_interface() && |
duke@435 | 2850 | ktip->is_loaded() && !ktip->klass()->is_interface()) { |
duke@435 | 2851 | // Happens in a CTW of rt.jar, 320-341, no extra flags |
kvn@1770 | 2852 | assert(!ftip->klass_is_exact(), "interface could not be exact"); |
duke@435 | 2853 | return ktip->cast_to_ptr_type(ftip->ptr()); |
duke@435 | 2854 | } |
duke@435 | 2855 | |
duke@435 | 2856 | return ft; |
duke@435 | 2857 | } |
duke@435 | 2858 | |
duke@435 | 2859 | //------------------------------eq--------------------------------------------- |
duke@435 | 2860 | // Structural equality check for Type representations |
duke@435 | 2861 | bool TypeOopPtr::eq( const Type *t ) const { |
duke@435 | 2862 | const TypeOopPtr *a = (const TypeOopPtr*)t; |
duke@435 | 2863 | if (_klass_is_exact != a->_klass_is_exact || |
roland@5991 | 2864 | _instance_id != a->_instance_id || |
roland@6380 | 2865 | !eq_speculative(a) || |
roland@6380 | 2866 | _inline_depth != a->_inline_depth) return false; |
duke@435 | 2867 | ciObject* one = const_oop(); |
duke@435 | 2868 | ciObject* two = a->const_oop(); |
duke@435 | 2869 | if (one == NULL || two == NULL) { |
duke@435 | 2870 | return (one == two) && TypePtr::eq(t); |
duke@435 | 2871 | } else { |
duke@435 | 2872 | return one->equals(two) && TypePtr::eq(t); |
duke@435 | 2873 | } |
duke@435 | 2874 | } |
duke@435 | 2875 | |
duke@435 | 2876 | //------------------------------hash------------------------------------------- |
duke@435 | 2877 | // Type-specific hashing function. |
duke@435 | 2878 | int TypeOopPtr::hash(void) const { |
duke@435 | 2879 | return |
duke@435 | 2880 | (const_oop() ? const_oop()->hash() : 0) + |
duke@435 | 2881 | _klass_is_exact + |
duke@435 | 2882 | _instance_id + |
roland@5991 | 2883 | hash_speculative() + |
roland@6380 | 2884 | _inline_depth + |
duke@435 | 2885 | TypePtr::hash(); |
duke@435 | 2886 | } |
duke@435 | 2887 | |
duke@435 | 2888 | //------------------------------dump2------------------------------------------ |
duke@435 | 2889 | #ifndef PRODUCT |
duke@435 | 2890 | void TypeOopPtr::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 2891 | st->print("oopptr:%s", ptr_msg[_ptr]); |
duke@435 | 2892 | if( _klass_is_exact ) st->print(":exact"); |
duke@435 | 2893 | if( const_oop() ) st->print(INTPTR_FORMAT, const_oop()); |
duke@435 | 2894 | switch( _offset ) { |
duke@435 | 2895 | case OffsetTop: st->print("+top"); break; |
duke@435 | 2896 | case OffsetBot: st->print("+any"); break; |
duke@435 | 2897 | case 0: break; |
duke@435 | 2898 | default: st->print("+%d",_offset); break; |
duke@435 | 2899 | } |
kvn@658 | 2900 | if (_instance_id == InstanceTop) |
kvn@658 | 2901 | st->print(",iid=top"); |
kvn@658 | 2902 | else if (_instance_id != InstanceBot) |
duke@435 | 2903 | st->print(",iid=%d",_instance_id); |
roland@5991 | 2904 | |
roland@6380 | 2905 | dump_inline_depth(st); |
roland@5991 | 2906 | dump_speculative(st); |
roland@5991 | 2907 | } |
roland@5991 | 2908 | |
roland@5991 | 2909 | /** |
roland@5991 | 2910 | *dump the speculative part of the type |
roland@5991 | 2911 | */ |
roland@5991 | 2912 | void TypeOopPtr::dump_speculative(outputStream *st) const { |
roland@5991 | 2913 | if (_speculative != NULL) { |
roland@5991 | 2914 | st->print(" (speculative="); |
roland@5991 | 2915 | _speculative->dump_on(st); |
roland@5991 | 2916 | st->print(")"); |
roland@5991 | 2917 | } |
duke@435 | 2918 | } |
roland@6380 | 2919 | |
roland@6380 | 2920 | void TypeOopPtr::dump_inline_depth(outputStream *st) const { |
roland@6380 | 2921 | if (_inline_depth != InlineDepthBottom) { |
roland@6380 | 2922 | if (_inline_depth == InlineDepthTop) { |
roland@6380 | 2923 | st->print(" (inline_depth=InlineDepthTop)"); |
roland@6380 | 2924 | } else { |
roland@6380 | 2925 | st->print(" (inline_depth=%d)", _inline_depth); |
roland@6380 | 2926 | } |
roland@6380 | 2927 | } |
roland@6380 | 2928 | } |
duke@435 | 2929 | #endif |
duke@435 | 2930 | |
duke@435 | 2931 | //------------------------------singleton-------------------------------------- |
duke@435 | 2932 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 2933 | // constants |
duke@435 | 2934 | bool TypeOopPtr::singleton(void) const { |
duke@435 | 2935 | // detune optimizer to not generate constant oop + constant offset as a constant! |
duke@435 | 2936 | // TopPTR, Null, AnyNull, Constant are all singletons |
duke@435 | 2937 | return (_offset == 0) && !below_centerline(_ptr); |
duke@435 | 2938 | } |
duke@435 | 2939 | |
duke@435 | 2940 | //------------------------------add_offset------------------------------------- |
roland@5991 | 2941 | const TypePtr *TypeOopPtr::add_offset(intptr_t offset) const { |
roland@6380 | 2942 | return make(_ptr, xadd_offset(offset), _instance_id, add_offset_speculative(offset), _inline_depth); |
roland@5991 | 2943 | } |
roland@5991 | 2944 | |
roland@5991 | 2945 | /** |
roland@5991 | 2946 | * Return same type without a speculative part |
roland@5991 | 2947 | */ |
roland@6313 | 2948 | const Type* TypeOopPtr::remove_speculative() const { |
roland@6313 | 2949 | if (_speculative == NULL) { |
roland@6313 | 2950 | return this; |
roland@6313 | 2951 | } |
roland@6380 | 2952 | assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth"); |
roland@6380 | 2953 | return make(_ptr, _offset, _instance_id, NULL, _inline_depth); |
roland@6380 | 2954 | } |
roland@6380 | 2955 | |
roland@6380 | 2956 | /** |
roland@6380 | 2957 | * Return same type but with a different inline depth (used for speculation) |
roland@6380 | 2958 | * |
roland@6380 | 2959 | * @param depth depth to meet with |
roland@6380 | 2960 | */ |
roland@6380 | 2961 | const TypeOopPtr* TypeOopPtr::with_inline_depth(int depth) const { |
roland@6380 | 2962 | if (!UseInlineDepthForSpeculativeTypes) { |
roland@6380 | 2963 | return this; |
roland@6380 | 2964 | } |
roland@6380 | 2965 | return make(_ptr, _offset, _instance_id, _speculative, depth); |
roland@6380 | 2966 | } |
roland@6380 | 2967 | |
roland@6380 | 2968 | /** |
roland@6380 | 2969 | * Check whether new profiling would improve speculative type |
roland@6380 | 2970 | * |
roland@6380 | 2971 | * @param exact_kls class from profiling |
roland@6380 | 2972 | * @param inline_depth inlining depth of profile point |
roland@6380 | 2973 | * |
roland@6380 | 2974 | * @return true if type profile is valuable |
roland@6380 | 2975 | */ |
roland@6380 | 2976 | bool TypeOopPtr::would_improve_type(ciKlass* exact_kls, int inline_depth) const { |
roland@6380 | 2977 | // no way to improve an already exact type |
roland@6380 | 2978 | if (klass_is_exact()) { |
roland@6380 | 2979 | return false; |
roland@6380 | 2980 | } |
roland@6380 | 2981 | // no profiling? |
roland@6380 | 2982 | if (exact_kls == NULL) { |
roland@6380 | 2983 | return false; |
roland@6380 | 2984 | } |
roland@6380 | 2985 | // no speculative type or non exact speculative type? |
roland@6380 | 2986 | if (speculative_type() == NULL) { |
roland@6380 | 2987 | return true; |
roland@6380 | 2988 | } |
roland@6380 | 2989 | // If the node already has an exact speculative type keep it, |
roland@6380 | 2990 | // unless it was provided by profiling that is at a deeper |
roland@6380 | 2991 | // inlining level. Profiling at a higher inlining depth is |
roland@6380 | 2992 | // expected to be less accurate. |
roland@6380 | 2993 | if (_speculative->inline_depth() == InlineDepthBottom) { |
roland@6380 | 2994 | return false; |
roland@6380 | 2995 | } |
roland@6380 | 2996 | assert(_speculative->inline_depth() != InlineDepthTop, "can't do the comparison"); |
roland@6380 | 2997 | return inline_depth < _speculative->inline_depth(); |
duke@435 | 2998 | } |
duke@435 | 2999 | |
kvn@658 | 3000 | //------------------------------meet_instance_id-------------------------------- |
kvn@658 | 3001 | int TypeOopPtr::meet_instance_id( int instance_id ) const { |
kvn@658 | 3002 | // Either is 'TOP' instance? Return the other instance! |
kvn@658 | 3003 | if( _instance_id == InstanceTop ) return instance_id; |
kvn@658 | 3004 | if( instance_id == InstanceTop ) return _instance_id; |
kvn@658 | 3005 | // If either is different, return 'BOTTOM' instance |
kvn@658 | 3006 | if( _instance_id != instance_id ) return InstanceBot; |
kvn@658 | 3007 | return _instance_id; |
duke@435 | 3008 | } |
duke@435 | 3009 | |
kvn@658 | 3010 | //------------------------------dual_instance_id-------------------------------- |
kvn@658 | 3011 | int TypeOopPtr::dual_instance_id( ) const { |
kvn@658 | 3012 | if( _instance_id == InstanceTop ) return InstanceBot; // Map TOP into BOTTOM |
kvn@658 | 3013 | if( _instance_id == InstanceBot ) return InstanceTop; // Map BOTTOM into TOP |
kvn@658 | 3014 | return _instance_id; // Map everything else into self |
kvn@658 | 3015 | } |
kvn@658 | 3016 | |
roland@5991 | 3017 | /** |
roland@5991 | 3018 | * meet of the speculative parts of 2 types |
roland@5991 | 3019 | * |
roland@5991 | 3020 | * @param other type to meet with |
roland@5991 | 3021 | */ |
roland@6313 | 3022 | const TypeOopPtr* TypeOopPtr::xmeet_speculative(const TypeOopPtr* other) const { |
roland@5991 | 3023 | bool this_has_spec = (_speculative != NULL); |
roland@5991 | 3024 | bool other_has_spec = (other->speculative() != NULL); |
roland@5991 | 3025 | |
roland@5991 | 3026 | if (!this_has_spec && !other_has_spec) { |
roland@5991 | 3027 | return NULL; |
roland@5991 | 3028 | } |
roland@5991 | 3029 | |
roland@5991 | 3030 | // If we are at a point where control flow meets and one branch has |
roland@5991 | 3031 | // a speculative type and the other has not, we meet the speculative |
roland@5991 | 3032 | // type of one branch with the actual type of the other. If the |
roland@5991 | 3033 | // actual type is exact and the speculative is as well, then the |
roland@5991 | 3034 | // result is a speculative type which is exact and we can continue |
roland@5991 | 3035 | // speculation further. |
roland@5991 | 3036 | const TypeOopPtr* this_spec = _speculative; |
roland@5991 | 3037 | const TypeOopPtr* other_spec = other->speculative(); |
roland@5991 | 3038 | |
roland@5991 | 3039 | if (!this_has_spec) { |
roland@5991 | 3040 | this_spec = this; |
roland@5991 | 3041 | } |
roland@5991 | 3042 | |
roland@5991 | 3043 | if (!other_has_spec) { |
roland@5991 | 3044 | other_spec = other; |
roland@5991 | 3045 | } |
roland@5991 | 3046 | |
roland@6313 | 3047 | return this_spec->meet_speculative(other_spec)->is_oopptr(); |
roland@5991 | 3048 | } |
roland@5991 | 3049 | |
roland@5991 | 3050 | /** |
roland@5991 | 3051 | * dual of the speculative part of the type |
roland@5991 | 3052 | */ |
roland@5991 | 3053 | const TypeOopPtr* TypeOopPtr::dual_speculative() const { |
roland@5991 | 3054 | if (_speculative == NULL) { |
roland@5991 | 3055 | return NULL; |
roland@5991 | 3056 | } |
roland@5991 | 3057 | return _speculative->dual()->is_oopptr(); |
roland@5991 | 3058 | } |
roland@5991 | 3059 | |
roland@5991 | 3060 | /** |
roland@5991 | 3061 | * add offset to the speculative part of the type |
roland@5991 | 3062 | * |
roland@5991 | 3063 | * @param offset offset to add |
roland@5991 | 3064 | */ |
roland@5991 | 3065 | const TypeOopPtr* TypeOopPtr::add_offset_speculative(intptr_t offset) const { |
roland@5991 | 3066 | if (_speculative == NULL) { |
roland@5991 | 3067 | return NULL; |
roland@5991 | 3068 | } |
roland@5991 | 3069 | return _speculative->add_offset(offset)->is_oopptr(); |
roland@5991 | 3070 | } |
roland@5991 | 3071 | |
roland@5991 | 3072 | /** |
roland@5991 | 3073 | * Are the speculative parts of 2 types equal? |
roland@5991 | 3074 | * |
roland@5991 | 3075 | * @param other type to compare this one to |
roland@5991 | 3076 | */ |
roland@5991 | 3077 | bool TypeOopPtr::eq_speculative(const TypeOopPtr* other) const { |
roland@5991 | 3078 | if (_speculative == NULL || other->speculative() == NULL) { |
roland@5991 | 3079 | return _speculative == other->speculative(); |
roland@5991 | 3080 | } |
roland@5991 | 3081 | |
roland@5991 | 3082 | if (_speculative->base() != other->speculative()->base()) { |
roland@5991 | 3083 | return false; |
roland@5991 | 3084 | } |
roland@5991 | 3085 | |
roland@5991 | 3086 | return _speculative->eq(other->speculative()); |
roland@5991 | 3087 | } |
roland@5991 | 3088 | |
roland@5991 | 3089 | /** |
roland@5991 | 3090 | * Hash of the speculative part of the type |
roland@5991 | 3091 | */ |
roland@5991 | 3092 | int TypeOopPtr::hash_speculative() const { |
roland@5991 | 3093 | if (_speculative == NULL) { |
roland@5991 | 3094 | return 0; |
roland@5991 | 3095 | } |
roland@5991 | 3096 | |
roland@5991 | 3097 | return _speculative->hash(); |
roland@5991 | 3098 | } |
roland@5991 | 3099 | |
roland@6380 | 3100 | /** |
roland@6380 | 3101 | * dual of the inline depth for this type (used for speculation) |
roland@6380 | 3102 | */ |
roland@6380 | 3103 | int TypeOopPtr::dual_inline_depth() const { |
roland@6380 | 3104 | return -inline_depth(); |
roland@6380 | 3105 | } |
roland@6380 | 3106 | |
roland@6380 | 3107 | /** |
roland@6380 | 3108 | * meet of 2 inline depth (used for speculation) |
roland@6380 | 3109 | * |
roland@6380 | 3110 | * @param depth depth to meet with |
roland@6380 | 3111 | */ |
roland@6380 | 3112 | int TypeOopPtr::meet_inline_depth(int depth) const { |
roland@6380 | 3113 | return MAX2(inline_depth(), depth); |
roland@6380 | 3114 | } |
kvn@658 | 3115 | |
duke@435 | 3116 | //============================================================================= |
duke@435 | 3117 | // Convenience common pre-built types. |
duke@435 | 3118 | const TypeInstPtr *TypeInstPtr::NOTNULL; |
duke@435 | 3119 | const TypeInstPtr *TypeInstPtr::BOTTOM; |
duke@435 | 3120 | const TypeInstPtr *TypeInstPtr::MIRROR; |
duke@435 | 3121 | const TypeInstPtr *TypeInstPtr::MARK; |
duke@435 | 3122 | const TypeInstPtr *TypeInstPtr::KLASS; |
duke@435 | 3123 | |
duke@435 | 3124 | //------------------------------TypeInstPtr------------------------------------- |
roland@6380 | 3125 | TypeInstPtr::TypeInstPtr(PTR ptr, ciKlass* k, bool xk, ciObject* o, int off, int instance_id, const TypeOopPtr* speculative, int inline_depth) |
roland@6380 | 3126 | : TypeOopPtr(InstPtr, ptr, k, xk, o, off, instance_id, speculative, inline_depth), _name(k->name()) { |
duke@435 | 3127 | assert(k != NULL && |
duke@435 | 3128 | (k->is_loaded() || o == NULL), |
duke@435 | 3129 | "cannot have constants with non-loaded klass"); |
duke@435 | 3130 | }; |
duke@435 | 3131 | |
duke@435 | 3132 | //------------------------------make------------------------------------------- |
duke@435 | 3133 | const TypeInstPtr *TypeInstPtr::make(PTR ptr, |
duke@435 | 3134 | ciKlass* k, |
duke@435 | 3135 | bool xk, |
duke@435 | 3136 | ciObject* o, |
duke@435 | 3137 | int offset, |
roland@5991 | 3138 | int instance_id, |
roland@6380 | 3139 | const TypeOopPtr* speculative, |
roland@6380 | 3140 | int inline_depth) { |
coleenp@4037 | 3141 | assert( !k->is_loaded() || k->is_instance_klass(), "Must be for instance"); |
duke@435 | 3142 | // Either const_oop() is NULL or else ptr is Constant |
duke@435 | 3143 | assert( (!o && ptr != Constant) || (o && ptr == Constant), |
duke@435 | 3144 | "constant pointers must have a value supplied" ); |
duke@435 | 3145 | // Ptr is never Null |
duke@435 | 3146 | assert( ptr != Null, "NULL pointers are not typed" ); |
duke@435 | 3147 | |
kvn@682 | 3148 | assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); |
duke@435 | 3149 | if (!UseExactTypes) xk = false; |
duke@435 | 3150 | if (ptr == Constant) { |
duke@435 | 3151 | // Note: This case includes meta-object constants, such as methods. |
duke@435 | 3152 | xk = true; |
duke@435 | 3153 | } else if (k->is_loaded()) { |
duke@435 | 3154 | ciInstanceKlass* ik = k->as_instance_klass(); |
duke@435 | 3155 | if (!xk && ik->is_final()) xk = true; // no inexact final klass |
duke@435 | 3156 | if (xk && ik->is_interface()) xk = false; // no exact interface |
duke@435 | 3157 | } |
duke@435 | 3158 | |
duke@435 | 3159 | // Now hash this baby |
duke@435 | 3160 | TypeInstPtr *result = |
roland@6380 | 3161 | (TypeInstPtr*)(new TypeInstPtr(ptr, k, xk, o ,offset, instance_id, speculative, inline_depth))->hashcons(); |
duke@435 | 3162 | |
duke@435 | 3163 | return result; |
duke@435 | 3164 | } |
duke@435 | 3165 | |
kvn@5110 | 3166 | /** |
kvn@5110 | 3167 | * Create constant type for a constant boxed value |
kvn@5110 | 3168 | */ |
kvn@5110 | 3169 | const Type* TypeInstPtr::get_const_boxed_value() const { |
kvn@5110 | 3170 | assert(is_ptr_to_boxed_value(), "should be called only for boxed value"); |
kvn@5110 | 3171 | assert((const_oop() != NULL), "should be called only for constant object"); |
kvn@5110 | 3172 | ciConstant constant = const_oop()->as_instance()->field_value_by_offset(offset()); |
kvn@5110 | 3173 | BasicType bt = constant.basic_type(); |
kvn@5110 | 3174 | switch (bt) { |
kvn@5110 | 3175 | case T_BOOLEAN: return TypeInt::make(constant.as_boolean()); |
kvn@5110 | 3176 | case T_INT: return TypeInt::make(constant.as_int()); |
kvn@5110 | 3177 | case T_CHAR: return TypeInt::make(constant.as_char()); |
kvn@5110 | 3178 | case T_BYTE: return TypeInt::make(constant.as_byte()); |
kvn@5110 | 3179 | case T_SHORT: return TypeInt::make(constant.as_short()); |
kvn@5110 | 3180 | case T_FLOAT: return TypeF::make(constant.as_float()); |
kvn@5110 | 3181 | case T_DOUBLE: return TypeD::make(constant.as_double()); |
kvn@5110 | 3182 | case T_LONG: return TypeLong::make(constant.as_long()); |
kvn@5110 | 3183 | default: break; |
kvn@5110 | 3184 | } |
kvn@5110 | 3185 | fatal(err_msg_res("Invalid boxed value type '%s'", type2name(bt))); |
kvn@5110 | 3186 | return NULL; |
kvn@5110 | 3187 | } |
duke@435 | 3188 | |
duke@435 | 3189 | //------------------------------cast_to_ptr_type------------------------------- |
duke@435 | 3190 | const Type *TypeInstPtr::cast_to_ptr_type(PTR ptr) const { |
duke@435 | 3191 | if( ptr == _ptr ) return this; |
duke@435 | 3192 | // Reconstruct _sig info here since not a problem with later lazy |
duke@435 | 3193 | // construction, _sig will show up on demand. |
roland@6380 | 3194 | return make(ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative, _inline_depth); |
duke@435 | 3195 | } |
duke@435 | 3196 | |
duke@435 | 3197 | |
duke@435 | 3198 | //-----------------------------cast_to_exactness------------------------------- |
duke@435 | 3199 | const Type *TypeInstPtr::cast_to_exactness(bool klass_is_exact) const { |
duke@435 | 3200 | if( klass_is_exact == _klass_is_exact ) return this; |
duke@435 | 3201 | if (!UseExactTypes) return this; |
duke@435 | 3202 | if (!_klass->is_loaded()) return this; |
duke@435 | 3203 | ciInstanceKlass* ik = _klass->as_instance_klass(); |
duke@435 | 3204 | if( (ik->is_final() || _const_oop) ) return this; // cannot clear xk |
duke@435 | 3205 | if( ik->is_interface() ) return this; // cannot set xk |
roland@6380 | 3206 | return make(ptr(), klass(), klass_is_exact, const_oop(), _offset, _instance_id, _speculative, _inline_depth); |
duke@435 | 3207 | } |
duke@435 | 3208 | |
kvn@682 | 3209 | //-----------------------------cast_to_instance_id---------------------------- |
kvn@658 | 3210 | const TypeOopPtr *TypeInstPtr::cast_to_instance_id(int instance_id) const { |
kvn@658 | 3211 | if( instance_id == _instance_id ) return this; |
roland@6380 | 3212 | return make(_ptr, klass(), _klass_is_exact, const_oop(), _offset, instance_id, _speculative, _inline_depth); |
duke@435 | 3213 | } |
duke@435 | 3214 | |
duke@435 | 3215 | //------------------------------xmeet_unloaded--------------------------------- |
duke@435 | 3216 | // Compute the MEET of two InstPtrs when at least one is unloaded. |
duke@435 | 3217 | // Assume classes are different since called after check for same name/class-loader |
duke@435 | 3218 | const TypeInstPtr *TypeInstPtr::xmeet_unloaded(const TypeInstPtr *tinst) const { |
duke@435 | 3219 | int off = meet_offset(tinst->offset()); |
duke@435 | 3220 | PTR ptr = meet_ptr(tinst->ptr()); |
kvn@1427 | 3221 | int instance_id = meet_instance_id(tinst->instance_id()); |
roland@6313 | 3222 | const TypeOopPtr* speculative = xmeet_speculative(tinst); |
roland@6380 | 3223 | int depth = meet_inline_depth(tinst->inline_depth()); |
duke@435 | 3224 | |
duke@435 | 3225 | const TypeInstPtr *loaded = is_loaded() ? this : tinst; |
duke@435 | 3226 | const TypeInstPtr *unloaded = is_loaded() ? tinst : this; |
duke@435 | 3227 | if( loaded->klass()->equals(ciEnv::current()->Object_klass()) ) { |
duke@435 | 3228 | // |
duke@435 | 3229 | // Meet unloaded class with java/lang/Object |
duke@435 | 3230 | // |
duke@435 | 3231 | // Meet |
duke@435 | 3232 | // | Unloaded Class |
duke@435 | 3233 | // Object | TOP | AnyNull | Constant | NotNull | BOTTOM | |
duke@435 | 3234 | // =================================================================== |
duke@435 | 3235 | // TOP | ..........................Unloaded......................| |
duke@435 | 3236 | // AnyNull | U-AN |................Unloaded......................| |
duke@435 | 3237 | // Constant | ... O-NN .................................. | O-BOT | |
duke@435 | 3238 | // NotNull | ... O-NN .................................. | O-BOT | |
duke@435 | 3239 | // BOTTOM | ........................Object-BOTTOM ..................| |
duke@435 | 3240 | // |
duke@435 | 3241 | assert(loaded->ptr() != TypePtr::Null, "insanity check"); |
duke@435 | 3242 | // |
duke@435 | 3243 | if( loaded->ptr() == TypePtr::TopPTR ) { return unloaded; } |
roland@6380 | 3244 | else if (loaded->ptr() == TypePtr::AnyNull) { return TypeInstPtr::make(ptr, unloaded->klass(), false, NULL, off, instance_id, speculative, depth); } |
duke@435 | 3245 | else if (loaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; } |
duke@435 | 3246 | else if (loaded->ptr() == TypePtr::Constant || loaded->ptr() == TypePtr::NotNull) { |
duke@435 | 3247 | if (unloaded->ptr() == TypePtr::BotPTR ) { return TypeInstPtr::BOTTOM; } |
duke@435 | 3248 | else { return TypeInstPtr::NOTNULL; } |
duke@435 | 3249 | } |
duke@435 | 3250 | else if( unloaded->ptr() == TypePtr::TopPTR ) { return unloaded; } |
duke@435 | 3251 | |
duke@435 | 3252 | return unloaded->cast_to_ptr_type(TypePtr::AnyNull)->is_instptr(); |
duke@435 | 3253 | } |
duke@435 | 3254 | |
duke@435 | 3255 | // Both are unloaded, not the same class, not Object |
duke@435 | 3256 | // Or meet unloaded with a different loaded class, not java/lang/Object |
duke@435 | 3257 | if( ptr != TypePtr::BotPTR ) { |
duke@435 | 3258 | return TypeInstPtr::NOTNULL; |
duke@435 | 3259 | } |
duke@435 | 3260 | return TypeInstPtr::BOTTOM; |
duke@435 | 3261 | } |
duke@435 | 3262 | |
duke@435 | 3263 | |
duke@435 | 3264 | //------------------------------meet------------------------------------------- |
duke@435 | 3265 | // Compute the MEET of two types. It returns a new Type object. |
roland@5991 | 3266 | const Type *TypeInstPtr::xmeet_helper(const Type *t) const { |
duke@435 | 3267 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 3268 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 3269 | |
duke@435 | 3270 | // Current "this->_base" is Pointer |
duke@435 | 3271 | switch (t->base()) { // switch on original type |
duke@435 | 3272 | |
duke@435 | 3273 | case Int: // Mixing ints & oops happens when javac |
duke@435 | 3274 | case Long: // reuses local variables |
duke@435 | 3275 | case FloatTop: |
duke@435 | 3276 | case FloatCon: |
duke@435 | 3277 | case FloatBot: |
duke@435 | 3278 | case DoubleTop: |
duke@435 | 3279 | case DoubleCon: |
duke@435 | 3280 | case DoubleBot: |
coleenp@548 | 3281 | case NarrowOop: |
roland@4159 | 3282 | case NarrowKlass: |
duke@435 | 3283 | case Bottom: // Ye Olde Default |
duke@435 | 3284 | return Type::BOTTOM; |
duke@435 | 3285 | case Top: |
duke@435 | 3286 | return this; |
duke@435 | 3287 | |
duke@435 | 3288 | default: // All else is a mistake |
duke@435 | 3289 | typerr(t); |
duke@435 | 3290 | |
coleenp@4037 | 3291 | case MetadataPtr: |
coleenp@4037 | 3292 | case KlassPtr: |
duke@435 | 3293 | case RawPtr: return TypePtr::BOTTOM; |
duke@435 | 3294 | |
duke@435 | 3295 | case AryPtr: { // All arrays inherit from Object class |
duke@435 | 3296 | const TypeAryPtr *tp = t->is_aryptr(); |
duke@435 | 3297 | int offset = meet_offset(tp->offset()); |
duke@435 | 3298 | PTR ptr = meet_ptr(tp->ptr()); |
kvn@658 | 3299 | int instance_id = meet_instance_id(tp->instance_id()); |
roland@6313 | 3300 | const TypeOopPtr* speculative = xmeet_speculative(tp); |
roland@6380 | 3301 | int depth = meet_inline_depth(tp->inline_depth()); |
duke@435 | 3302 | switch (ptr) { |
duke@435 | 3303 | case TopPTR: |
duke@435 | 3304 | case AnyNull: // Fall 'down' to dual of object klass |
roland@5991 | 3305 | // For instances when a subclass meets a superclass we fall |
roland@5991 | 3306 | // below the centerline when the superclass is exact. We need to |
roland@5991 | 3307 | // do the same here. |
roland@5991 | 3308 | if (klass()->equals(ciEnv::current()->Object_klass()) && !klass_is_exact()) { |
roland@6380 | 3309 | return TypeAryPtr::make(ptr, tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative, depth); |
duke@435 | 3310 | } else { |
duke@435 | 3311 | // cannot subclass, so the meet has to fall badly below the centerline |
duke@435 | 3312 | ptr = NotNull; |
kvn@658 | 3313 | instance_id = InstanceBot; |
roland@6380 | 3314 | return TypeInstPtr::make( ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative, depth); |
duke@435 | 3315 | } |
duke@435 | 3316 | case Constant: |
duke@435 | 3317 | case NotNull: |
duke@435 | 3318 | case BotPTR: // Fall down to object klass |
duke@435 | 3319 | // LCA is object_klass, but if we subclass from the top we can do better |
duke@435 | 3320 | if( above_centerline(_ptr) ) { // if( _ptr == TopPTR || _ptr == AnyNull ) |
duke@435 | 3321 | // If 'this' (InstPtr) is above the centerline and it is Object class |
twisti@1040 | 3322 | // then we can subclass in the Java class hierarchy. |
roland@5991 | 3323 | // For instances when a subclass meets a superclass we fall |
roland@5991 | 3324 | // below the centerline when the superclass is exact. We need |
roland@5991 | 3325 | // to do the same here. |
roland@5991 | 3326 | if (klass()->equals(ciEnv::current()->Object_klass()) && !klass_is_exact()) { |
duke@435 | 3327 | // that is, tp's array type is a subtype of my klass |
kvn@1714 | 3328 | return TypeAryPtr::make(ptr, (ptr == Constant ? tp->const_oop() : NULL), |
roland@6380 | 3329 | tp->ary(), tp->klass(), tp->klass_is_exact(), offset, instance_id, speculative, depth); |
duke@435 | 3330 | } |
duke@435 | 3331 | } |
duke@435 | 3332 | // The other case cannot happen, since I cannot be a subtype of an array. |
duke@435 | 3333 | // The meet falls down to Object class below centerline. |
duke@435 | 3334 | if( ptr == Constant ) |
duke@435 | 3335 | ptr = NotNull; |
kvn@658 | 3336 | instance_id = InstanceBot; |
roland@6380 | 3337 | return make(ptr, ciEnv::current()->Object_klass(), false, NULL, offset, instance_id, speculative, depth); |
duke@435 | 3338 | default: typerr(t); |
duke@435 | 3339 | } |
duke@435 | 3340 | } |
duke@435 | 3341 | |
duke@435 | 3342 | case OopPtr: { // Meeting to OopPtrs |
duke@435 | 3343 | // Found a OopPtr type vs self-InstPtr type |
kvn@1393 | 3344 | const TypeOopPtr *tp = t->is_oopptr(); |
duke@435 | 3345 | int offset = meet_offset(tp->offset()); |
duke@435 | 3346 | PTR ptr = meet_ptr(tp->ptr()); |
duke@435 | 3347 | switch (tp->ptr()) { |
duke@435 | 3348 | case TopPTR: |
kvn@658 | 3349 | case AnyNull: { |
kvn@658 | 3350 | int instance_id = meet_instance_id(InstanceTop); |
roland@6313 | 3351 | const TypeOopPtr* speculative = xmeet_speculative(tp); |
roland@6380 | 3352 | int depth = meet_inline_depth(tp->inline_depth()); |
duke@435 | 3353 | return make(ptr, klass(), klass_is_exact(), |
roland@6380 | 3354 | (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, depth); |
kvn@658 | 3355 | } |
duke@435 | 3356 | case NotNull: |
kvn@1393 | 3357 | case BotPTR: { |
kvn@1393 | 3358 | int instance_id = meet_instance_id(tp->instance_id()); |
roland@6313 | 3359 | const TypeOopPtr* speculative = xmeet_speculative(tp); |
roland@6380 | 3360 | int depth = meet_inline_depth(tp->inline_depth()); |
roland@6380 | 3361 | return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth); |
kvn@1393 | 3362 | } |
duke@435 | 3363 | default: typerr(t); |
duke@435 | 3364 | } |
duke@435 | 3365 | } |
duke@435 | 3366 | |
duke@435 | 3367 | case AnyPtr: { // Meeting to AnyPtrs |
duke@435 | 3368 | // Found an AnyPtr type vs self-InstPtr type |
duke@435 | 3369 | const TypePtr *tp = t->is_ptr(); |
duke@435 | 3370 | int offset = meet_offset(tp->offset()); |
duke@435 | 3371 | PTR ptr = meet_ptr(tp->ptr()); |
duke@435 | 3372 | switch (tp->ptr()) { |
duke@435 | 3373 | case Null: |
roland@5991 | 3374 | if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset); |
kvn@658 | 3375 | // else fall through to AnyNull |
duke@435 | 3376 | case TopPTR: |
kvn@658 | 3377 | case AnyNull: { |
kvn@658 | 3378 | int instance_id = meet_instance_id(InstanceTop); |
roland@5991 | 3379 | const TypeOopPtr* speculative = _speculative; |
roland@5991 | 3380 | return make(ptr, klass(), klass_is_exact(), |
roland@6380 | 3381 | (ptr == Constant ? const_oop() : NULL), offset, instance_id, speculative, _inline_depth); |
kvn@658 | 3382 | } |
duke@435 | 3383 | case NotNull: |
duke@435 | 3384 | case BotPTR: |
roland@5991 | 3385 | return TypePtr::make(AnyPtr, ptr, offset); |
duke@435 | 3386 | default: typerr(t); |
duke@435 | 3387 | } |
duke@435 | 3388 | } |
duke@435 | 3389 | |
duke@435 | 3390 | /* |
duke@435 | 3391 | A-top } |
duke@435 | 3392 | / | \ } Tops |
duke@435 | 3393 | B-top A-any C-top } |
duke@435 | 3394 | | / | \ | } Any-nulls |
duke@435 | 3395 | B-any | C-any } |
duke@435 | 3396 | | | | |
duke@435 | 3397 | B-con A-con C-con } constants; not comparable across classes |
duke@435 | 3398 | | | | |
duke@435 | 3399 | B-not | C-not } |
duke@435 | 3400 | | \ | / | } not-nulls |
duke@435 | 3401 | B-bot A-not C-bot } |
duke@435 | 3402 | \ | / } Bottoms |
duke@435 | 3403 | A-bot } |
duke@435 | 3404 | */ |
duke@435 | 3405 | |
duke@435 | 3406 | case InstPtr: { // Meeting 2 Oops? |
duke@435 | 3407 | // Found an InstPtr sub-type vs self-InstPtr type |
duke@435 | 3408 | const TypeInstPtr *tinst = t->is_instptr(); |
duke@435 | 3409 | int off = meet_offset( tinst->offset() ); |
duke@435 | 3410 | PTR ptr = meet_ptr( tinst->ptr() ); |
kvn@658 | 3411 | int instance_id = meet_instance_id(tinst->instance_id()); |
roland@6313 | 3412 | const TypeOopPtr* speculative = xmeet_speculative(tinst); |
roland@6380 | 3413 | int depth = meet_inline_depth(tinst->inline_depth()); |
duke@435 | 3414 | |
duke@435 | 3415 | // Check for easy case; klasses are equal (and perhaps not loaded!) |
duke@435 | 3416 | // If we have constants, then we created oops so classes are loaded |
duke@435 | 3417 | // and we can handle the constants further down. This case handles |
duke@435 | 3418 | // both-not-loaded or both-loaded classes |
duke@435 | 3419 | if (ptr != Constant && klass()->equals(tinst->klass()) && klass_is_exact() == tinst->klass_is_exact()) { |
roland@6380 | 3420 | return make(ptr, klass(), klass_is_exact(), NULL, off, instance_id, speculative, depth); |
duke@435 | 3421 | } |
duke@435 | 3422 | |
duke@435 | 3423 | // Classes require inspection in the Java klass hierarchy. Must be loaded. |
duke@435 | 3424 | ciKlass* tinst_klass = tinst->klass(); |
duke@435 | 3425 | ciKlass* this_klass = this->klass(); |
duke@435 | 3426 | bool tinst_xk = tinst->klass_is_exact(); |
duke@435 | 3427 | bool this_xk = this->klass_is_exact(); |
duke@435 | 3428 | if (!tinst_klass->is_loaded() || !this_klass->is_loaded() ) { |
duke@435 | 3429 | // One of these classes has not been loaded |
duke@435 | 3430 | const TypeInstPtr *unloaded_meet = xmeet_unloaded(tinst); |
duke@435 | 3431 | #ifndef PRODUCT |
duke@435 | 3432 | if( PrintOpto && Verbose ) { |
duke@435 | 3433 | tty->print("meet of unloaded classes resulted in: "); unloaded_meet->dump(); tty->cr(); |
duke@435 | 3434 | tty->print(" this == "); this->dump(); tty->cr(); |
duke@435 | 3435 | tty->print(" tinst == "); tinst->dump(); tty->cr(); |
duke@435 | 3436 | } |
duke@435 | 3437 | #endif |
duke@435 | 3438 | return unloaded_meet; |
duke@435 | 3439 | } |
duke@435 | 3440 | |
duke@435 | 3441 | // Handle mixing oops and interfaces first. |
roland@5991 | 3442 | if( this_klass->is_interface() && !(tinst_klass->is_interface() || |
roland@5991 | 3443 | tinst_klass == ciEnv::current()->Object_klass())) { |
duke@435 | 3444 | ciKlass *tmp = tinst_klass; // Swap interface around |
duke@435 | 3445 | tinst_klass = this_klass; |
duke@435 | 3446 | this_klass = tmp; |
duke@435 | 3447 | bool tmp2 = tinst_xk; |
duke@435 | 3448 | tinst_xk = this_xk; |
duke@435 | 3449 | this_xk = tmp2; |
duke@435 | 3450 | } |
duke@435 | 3451 | if (tinst_klass->is_interface() && |
duke@435 | 3452 | !(this_klass->is_interface() || |
duke@435 | 3453 | // Treat java/lang/Object as an honorary interface, |
duke@435 | 3454 | // because we need a bottom for the interface hierarchy. |
duke@435 | 3455 | this_klass == ciEnv::current()->Object_klass())) { |
duke@435 | 3456 | // Oop meets interface! |
duke@435 | 3457 | |
duke@435 | 3458 | // See if the oop subtypes (implements) interface. |
duke@435 | 3459 | ciKlass *k; |
duke@435 | 3460 | bool xk; |
duke@435 | 3461 | if( this_klass->is_subtype_of( tinst_klass ) ) { |
duke@435 | 3462 | // Oop indeed subtypes. Now keep oop or interface depending |
duke@435 | 3463 | // on whether we are both above the centerline or either is |
duke@435 | 3464 | // below the centerline. If we are on the centerline |
duke@435 | 3465 | // (e.g., Constant vs. AnyNull interface), use the constant. |
duke@435 | 3466 | k = below_centerline(ptr) ? tinst_klass : this_klass; |
duke@435 | 3467 | // If we are keeping this_klass, keep its exactness too. |
duke@435 | 3468 | xk = below_centerline(ptr) ? tinst_xk : this_xk; |
duke@435 | 3469 | } else { // Does not implement, fall to Object |
duke@435 | 3470 | // Oop does not implement interface, so mixing falls to Object |
duke@435 | 3471 | // just like the verifier does (if both are above the |
duke@435 | 3472 | // centerline fall to interface) |
duke@435 | 3473 | k = above_centerline(ptr) ? tinst_klass : ciEnv::current()->Object_klass(); |
duke@435 | 3474 | xk = above_centerline(ptr) ? tinst_xk : false; |
duke@435 | 3475 | // Watch out for Constant vs. AnyNull interface. |
duke@435 | 3476 | if (ptr == Constant) ptr = NotNull; // forget it was a constant |
kvn@682 | 3477 | instance_id = InstanceBot; |
duke@435 | 3478 | } |
duke@435 | 3479 | ciObject* o = NULL; // the Constant value, if any |
duke@435 | 3480 | if (ptr == Constant) { |
duke@435 | 3481 | // Find out which constant. |
duke@435 | 3482 | o = (this_klass == klass()) ? const_oop() : tinst->const_oop(); |
duke@435 | 3483 | } |
roland@6380 | 3484 | return make(ptr, k, xk, o, off, instance_id, speculative, depth); |
duke@435 | 3485 | } |
duke@435 | 3486 | |
duke@435 | 3487 | // Either oop vs oop or interface vs interface or interface vs Object |
duke@435 | 3488 | |
duke@435 | 3489 | // !!! Here's how the symmetry requirement breaks down into invariants: |
duke@435 | 3490 | // If we split one up & one down AND they subtype, take the down man. |
duke@435 | 3491 | // If we split one up & one down AND they do NOT subtype, "fall hard". |
duke@435 | 3492 | // If both are up and they subtype, take the subtype class. |
duke@435 | 3493 | // If both are up and they do NOT subtype, "fall hard". |
duke@435 | 3494 | // If both are down and they subtype, take the supertype class. |
duke@435 | 3495 | // If both are down and they do NOT subtype, "fall hard". |
duke@435 | 3496 | // Constants treated as down. |
duke@435 | 3497 | |
duke@435 | 3498 | // Now, reorder the above list; observe that both-down+subtype is also |
duke@435 | 3499 | // "fall hard"; "fall hard" becomes the default case: |
duke@435 | 3500 | // If we split one up & one down AND they subtype, take the down man. |
duke@435 | 3501 | // If both are up and they subtype, take the subtype class. |
duke@435 | 3502 | |
duke@435 | 3503 | // If both are down and they subtype, "fall hard". |
duke@435 | 3504 | // If both are down and they do NOT subtype, "fall hard". |
duke@435 | 3505 | // If both are up and they do NOT subtype, "fall hard". |
duke@435 | 3506 | // If we split one up & one down AND they do NOT subtype, "fall hard". |
duke@435 | 3507 | |
duke@435 | 3508 | // If a proper subtype is exact, and we return it, we return it exactly. |
duke@435 | 3509 | // If a proper supertype is exact, there can be no subtyping relationship! |
duke@435 | 3510 | // If both types are equal to the subtype, exactness is and-ed below the |
duke@435 | 3511 | // centerline and or-ed above it. (N.B. Constants are always exact.) |
duke@435 | 3512 | |
duke@435 | 3513 | // Check for subtyping: |
duke@435 | 3514 | ciKlass *subtype = NULL; |
duke@435 | 3515 | bool subtype_exact = false; |
duke@435 | 3516 | if( tinst_klass->equals(this_klass) ) { |
duke@435 | 3517 | subtype = this_klass; |
duke@435 | 3518 | subtype_exact = below_centerline(ptr) ? (this_xk & tinst_xk) : (this_xk | tinst_xk); |
duke@435 | 3519 | } else if( !tinst_xk && this_klass->is_subtype_of( tinst_klass ) ) { |
duke@435 | 3520 | subtype = this_klass; // Pick subtyping class |
duke@435 | 3521 | subtype_exact = this_xk; |
duke@435 | 3522 | } else if( !this_xk && tinst_klass->is_subtype_of( this_klass ) ) { |
duke@435 | 3523 | subtype = tinst_klass; // Pick subtyping class |
duke@435 | 3524 | subtype_exact = tinst_xk; |
duke@435 | 3525 | } |
duke@435 | 3526 | |
duke@435 | 3527 | if( subtype ) { |
duke@435 | 3528 | if( above_centerline(ptr) ) { // both are up? |
duke@435 | 3529 | this_klass = tinst_klass = subtype; |
duke@435 | 3530 | this_xk = tinst_xk = subtype_exact; |
duke@435 | 3531 | } else if( above_centerline(this ->_ptr) && !above_centerline(tinst->_ptr) ) { |
duke@435 | 3532 | this_klass = tinst_klass; // tinst is down; keep down man |
duke@435 | 3533 | this_xk = tinst_xk; |
duke@435 | 3534 | } else if( above_centerline(tinst->_ptr) && !above_centerline(this ->_ptr) ) { |
duke@435 | 3535 | tinst_klass = this_klass; // this is down; keep down man |
duke@435 | 3536 | tinst_xk = this_xk; |
duke@435 | 3537 | } else { |
duke@435 | 3538 | this_xk = subtype_exact; // either they are equal, or we'll do an LCA |
duke@435 | 3539 | } |
duke@435 | 3540 | } |
duke@435 | 3541 | |
duke@435 | 3542 | // Check for classes now being equal |
duke@435 | 3543 | if (tinst_klass->equals(this_klass)) { |
duke@435 | 3544 | // If the klasses are equal, the constants may still differ. Fall to |
duke@435 | 3545 | // NotNull if they do (neither constant is NULL; that is a special case |
duke@435 | 3546 | // handled elsewhere). |
duke@435 | 3547 | ciObject* o = NULL; // Assume not constant when done |
duke@435 | 3548 | ciObject* this_oop = const_oop(); |
duke@435 | 3549 | ciObject* tinst_oop = tinst->const_oop(); |
duke@435 | 3550 | if( ptr == Constant ) { |
duke@435 | 3551 | if (this_oop != NULL && tinst_oop != NULL && |
duke@435 | 3552 | this_oop->equals(tinst_oop) ) |
duke@435 | 3553 | o = this_oop; |
duke@435 | 3554 | else if (above_centerline(this ->_ptr)) |
duke@435 | 3555 | o = tinst_oop; |
duke@435 | 3556 | else if (above_centerline(tinst ->_ptr)) |
duke@435 | 3557 | o = this_oop; |
duke@435 | 3558 | else |
duke@435 | 3559 | ptr = NotNull; |
duke@435 | 3560 | } |
roland@6380 | 3561 | return make(ptr, this_klass, this_xk, o, off, instance_id, speculative, depth); |
duke@435 | 3562 | } // Else classes are not equal |
duke@435 | 3563 | |
duke@435 | 3564 | // Since klasses are different, we require a LCA in the Java |
duke@435 | 3565 | // class hierarchy - which means we have to fall to at least NotNull. |
duke@435 | 3566 | if( ptr == TopPTR || ptr == AnyNull || ptr == Constant ) |
duke@435 | 3567 | ptr = NotNull; |
kvn@682 | 3568 | instance_id = InstanceBot; |
duke@435 | 3569 | |
duke@435 | 3570 | // Now we find the LCA of Java classes |
duke@435 | 3571 | ciKlass* k = this_klass->least_common_ancestor(tinst_klass); |
roland@6380 | 3572 | return make(ptr, k, false, NULL, off, instance_id, speculative, depth); |
duke@435 | 3573 | } // End of case InstPtr |
duke@435 | 3574 | |
duke@435 | 3575 | } // End of switch |
duke@435 | 3576 | return this; // Return the double constant |
duke@435 | 3577 | } |
duke@435 | 3578 | |
duke@435 | 3579 | |
duke@435 | 3580 | //------------------------java_mirror_type-------------------------------------- |
duke@435 | 3581 | ciType* TypeInstPtr::java_mirror_type() const { |
duke@435 | 3582 | // must be a singleton type |
duke@435 | 3583 | if( const_oop() == NULL ) return NULL; |
duke@435 | 3584 | |
duke@435 | 3585 | // must be of type java.lang.Class |
duke@435 | 3586 | if( klass() != ciEnv::current()->Class_klass() ) return NULL; |
duke@435 | 3587 | |
duke@435 | 3588 | return const_oop()->as_instance()->java_mirror_type(); |
duke@435 | 3589 | } |
duke@435 | 3590 | |
duke@435 | 3591 | |
duke@435 | 3592 | //------------------------------xdual------------------------------------------ |
duke@435 | 3593 | // Dual: do NOT dual on klasses. This means I do NOT understand the Java |
twisti@1040 | 3594 | // inheritance mechanism. |
duke@435 | 3595 | const Type *TypeInstPtr::xdual() const { |
roland@6380 | 3596 | return new TypeInstPtr(dual_ptr(), klass(), klass_is_exact(), const_oop(), dual_offset(), dual_instance_id(), dual_speculative(), dual_inline_depth()); |
duke@435 | 3597 | } |
duke@435 | 3598 | |
duke@435 | 3599 | //------------------------------eq--------------------------------------------- |
duke@435 | 3600 | // Structural equality check for Type representations |
duke@435 | 3601 | bool TypeInstPtr::eq( const Type *t ) const { |
duke@435 | 3602 | const TypeInstPtr *p = t->is_instptr(); |
duke@435 | 3603 | return |
duke@435 | 3604 | klass()->equals(p->klass()) && |
duke@435 | 3605 | TypeOopPtr::eq(p); // Check sub-type stuff |
duke@435 | 3606 | } |
duke@435 | 3607 | |
duke@435 | 3608 | //------------------------------hash------------------------------------------- |
duke@435 | 3609 | // Type-specific hashing function. |
duke@435 | 3610 | int TypeInstPtr::hash(void) const { |
duke@435 | 3611 | int hash = klass()->hash() + TypeOopPtr::hash(); |
duke@435 | 3612 | return hash; |
duke@435 | 3613 | } |
duke@435 | 3614 | |
duke@435 | 3615 | //------------------------------dump2------------------------------------------ |
duke@435 | 3616 | // Dump oop Type |
duke@435 | 3617 | #ifndef PRODUCT |
duke@435 | 3618 | void TypeInstPtr::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 3619 | // Print the name of the klass. |
duke@435 | 3620 | klass()->print_name_on(st); |
duke@435 | 3621 | |
duke@435 | 3622 | switch( _ptr ) { |
duke@435 | 3623 | case Constant: |
duke@435 | 3624 | // TO DO: Make CI print the hex address of the underlying oop. |
duke@435 | 3625 | if (WizardMode || Verbose) { |
duke@435 | 3626 | const_oop()->print_oop(st); |
duke@435 | 3627 | } |
duke@435 | 3628 | case BotPTR: |
duke@435 | 3629 | if (!WizardMode && !Verbose) { |
duke@435 | 3630 | if( _klass_is_exact ) st->print(":exact"); |
duke@435 | 3631 | break; |
duke@435 | 3632 | } |
duke@435 | 3633 | case TopPTR: |
duke@435 | 3634 | case AnyNull: |
duke@435 | 3635 | case NotNull: |
duke@435 | 3636 | st->print(":%s", ptr_msg[_ptr]); |
duke@435 | 3637 | if( _klass_is_exact ) st->print(":exact"); |
duke@435 | 3638 | break; |
duke@435 | 3639 | } |
duke@435 | 3640 | |
duke@435 | 3641 | if( _offset ) { // Dump offset, if any |
duke@435 | 3642 | if( _offset == OffsetBot ) st->print("+any"); |
duke@435 | 3643 | else if( _offset == OffsetTop ) st->print("+unknown"); |
duke@435 | 3644 | else st->print("+%d", _offset); |
duke@435 | 3645 | } |
duke@435 | 3646 | |
duke@435 | 3647 | st->print(" *"); |
kvn@658 | 3648 | if (_instance_id == InstanceTop) |
kvn@658 | 3649 | st->print(",iid=top"); |
kvn@658 | 3650 | else if (_instance_id != InstanceBot) |
duke@435 | 3651 | st->print(",iid=%d",_instance_id); |
roland@5991 | 3652 | |
roland@6380 | 3653 | dump_inline_depth(st); |
roland@5991 | 3654 | dump_speculative(st); |
duke@435 | 3655 | } |
duke@435 | 3656 | #endif |
duke@435 | 3657 | |
duke@435 | 3658 | //------------------------------add_offset------------------------------------- |
roland@5991 | 3659 | const TypePtr *TypeInstPtr::add_offset(intptr_t offset) const { |
roland@5991 | 3660 | return make(_ptr, klass(), klass_is_exact(), const_oop(), xadd_offset(offset), _instance_id, add_offset_speculative(offset)); |
roland@5991 | 3661 | } |
roland@5991 | 3662 | |
roland@6313 | 3663 | const Type *TypeInstPtr::remove_speculative() const { |
roland@6313 | 3664 | if (_speculative == NULL) { |
roland@6313 | 3665 | return this; |
roland@6313 | 3666 | } |
roland@6380 | 3667 | assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth"); |
roland@6380 | 3668 | return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, NULL, _inline_depth); |
roland@6380 | 3669 | } |
roland@6380 | 3670 | |
roland@6380 | 3671 | const TypeOopPtr *TypeInstPtr::with_inline_depth(int depth) const { |
roland@6380 | 3672 | if (!UseInlineDepthForSpeculativeTypes) { |
roland@6380 | 3673 | return this; |
roland@6380 | 3674 | } |
roland@6380 | 3675 | return make(_ptr, klass(), klass_is_exact(), const_oop(), _offset, _instance_id, _speculative, depth); |
duke@435 | 3676 | } |
duke@435 | 3677 | |
duke@435 | 3678 | //============================================================================= |
duke@435 | 3679 | // Convenience common pre-built types. |
duke@435 | 3680 | const TypeAryPtr *TypeAryPtr::RANGE; |
duke@435 | 3681 | const TypeAryPtr *TypeAryPtr::OOPS; |
kvn@598 | 3682 | const TypeAryPtr *TypeAryPtr::NARROWOOPS; |
duke@435 | 3683 | const TypeAryPtr *TypeAryPtr::BYTES; |
duke@435 | 3684 | const TypeAryPtr *TypeAryPtr::SHORTS; |
duke@435 | 3685 | const TypeAryPtr *TypeAryPtr::CHARS; |
duke@435 | 3686 | const TypeAryPtr *TypeAryPtr::INTS; |
duke@435 | 3687 | const TypeAryPtr *TypeAryPtr::LONGS; |
duke@435 | 3688 | const TypeAryPtr *TypeAryPtr::FLOATS; |
duke@435 | 3689 | const TypeAryPtr *TypeAryPtr::DOUBLES; |
duke@435 | 3690 | |
duke@435 | 3691 | //------------------------------make------------------------------------------- |
roland@6380 | 3692 | const TypeAryPtr *TypeAryPtr::make(PTR ptr, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth) { |
duke@435 | 3693 | assert(!(k == NULL && ary->_elem->isa_int()), |
duke@435 | 3694 | "integral arrays must be pre-equipped with a class"); |
duke@435 | 3695 | if (!xk) xk = ary->ary_must_be_exact(); |
kvn@682 | 3696 | assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); |
duke@435 | 3697 | if (!UseExactTypes) xk = (ptr == Constant); |
roland@6380 | 3698 | return (TypeAryPtr*)(new TypeAryPtr(ptr, NULL, ary, k, xk, offset, instance_id, false, speculative, inline_depth))->hashcons(); |
duke@435 | 3699 | } |
duke@435 | 3700 | |
duke@435 | 3701 | //------------------------------make------------------------------------------- |
roland@6380 | 3702 | const TypeAryPtr *TypeAryPtr::make(PTR ptr, ciObject* o, const TypeAry *ary, ciKlass* k, bool xk, int offset, int instance_id, const TypeOopPtr* speculative, int inline_depth, bool is_autobox_cache) { |
duke@435 | 3703 | assert(!(k == NULL && ary->_elem->isa_int()), |
duke@435 | 3704 | "integral arrays must be pre-equipped with a class"); |
duke@435 | 3705 | assert( (ptr==Constant && o) || (ptr!=Constant && !o), "" ); |
duke@435 | 3706 | if (!xk) xk = (o != NULL) || ary->ary_must_be_exact(); |
kvn@682 | 3707 | assert(instance_id <= 0 || xk || !UseExactTypes, "instances are always exactly typed"); |
duke@435 | 3708 | if (!UseExactTypes) xk = (ptr == Constant); |
roland@6380 | 3709 | return (TypeAryPtr*)(new TypeAryPtr(ptr, o, ary, k, xk, offset, instance_id, is_autobox_cache, speculative, inline_depth))->hashcons(); |
duke@435 | 3710 | } |
duke@435 | 3711 | |
duke@435 | 3712 | //------------------------------cast_to_ptr_type------------------------------- |
duke@435 | 3713 | const Type *TypeAryPtr::cast_to_ptr_type(PTR ptr) const { |
duke@435 | 3714 | if( ptr == _ptr ) return this; |
roland@6380 | 3715 | return make(ptr, const_oop(), _ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth); |
duke@435 | 3716 | } |
duke@435 | 3717 | |
duke@435 | 3718 | |
duke@435 | 3719 | //-----------------------------cast_to_exactness------------------------------- |
duke@435 | 3720 | const Type *TypeAryPtr::cast_to_exactness(bool klass_is_exact) const { |
duke@435 | 3721 | if( klass_is_exact == _klass_is_exact ) return this; |
duke@435 | 3722 | if (!UseExactTypes) return this; |
duke@435 | 3723 | if (_ary->ary_must_be_exact()) return this; // cannot clear xk |
roland@6380 | 3724 | return make(ptr(), const_oop(), _ary, klass(), klass_is_exact, _offset, _instance_id, _speculative, _inline_depth); |
duke@435 | 3725 | } |
duke@435 | 3726 | |
kvn@682 | 3727 | //-----------------------------cast_to_instance_id---------------------------- |
kvn@658 | 3728 | const TypeOopPtr *TypeAryPtr::cast_to_instance_id(int instance_id) const { |
kvn@658 | 3729 | if( instance_id == _instance_id ) return this; |
roland@6380 | 3730 | return make(_ptr, const_oop(), _ary, klass(), _klass_is_exact, _offset, instance_id, _speculative, _inline_depth); |
duke@435 | 3731 | } |
duke@435 | 3732 | |
duke@435 | 3733 | //-----------------------------narrow_size_type------------------------------- |
duke@435 | 3734 | // Local cache for arrayOopDesc::max_array_length(etype), |
duke@435 | 3735 | // which is kind of slow (and cached elsewhere by other users). |
duke@435 | 3736 | static jint max_array_length_cache[T_CONFLICT+1]; |
duke@435 | 3737 | static jint max_array_length(BasicType etype) { |
duke@435 | 3738 | jint& cache = max_array_length_cache[etype]; |
duke@435 | 3739 | jint res = cache; |
duke@435 | 3740 | if (res == 0) { |
duke@435 | 3741 | switch (etype) { |
coleenp@548 | 3742 | case T_NARROWOOP: |
coleenp@548 | 3743 | etype = T_OBJECT; |
coleenp@548 | 3744 | break; |
roland@4159 | 3745 | case T_NARROWKLASS: |
duke@435 | 3746 | case T_CONFLICT: |
duke@435 | 3747 | case T_ILLEGAL: |
duke@435 | 3748 | case T_VOID: |
duke@435 | 3749 | etype = T_BYTE; // will produce conservatively high value |
duke@435 | 3750 | } |
duke@435 | 3751 | cache = res = arrayOopDesc::max_array_length(etype); |
duke@435 | 3752 | } |
duke@435 | 3753 | return res; |
duke@435 | 3754 | } |
duke@435 | 3755 | |
duke@435 | 3756 | // Narrow the given size type to the index range for the given array base type. |
duke@435 | 3757 | // Return NULL if the resulting int type becomes empty. |
rasbold@801 | 3758 | const TypeInt* TypeAryPtr::narrow_size_type(const TypeInt* size) const { |
duke@435 | 3759 | jint hi = size->_hi; |
duke@435 | 3760 | jint lo = size->_lo; |
duke@435 | 3761 | jint min_lo = 0; |
rasbold@801 | 3762 | jint max_hi = max_array_length(elem()->basic_type()); |
duke@435 | 3763 | //if (index_not_size) --max_hi; // type of a valid array index, FTR |
duke@435 | 3764 | bool chg = false; |
kvn@5110 | 3765 | if (lo < min_lo) { |
kvn@5110 | 3766 | lo = min_lo; |
kvn@5110 | 3767 | if (size->is_con()) { |
kvn@5110 | 3768 | hi = lo; |
kvn@5110 | 3769 | } |
kvn@5110 | 3770 | chg = true; |
kvn@5110 | 3771 | } |
kvn@5110 | 3772 | if (hi > max_hi) { |
kvn@5110 | 3773 | hi = max_hi; |
kvn@5110 | 3774 | if (size->is_con()) { |
kvn@5110 | 3775 | lo = hi; |
kvn@5110 | 3776 | } |
kvn@5110 | 3777 | chg = true; |
kvn@5110 | 3778 | } |
twisti@1040 | 3779 | // Negative length arrays will produce weird intermediate dead fast-path code |
duke@435 | 3780 | if (lo > hi) |
rasbold@801 | 3781 | return TypeInt::ZERO; |
duke@435 | 3782 | if (!chg) |
duke@435 | 3783 | return size; |
duke@435 | 3784 | return TypeInt::make(lo, hi, Type::WidenMin); |
duke@435 | 3785 | } |
duke@435 | 3786 | |
duke@435 | 3787 | //-------------------------------cast_to_size---------------------------------- |
duke@435 | 3788 | const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const { |
duke@435 | 3789 | assert(new_size != NULL, ""); |
rasbold@801 | 3790 | new_size = narrow_size_type(new_size); |
duke@435 | 3791 | if (new_size == size()) return this; |
vlivanov@5658 | 3792 | const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable()); |
roland@6380 | 3793 | return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id, _speculative, _inline_depth); |
duke@435 | 3794 | } |
duke@435 | 3795 | |
duke@435 | 3796 | |
vlivanov@5658 | 3797 | //------------------------------cast_to_stable--------------------------------- |
vlivanov@5658 | 3798 | const TypeAryPtr* TypeAryPtr::cast_to_stable(bool stable, int stable_dimension) const { |
vlivanov@5658 | 3799 | if (stable_dimension <= 0 || (stable_dimension == 1 && stable == this->is_stable())) |
vlivanov@5658 | 3800 | return this; |
vlivanov@5658 | 3801 | |
vlivanov@5658 | 3802 | const Type* elem = this->elem(); |
vlivanov@5658 | 3803 | const TypePtr* elem_ptr = elem->make_ptr(); |
vlivanov@5658 | 3804 | |
vlivanov@5658 | 3805 | if (stable_dimension > 1 && elem_ptr != NULL && elem_ptr->isa_aryptr()) { |
vlivanov@5658 | 3806 | // If this is widened from a narrow oop, TypeAry::make will re-narrow it. |
vlivanov@5658 | 3807 | elem = elem_ptr = elem_ptr->is_aryptr()->cast_to_stable(stable, stable_dimension - 1); |
vlivanov@5658 | 3808 | } |
vlivanov@5658 | 3809 | |
vlivanov@5658 | 3810 | const TypeAry* new_ary = TypeAry::make(elem, size(), stable); |
vlivanov@5658 | 3811 | |
vlivanov@5658 | 3812 | return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); |
vlivanov@5658 | 3813 | } |
vlivanov@5658 | 3814 | |
vlivanov@5658 | 3815 | //-----------------------------stable_dimension-------------------------------- |
vlivanov@5658 | 3816 | int TypeAryPtr::stable_dimension() const { |
vlivanov@5658 | 3817 | if (!is_stable()) return 0; |
vlivanov@5658 | 3818 | int dim = 1; |
vlivanov@5658 | 3819 | const TypePtr* elem_ptr = elem()->make_ptr(); |
vlivanov@5658 | 3820 | if (elem_ptr != NULL && elem_ptr->isa_aryptr()) |
vlivanov@5658 | 3821 | dim += elem_ptr->is_aryptr()->stable_dimension(); |
vlivanov@5658 | 3822 | return dim; |
vlivanov@5658 | 3823 | } |
vlivanov@5658 | 3824 | |
duke@435 | 3825 | //------------------------------eq--------------------------------------------- |
duke@435 | 3826 | // Structural equality check for Type representations |
duke@435 | 3827 | bool TypeAryPtr::eq( const Type *t ) const { |
duke@435 | 3828 | const TypeAryPtr *p = t->is_aryptr(); |
duke@435 | 3829 | return |
duke@435 | 3830 | _ary == p->_ary && // Check array |
duke@435 | 3831 | TypeOopPtr::eq(p); // Check sub-parts |
duke@435 | 3832 | } |
duke@435 | 3833 | |
duke@435 | 3834 | //------------------------------hash------------------------------------------- |
duke@435 | 3835 | // Type-specific hashing function. |
duke@435 | 3836 | int TypeAryPtr::hash(void) const { |
duke@435 | 3837 | return (intptr_t)_ary + TypeOopPtr::hash(); |
duke@435 | 3838 | } |
duke@435 | 3839 | |
duke@435 | 3840 | //------------------------------meet------------------------------------------- |
duke@435 | 3841 | // Compute the MEET of two types. It returns a new Type object. |
roland@5991 | 3842 | const Type *TypeAryPtr::xmeet_helper(const Type *t) const { |
duke@435 | 3843 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 3844 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 3845 | // Current "this->_base" is Pointer |
duke@435 | 3846 | switch (t->base()) { // switch on original type |
duke@435 | 3847 | |
duke@435 | 3848 | // Mixing ints & oops happens when javac reuses local variables |
duke@435 | 3849 | case Int: |
duke@435 | 3850 | case Long: |
duke@435 | 3851 | case FloatTop: |
duke@435 | 3852 | case FloatCon: |
duke@435 | 3853 | case FloatBot: |
duke@435 | 3854 | case DoubleTop: |
duke@435 | 3855 | case DoubleCon: |
duke@435 | 3856 | case DoubleBot: |
coleenp@548 | 3857 | case NarrowOop: |
roland@4159 | 3858 | case NarrowKlass: |
duke@435 | 3859 | case Bottom: // Ye Olde Default |
duke@435 | 3860 | return Type::BOTTOM; |
duke@435 | 3861 | case Top: |
duke@435 | 3862 | return this; |
duke@435 | 3863 | |
duke@435 | 3864 | default: // All else is a mistake |
duke@435 | 3865 | typerr(t); |
duke@435 | 3866 | |
duke@435 | 3867 | case OopPtr: { // Meeting to OopPtrs |
duke@435 | 3868 | // Found a OopPtr type vs self-AryPtr type |
kvn@1393 | 3869 | const TypeOopPtr *tp = t->is_oopptr(); |
duke@435 | 3870 | int offset = meet_offset(tp->offset()); |
duke@435 | 3871 | PTR ptr = meet_ptr(tp->ptr()); |
roland@6380 | 3872 | int depth = meet_inline_depth(tp->inline_depth()); |
duke@435 | 3873 | switch (tp->ptr()) { |
duke@435 | 3874 | case TopPTR: |
kvn@658 | 3875 | case AnyNull: { |
kvn@658 | 3876 | int instance_id = meet_instance_id(InstanceTop); |
roland@6313 | 3877 | const TypeOopPtr* speculative = xmeet_speculative(tp); |
kvn@658 | 3878 | return make(ptr, (ptr == Constant ? const_oop() : NULL), |
roland@6380 | 3879 | _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth); |
kvn@658 | 3880 | } |
duke@435 | 3881 | case BotPTR: |
kvn@1393 | 3882 | case NotNull: { |
kvn@1393 | 3883 | int instance_id = meet_instance_id(tp->instance_id()); |
roland@6313 | 3884 | const TypeOopPtr* speculative = xmeet_speculative(tp); |
roland@6380 | 3885 | return TypeOopPtr::make(ptr, offset, instance_id, speculative, depth); |
kvn@1393 | 3886 | } |
duke@435 | 3887 | default: ShouldNotReachHere(); |
duke@435 | 3888 | } |
duke@435 | 3889 | } |
duke@435 | 3890 | |
duke@435 | 3891 | case AnyPtr: { // Meeting two AnyPtrs |
duke@435 | 3892 | // Found an AnyPtr type vs self-AryPtr type |
duke@435 | 3893 | const TypePtr *tp = t->is_ptr(); |
duke@435 | 3894 | int offset = meet_offset(tp->offset()); |
duke@435 | 3895 | PTR ptr = meet_ptr(tp->ptr()); |
duke@435 | 3896 | switch (tp->ptr()) { |
duke@435 | 3897 | case TopPTR: |
duke@435 | 3898 | return this; |
duke@435 | 3899 | case BotPTR: |
duke@435 | 3900 | case NotNull: |
duke@435 | 3901 | return TypePtr::make(AnyPtr, ptr, offset); |
duke@435 | 3902 | case Null: |
duke@435 | 3903 | if( ptr == Null ) return TypePtr::make(AnyPtr, ptr, offset); |
kvn@658 | 3904 | // else fall through to AnyNull |
kvn@658 | 3905 | case AnyNull: { |
kvn@658 | 3906 | int instance_id = meet_instance_id(InstanceTop); |
roland@5991 | 3907 | const TypeOopPtr* speculative = _speculative; |
roland@5991 | 3908 | return make(ptr, (ptr == Constant ? const_oop() : NULL), |
roland@6380 | 3909 | _ary, _klass, _klass_is_exact, offset, instance_id, speculative, _inline_depth); |
kvn@658 | 3910 | } |
duke@435 | 3911 | default: ShouldNotReachHere(); |
duke@435 | 3912 | } |
duke@435 | 3913 | } |
duke@435 | 3914 | |
coleenp@4037 | 3915 | case MetadataPtr: |
coleenp@4037 | 3916 | case KlassPtr: |
duke@435 | 3917 | case RawPtr: return TypePtr::BOTTOM; |
duke@435 | 3918 | |
duke@435 | 3919 | case AryPtr: { // Meeting 2 references? |
duke@435 | 3920 | const TypeAryPtr *tap = t->is_aryptr(); |
duke@435 | 3921 | int off = meet_offset(tap->offset()); |
roland@6313 | 3922 | const TypeAry *tary = _ary->meet_speculative(tap->_ary)->is_ary(); |
duke@435 | 3923 | PTR ptr = meet_ptr(tap->ptr()); |
kvn@658 | 3924 | int instance_id = meet_instance_id(tap->instance_id()); |
roland@6313 | 3925 | const TypeOopPtr* speculative = xmeet_speculative(tap); |
roland@6380 | 3926 | int depth = meet_inline_depth(tap->inline_depth()); |
duke@435 | 3927 | ciKlass* lazy_klass = NULL; |
duke@435 | 3928 | if (tary->_elem->isa_int()) { |
duke@435 | 3929 | // Integral array element types have irrelevant lattice relations. |
duke@435 | 3930 | // It is the klass that determines array layout, not the element type. |
duke@435 | 3931 | if (_klass == NULL) |
duke@435 | 3932 | lazy_klass = tap->_klass; |
duke@435 | 3933 | else if (tap->_klass == NULL || tap->_klass == _klass) { |
duke@435 | 3934 | lazy_klass = _klass; |
duke@435 | 3935 | } else { |
duke@435 | 3936 | // Something like byte[int+] meets char[int+]. |
duke@435 | 3937 | // This must fall to bottom, not (int[-128..65535])[int+]. |
kvn@682 | 3938 | instance_id = InstanceBot; |
vlivanov@5658 | 3939 | tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); |
duke@435 | 3940 | } |
kvn@2633 | 3941 | } else // Non integral arrays. |
roland@6214 | 3942 | // Must fall to bottom if exact klasses in upper lattice |
roland@6214 | 3943 | // are not equal or super klass is exact. |
roland@6214 | 3944 | if ((above_centerline(ptr) || ptr == Constant) && klass() != tap->klass() && |
roland@6214 | 3945 | // meet with top[] and bottom[] are processed further down: |
roland@6214 | 3946 | tap->_klass != NULL && this->_klass != NULL && |
roland@6214 | 3947 | // both are exact and not equal: |
roland@6214 | 3948 | ((tap->_klass_is_exact && this->_klass_is_exact) || |
roland@6214 | 3949 | // 'tap' is exact and super or unrelated: |
roland@6214 | 3950 | (tap->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || |
roland@6214 | 3951 | // 'this' is exact and super or unrelated: |
roland@6214 | 3952 | (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { |
vlivanov@5658 | 3953 | tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); |
roland@5991 | 3954 | return make(NotNull, NULL, tary, lazy_klass, false, off, InstanceBot); |
duke@435 | 3955 | } |
kvn@2633 | 3956 | |
kvn@2120 | 3957 | bool xk = false; |
duke@435 | 3958 | switch (tap->ptr()) { |
duke@435 | 3959 | case AnyNull: |
duke@435 | 3960 | case TopPTR: |
duke@435 | 3961 | // Compute new klass on demand, do not use tap->_klass |
roland@5991 | 3962 | if (below_centerline(this->_ptr)) { |
roland@5991 | 3963 | xk = this->_klass_is_exact; |
roland@5991 | 3964 | } else { |
roland@5991 | 3965 | xk = (tap->_klass_is_exact | this->_klass_is_exact); |
roland@5991 | 3966 | } |
roland@6380 | 3967 | return make(ptr, const_oop(), tary, lazy_klass, xk, off, instance_id, speculative, depth); |
duke@435 | 3968 | case Constant: { |
duke@435 | 3969 | ciObject* o = const_oop(); |
duke@435 | 3970 | if( _ptr == Constant ) { |
duke@435 | 3971 | if( tap->const_oop() != NULL && !o->equals(tap->const_oop()) ) { |
jrose@1424 | 3972 | xk = (klass() == tap->klass()); |
duke@435 | 3973 | ptr = NotNull; |
duke@435 | 3974 | o = NULL; |
kvn@682 | 3975 | instance_id = InstanceBot; |
jrose@1424 | 3976 | } else { |
jrose@1424 | 3977 | xk = true; |
duke@435 | 3978 | } |
roland@5991 | 3979 | } else if(above_centerline(_ptr)) { |
duke@435 | 3980 | o = tap->const_oop(); |
jrose@1424 | 3981 | xk = true; |
jrose@1424 | 3982 | } else { |
kvn@2120 | 3983 | // Only precise for identical arrays |
kvn@2120 | 3984 | xk = this->_klass_is_exact && (klass() == tap->klass()); |
duke@435 | 3985 | } |
roland@6380 | 3986 | return TypeAryPtr::make(ptr, o, tary, lazy_klass, xk, off, instance_id, speculative, depth); |
duke@435 | 3987 | } |
duke@435 | 3988 | case NotNull: |
duke@435 | 3989 | case BotPTR: |
duke@435 | 3990 | // Compute new klass on demand, do not use tap->_klass |
duke@435 | 3991 | if (above_centerline(this->_ptr)) |
duke@435 | 3992 | xk = tap->_klass_is_exact; |
duke@435 | 3993 | else xk = (tap->_klass_is_exact & this->_klass_is_exact) && |
duke@435 | 3994 | (klass() == tap->klass()); // Only precise for identical arrays |
roland@6380 | 3995 | return TypeAryPtr::make(ptr, NULL, tary, lazy_klass, xk, off, instance_id, speculative, depth); |
duke@435 | 3996 | default: ShouldNotReachHere(); |
duke@435 | 3997 | } |
duke@435 | 3998 | } |
duke@435 | 3999 | |
duke@435 | 4000 | // All arrays inherit from Object class |
duke@435 | 4001 | case InstPtr: { |
duke@435 | 4002 | const TypeInstPtr *tp = t->is_instptr(); |
duke@435 | 4003 | int offset = meet_offset(tp->offset()); |
duke@435 | 4004 | PTR ptr = meet_ptr(tp->ptr()); |
kvn@658 | 4005 | int instance_id = meet_instance_id(tp->instance_id()); |
roland@6313 | 4006 | const TypeOopPtr* speculative = xmeet_speculative(tp); |
roland@6380 | 4007 | int depth = meet_inline_depth(tp->inline_depth()); |
duke@435 | 4008 | switch (ptr) { |
duke@435 | 4009 | case TopPTR: |
duke@435 | 4010 | case AnyNull: // Fall 'down' to dual of object klass |
roland@5991 | 4011 | // For instances when a subclass meets a superclass we fall |
roland@5991 | 4012 | // below the centerline when the superclass is exact. We need to |
roland@5991 | 4013 | // do the same here. |
roland@5991 | 4014 | if (tp->klass()->equals(ciEnv::current()->Object_klass()) && !tp->klass_is_exact()) { |
roland@6380 | 4015 | return TypeAryPtr::make(ptr, _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth); |
duke@435 | 4016 | } else { |
duke@435 | 4017 | // cannot subclass, so the meet has to fall badly below the centerline |
duke@435 | 4018 | ptr = NotNull; |
kvn@658 | 4019 | instance_id = InstanceBot; |
roland@6380 | 4020 | return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative, depth); |
duke@435 | 4021 | } |
duke@435 | 4022 | case Constant: |
duke@435 | 4023 | case NotNull: |
duke@435 | 4024 | case BotPTR: // Fall down to object klass |
duke@435 | 4025 | // LCA is object_klass, but if we subclass from the top we can do better |
duke@435 | 4026 | if (above_centerline(tp->ptr())) { |
duke@435 | 4027 | // If 'tp' is above the centerline and it is Object class |
twisti@1040 | 4028 | // then we can subclass in the Java class hierarchy. |
roland@5991 | 4029 | // For instances when a subclass meets a superclass we fall |
roland@5991 | 4030 | // below the centerline when the superclass is exact. We need |
roland@5991 | 4031 | // to do the same here. |
roland@5991 | 4032 | if (tp->klass()->equals(ciEnv::current()->Object_klass()) && !tp->klass_is_exact()) { |
duke@435 | 4033 | // that is, my array type is a subtype of 'tp' klass |
roland@5991 | 4034 | return make(ptr, (ptr == Constant ? const_oop() : NULL), |
roland@6380 | 4035 | _ary, _klass, _klass_is_exact, offset, instance_id, speculative, depth); |
duke@435 | 4036 | } |
duke@435 | 4037 | } |
duke@435 | 4038 | // The other case cannot happen, since t cannot be a subtype of an array. |
duke@435 | 4039 | // The meet falls down to Object class below centerline. |
duke@435 | 4040 | if( ptr == Constant ) |
duke@435 | 4041 | ptr = NotNull; |
kvn@658 | 4042 | instance_id = InstanceBot; |
roland@6380 | 4043 | return TypeInstPtr::make(ptr, ciEnv::current()->Object_klass(), false, NULL,offset, instance_id, speculative, depth); |
duke@435 | 4044 | default: typerr(t); |
duke@435 | 4045 | } |
duke@435 | 4046 | } |
duke@435 | 4047 | } |
duke@435 | 4048 | return this; // Lint noise |
duke@435 | 4049 | } |
duke@435 | 4050 | |
duke@435 | 4051 | //------------------------------xdual------------------------------------------ |
duke@435 | 4052 | // Dual: compute field-by-field dual |
duke@435 | 4053 | const Type *TypeAryPtr::xdual() const { |
roland@6380 | 4054 | return new TypeAryPtr(dual_ptr(), _const_oop, _ary->dual()->is_ary(),_klass, _klass_is_exact, dual_offset(), dual_instance_id(), is_autobox_cache(), dual_speculative(), dual_inline_depth()); |
duke@435 | 4055 | } |
duke@435 | 4056 | |
kvn@1255 | 4057 | //----------------------interface_vs_oop--------------------------------------- |
kvn@1255 | 4058 | #ifdef ASSERT |
kvn@1255 | 4059 | bool TypeAryPtr::interface_vs_oop(const Type *t) const { |
kvn@1255 | 4060 | const TypeAryPtr* t_aryptr = t->isa_aryptr(); |
kvn@1255 | 4061 | if (t_aryptr) { |
kvn@1255 | 4062 | return _ary->interface_vs_oop(t_aryptr->_ary); |
kvn@1255 | 4063 | } |
kvn@1255 | 4064 | return false; |
kvn@1255 | 4065 | } |
kvn@1255 | 4066 | #endif |
kvn@1255 | 4067 | |
duke@435 | 4068 | //------------------------------dump2------------------------------------------ |
duke@435 | 4069 | #ifndef PRODUCT |
duke@435 | 4070 | void TypeAryPtr::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 4071 | _ary->dump2(d,depth,st); |
duke@435 | 4072 | switch( _ptr ) { |
duke@435 | 4073 | case Constant: |
duke@435 | 4074 | const_oop()->print(st); |
duke@435 | 4075 | break; |
duke@435 | 4076 | case BotPTR: |
duke@435 | 4077 | if (!WizardMode && !Verbose) { |
duke@435 | 4078 | if( _klass_is_exact ) st->print(":exact"); |
duke@435 | 4079 | break; |
duke@435 | 4080 | } |
duke@435 | 4081 | case TopPTR: |
duke@435 | 4082 | case AnyNull: |
duke@435 | 4083 | case NotNull: |
duke@435 | 4084 | st->print(":%s", ptr_msg[_ptr]); |
duke@435 | 4085 | if( _klass_is_exact ) st->print(":exact"); |
duke@435 | 4086 | break; |
duke@435 | 4087 | } |
duke@435 | 4088 | |
kvn@499 | 4089 | if( _offset != 0 ) { |
kvn@499 | 4090 | int header_size = objArrayOopDesc::header_size() * wordSize; |
kvn@499 | 4091 | if( _offset == OffsetTop ) st->print("+undefined"); |
kvn@499 | 4092 | else if( _offset == OffsetBot ) st->print("+any"); |
kvn@499 | 4093 | else if( _offset < header_size ) st->print("+%d", _offset); |
kvn@499 | 4094 | else { |
kvn@499 | 4095 | BasicType basic_elem_type = elem()->basic_type(); |
kvn@499 | 4096 | int array_base = arrayOopDesc::base_offset_in_bytes(basic_elem_type); |
kvn@499 | 4097 | int elem_size = type2aelembytes(basic_elem_type); |
kvn@499 | 4098 | st->print("[%d]", (_offset - array_base)/elem_size); |
kvn@499 | 4099 | } |
kvn@499 | 4100 | } |
kvn@499 | 4101 | st->print(" *"); |
kvn@658 | 4102 | if (_instance_id == InstanceTop) |
kvn@658 | 4103 | st->print(",iid=top"); |
kvn@658 | 4104 | else if (_instance_id != InstanceBot) |
duke@435 | 4105 | st->print(",iid=%d",_instance_id); |
roland@5991 | 4106 | |
roland@6380 | 4107 | dump_inline_depth(st); |
roland@5991 | 4108 | dump_speculative(st); |
duke@435 | 4109 | } |
duke@435 | 4110 | #endif |
duke@435 | 4111 | |
duke@435 | 4112 | bool TypeAryPtr::empty(void) const { |
duke@435 | 4113 | if (_ary->empty()) return true; |
duke@435 | 4114 | return TypeOopPtr::empty(); |
duke@435 | 4115 | } |
duke@435 | 4116 | |
duke@435 | 4117 | //------------------------------add_offset------------------------------------- |
roland@5991 | 4118 | const TypePtr *TypeAryPtr::add_offset(intptr_t offset) const { |
roland@6380 | 4119 | return make(_ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id, add_offset_speculative(offset), _inline_depth); |
roland@5991 | 4120 | } |
roland@5991 | 4121 | |
roland@6313 | 4122 | const Type *TypeAryPtr::remove_speculative() const { |
roland@6380 | 4123 | if (_speculative == NULL) { |
roland@6380 | 4124 | return this; |
roland@6380 | 4125 | } |
roland@6380 | 4126 | assert(_inline_depth == InlineDepthTop || _inline_depth == InlineDepthBottom, "non speculative type shouldn't have inline depth"); |
roland@6380 | 4127 | return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, NULL, _inline_depth); |
roland@6380 | 4128 | } |
roland@6380 | 4129 | |
roland@6380 | 4130 | const TypeOopPtr *TypeAryPtr::with_inline_depth(int depth) const { |
roland@6380 | 4131 | if (!UseInlineDepthForSpeculativeTypes) { |
roland@6380 | 4132 | return this; |
roland@6380 | 4133 | } |
roland@6380 | 4134 | return make(_ptr, _const_oop, _ary->remove_speculative()->is_ary(), _klass, _klass_is_exact, _offset, _instance_id, _speculative, depth); |
roland@5991 | 4135 | } |
duke@435 | 4136 | |
duke@435 | 4137 | //============================================================================= |
coleenp@548 | 4138 | |
coleenp@548 | 4139 | //------------------------------hash------------------------------------------- |
coleenp@548 | 4140 | // Type-specific hashing function. |
roland@4159 | 4141 | int TypeNarrowPtr::hash(void) const { |
never@1262 | 4142 | return _ptrtype->hash() + 7; |
coleenp@548 | 4143 | } |
coleenp@548 | 4144 | |
roland@4159 | 4145 | bool TypeNarrowPtr::singleton(void) const { // TRUE if type is a singleton |
roland@4159 | 4146 | return _ptrtype->singleton(); |
roland@4159 | 4147 | } |
roland@4159 | 4148 | |
roland@4159 | 4149 | bool TypeNarrowPtr::empty(void) const { |
roland@4159 | 4150 | return _ptrtype->empty(); |
roland@4159 | 4151 | } |
roland@4159 | 4152 | |
roland@4159 | 4153 | intptr_t TypeNarrowPtr::get_con() const { |
roland@4159 | 4154 | return _ptrtype->get_con(); |
roland@4159 | 4155 | } |
roland@4159 | 4156 | |
roland@4159 | 4157 | bool TypeNarrowPtr::eq( const Type *t ) const { |
roland@4159 | 4158 | const TypeNarrowPtr* tc = isa_same_narrowptr(t); |
coleenp@548 | 4159 | if (tc != NULL) { |
never@1262 | 4160 | if (_ptrtype->base() != tc->_ptrtype->base()) { |
coleenp@548 | 4161 | return false; |
coleenp@548 | 4162 | } |
never@1262 | 4163 | return tc->_ptrtype->eq(_ptrtype); |
coleenp@548 | 4164 | } |
coleenp@548 | 4165 | return false; |
coleenp@548 | 4166 | } |
coleenp@548 | 4167 | |
roland@4159 | 4168 | const Type *TypeNarrowPtr::xdual() const { // Compute dual right now. |
roland@4159 | 4169 | const TypePtr* odual = _ptrtype->dual()->is_ptr(); |
roland@4159 | 4170 | return make_same_narrowptr(odual); |
roland@4159 | 4171 | } |
roland@4159 | 4172 | |
roland@4159 | 4173 | |
roland@6313 | 4174 | const Type *TypeNarrowPtr::filter_helper(const Type *kills, bool include_speculative) const { |
roland@4159 | 4175 | if (isa_same_narrowptr(kills)) { |
roland@6313 | 4176 | const Type* ft =_ptrtype->filter_helper(is_same_narrowptr(kills)->_ptrtype, include_speculative); |
roland@4159 | 4177 | if (ft->empty()) |
roland@4159 | 4178 | return Type::TOP; // Canonical empty value |
roland@4159 | 4179 | if (ft->isa_ptr()) { |
roland@4159 | 4180 | return make_hash_same_narrowptr(ft->isa_ptr()); |
roland@4159 | 4181 | } |
roland@4159 | 4182 | return ft; |
roland@4159 | 4183 | } else if (kills->isa_ptr()) { |
roland@6313 | 4184 | const Type* ft = _ptrtype->join_helper(kills, include_speculative); |
roland@4159 | 4185 | if (ft->empty()) |
roland@4159 | 4186 | return Type::TOP; // Canonical empty value |
roland@4159 | 4187 | return ft; |
roland@4159 | 4188 | } else { |
roland@4159 | 4189 | return Type::TOP; |
roland@4159 | 4190 | } |
coleenp@548 | 4191 | } |
coleenp@548 | 4192 | |
kvn@728 | 4193 | //------------------------------xmeet------------------------------------------ |
coleenp@548 | 4194 | // Compute the MEET of two types. It returns a new Type object. |
roland@4159 | 4195 | const Type *TypeNarrowPtr::xmeet( const Type *t ) const { |
coleenp@548 | 4196 | // Perform a fast test for common case; meeting the same types together. |
coleenp@548 | 4197 | if( this == t ) return this; // Meeting same type-rep? |
coleenp@548 | 4198 | |
roland@4159 | 4199 | if (t->base() == base()) { |
roland@4159 | 4200 | const Type* result = _ptrtype->xmeet(t->make_ptr()); |
roland@4159 | 4201 | if (result->isa_ptr()) { |
roland@4159 | 4202 | return make_hash_same_narrowptr(result->is_ptr()); |
roland@4159 | 4203 | } |
roland@4159 | 4204 | return result; |
roland@4159 | 4205 | } |
roland@4159 | 4206 | |
roland@4159 | 4207 | // Current "this->_base" is NarrowKlass or NarrowOop |
coleenp@548 | 4208 | switch (t->base()) { // switch on original type |
coleenp@548 | 4209 | |
coleenp@548 | 4210 | case Int: // Mixing ints & oops happens when javac |
coleenp@548 | 4211 | case Long: // reuses local variables |
coleenp@548 | 4212 | case FloatTop: |
coleenp@548 | 4213 | case FloatCon: |
coleenp@548 | 4214 | case FloatBot: |
coleenp@548 | 4215 | case DoubleTop: |
coleenp@548 | 4216 | case DoubleCon: |
coleenp@548 | 4217 | case DoubleBot: |
kvn@728 | 4218 | case AnyPtr: |
kvn@728 | 4219 | case RawPtr: |
kvn@728 | 4220 | case OopPtr: |
kvn@728 | 4221 | case InstPtr: |
coleenp@4037 | 4222 | case AryPtr: |
coleenp@4037 | 4223 | case MetadataPtr: |
kvn@728 | 4224 | case KlassPtr: |
roland@4159 | 4225 | case NarrowOop: |
roland@4159 | 4226 | case NarrowKlass: |
kvn@728 | 4227 | |
coleenp@548 | 4228 | case Bottom: // Ye Olde Default |
coleenp@548 | 4229 | return Type::BOTTOM; |
coleenp@548 | 4230 | case Top: |
coleenp@548 | 4231 | return this; |
coleenp@548 | 4232 | |
coleenp@548 | 4233 | default: // All else is a mistake |
coleenp@548 | 4234 | typerr(t); |
coleenp@548 | 4235 | |
coleenp@548 | 4236 | } // End of switch |
kvn@728 | 4237 | |
kvn@728 | 4238 | return this; |
coleenp@548 | 4239 | } |
coleenp@548 | 4240 | |
roland@4159 | 4241 | #ifndef PRODUCT |
roland@4159 | 4242 | void TypeNarrowPtr::dump2( Dict & d, uint depth, outputStream *st ) const { |
roland@4159 | 4243 | _ptrtype->dump2(d, depth, st); |
roland@4159 | 4244 | } |
roland@4159 | 4245 | #endif |
roland@4159 | 4246 | |
roland@4159 | 4247 | const TypeNarrowOop *TypeNarrowOop::BOTTOM; |
roland@4159 | 4248 | const TypeNarrowOop *TypeNarrowOop::NULL_PTR; |
roland@4159 | 4249 | |
roland@4159 | 4250 | |
roland@4159 | 4251 | const TypeNarrowOop* TypeNarrowOop::make(const TypePtr* type) { |
roland@4159 | 4252 | return (const TypeNarrowOop*)(new TypeNarrowOop(type))->hashcons(); |
roland@4159 | 4253 | } |
roland@4159 | 4254 | |
coleenp@548 | 4255 | |
coleenp@548 | 4256 | #ifndef PRODUCT |
coleenp@548 | 4257 | void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const { |
never@852 | 4258 | st->print("narrowoop: "); |
roland@4159 | 4259 | TypeNarrowPtr::dump2(d, depth, st); |
coleenp@548 | 4260 | } |
coleenp@548 | 4261 | #endif |
coleenp@548 | 4262 | |
roland@4159 | 4263 | const TypeNarrowKlass *TypeNarrowKlass::NULL_PTR; |
roland@4159 | 4264 | |
roland@4159 | 4265 | const TypeNarrowKlass* TypeNarrowKlass::make(const TypePtr* type) { |
roland@4159 | 4266 | return (const TypeNarrowKlass*)(new TypeNarrowKlass(type))->hashcons(); |
roland@4159 | 4267 | } |
roland@4159 | 4268 | |
roland@4159 | 4269 | #ifndef PRODUCT |
roland@4159 | 4270 | void TypeNarrowKlass::dump2( Dict & d, uint depth, outputStream *st ) const { |
roland@4159 | 4271 | st->print("narrowklass: "); |
roland@4159 | 4272 | TypeNarrowPtr::dump2(d, depth, st); |
roland@4159 | 4273 | } |
roland@4159 | 4274 | #endif |
coleenp@548 | 4275 | |
coleenp@4037 | 4276 | |
coleenp@4037 | 4277 | //------------------------------eq--------------------------------------------- |
coleenp@4037 | 4278 | // Structural equality check for Type representations |
coleenp@4037 | 4279 | bool TypeMetadataPtr::eq( const Type *t ) const { |
coleenp@4037 | 4280 | const TypeMetadataPtr *a = (const TypeMetadataPtr*)t; |
coleenp@4037 | 4281 | ciMetadata* one = metadata(); |
coleenp@4037 | 4282 | ciMetadata* two = a->metadata(); |
coleenp@4037 | 4283 | if (one == NULL || two == NULL) { |
coleenp@4037 | 4284 | return (one == two) && TypePtr::eq(t); |
coleenp@4037 | 4285 | } else { |
coleenp@4037 | 4286 | return one->equals(two) && TypePtr::eq(t); |
coleenp@4037 | 4287 | } |
coleenp@4037 | 4288 | } |
coleenp@4037 | 4289 | |
coleenp@4037 | 4290 | //------------------------------hash------------------------------------------- |
coleenp@4037 | 4291 | // Type-specific hashing function. |
coleenp@4037 | 4292 | int TypeMetadataPtr::hash(void) const { |
coleenp@4037 | 4293 | return |
coleenp@4037 | 4294 | (metadata() ? metadata()->hash() : 0) + |
coleenp@4037 | 4295 | TypePtr::hash(); |
coleenp@4037 | 4296 | } |
coleenp@4037 | 4297 | |
coleenp@4037 | 4298 | //------------------------------singleton-------------------------------------- |
coleenp@4037 | 4299 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
coleenp@4037 | 4300 | // constants |
coleenp@4037 | 4301 | bool TypeMetadataPtr::singleton(void) const { |
coleenp@4037 | 4302 | // detune optimizer to not generate constant metadta + constant offset as a constant! |
coleenp@4037 | 4303 | // TopPTR, Null, AnyNull, Constant are all singletons |
coleenp@4037 | 4304 | return (_offset == 0) && !below_centerline(_ptr); |
coleenp@4037 | 4305 | } |
coleenp@4037 | 4306 | |
coleenp@4037 | 4307 | //------------------------------add_offset------------------------------------- |
coleenp@4037 | 4308 | const TypePtr *TypeMetadataPtr::add_offset( intptr_t offset ) const { |
coleenp@4037 | 4309 | return make( _ptr, _metadata, xadd_offset(offset)); |
coleenp@4037 | 4310 | } |
coleenp@4037 | 4311 | |
coleenp@4037 | 4312 | //-----------------------------filter------------------------------------------ |
coleenp@4037 | 4313 | // Do not allow interface-vs.-noninterface joins to collapse to top. |
roland@6313 | 4314 | const Type *TypeMetadataPtr::filter_helper(const Type *kills, bool include_speculative) const { |
roland@6313 | 4315 | const TypeMetadataPtr* ft = join_helper(kills, include_speculative)->isa_metadataptr(); |
coleenp@4037 | 4316 | if (ft == NULL || ft->empty()) |
coleenp@4037 | 4317 | return Type::TOP; // Canonical empty value |
coleenp@4037 | 4318 | return ft; |
coleenp@4037 | 4319 | } |
coleenp@4037 | 4320 | |
coleenp@4037 | 4321 | //------------------------------get_con---------------------------------------- |
coleenp@4037 | 4322 | intptr_t TypeMetadataPtr::get_con() const { |
coleenp@4037 | 4323 | assert( _ptr == Null || _ptr == Constant, "" ); |
coleenp@4037 | 4324 | assert( _offset >= 0, "" ); |
coleenp@4037 | 4325 | |
coleenp@4037 | 4326 | if (_offset != 0) { |
coleenp@4037 | 4327 | // After being ported to the compiler interface, the compiler no longer |
coleenp@4037 | 4328 | // directly manipulates the addresses of oops. Rather, it only has a pointer |
coleenp@4037 | 4329 | // to a handle at compile time. This handle is embedded in the generated |
coleenp@4037 | 4330 | // code and dereferenced at the time the nmethod is made. Until that time, |
coleenp@4037 | 4331 | // it is not reasonable to do arithmetic with the addresses of oops (we don't |
coleenp@4037 | 4332 | // have access to the addresses!). This does not seem to currently happen, |
coleenp@4037 | 4333 | // but this assertion here is to help prevent its occurence. |
coleenp@4037 | 4334 | tty->print_cr("Found oop constant with non-zero offset"); |
coleenp@4037 | 4335 | ShouldNotReachHere(); |
coleenp@4037 | 4336 | } |
coleenp@4037 | 4337 | |
coleenp@4037 | 4338 | return (intptr_t)metadata()->constant_encoding(); |
coleenp@4037 | 4339 | } |
coleenp@4037 | 4340 | |
coleenp@4037 | 4341 | //------------------------------cast_to_ptr_type------------------------------- |
coleenp@4037 | 4342 | const Type *TypeMetadataPtr::cast_to_ptr_type(PTR ptr) const { |
coleenp@4037 | 4343 | if( ptr == _ptr ) return this; |
coleenp@4037 | 4344 | return make(ptr, metadata(), _offset); |
coleenp@4037 | 4345 | } |
coleenp@4037 | 4346 | |
coleenp@4037 | 4347 | //------------------------------meet------------------------------------------- |
coleenp@4037 | 4348 | // Compute the MEET of two types. It returns a new Type object. |
coleenp@4037 | 4349 | const Type *TypeMetadataPtr::xmeet( const Type *t ) const { |
coleenp@4037 | 4350 | // Perform a fast test for common case; meeting the same types together. |
coleenp@4037 | 4351 | if( this == t ) return this; // Meeting same type-rep? |
coleenp@4037 | 4352 | |
coleenp@4037 | 4353 | // Current "this->_base" is OopPtr |
coleenp@4037 | 4354 | switch (t->base()) { // switch on original type |
coleenp@4037 | 4355 | |
coleenp@4037 | 4356 | case Int: // Mixing ints & oops happens when javac |
coleenp@4037 | 4357 | case Long: // reuses local variables |
coleenp@4037 | 4358 | case FloatTop: |
coleenp@4037 | 4359 | case FloatCon: |
coleenp@4037 | 4360 | case FloatBot: |
coleenp@4037 | 4361 | case DoubleTop: |
coleenp@4037 | 4362 | case DoubleCon: |
coleenp@4037 | 4363 | case DoubleBot: |
coleenp@4037 | 4364 | case NarrowOop: |
roland@4159 | 4365 | case NarrowKlass: |
coleenp@4037 | 4366 | case Bottom: // Ye Olde Default |
coleenp@4037 | 4367 | return Type::BOTTOM; |
coleenp@4037 | 4368 | case Top: |
coleenp@4037 | 4369 | return this; |
coleenp@4037 | 4370 | |
coleenp@4037 | 4371 | default: // All else is a mistake |
coleenp@4037 | 4372 | typerr(t); |
coleenp@4037 | 4373 | |
coleenp@4037 | 4374 | case AnyPtr: { |
coleenp@4037 | 4375 | // Found an AnyPtr type vs self-OopPtr type |
coleenp@4037 | 4376 | const TypePtr *tp = t->is_ptr(); |
coleenp@4037 | 4377 | int offset = meet_offset(tp->offset()); |
coleenp@4037 | 4378 | PTR ptr = meet_ptr(tp->ptr()); |
coleenp@4037 | 4379 | switch (tp->ptr()) { |
coleenp@4037 | 4380 | case Null: |
coleenp@4037 | 4381 | if (ptr == Null) return TypePtr::make(AnyPtr, ptr, offset); |
coleenp@4037 | 4382 | // else fall through: |
coleenp@4037 | 4383 | case TopPTR: |
coleenp@4037 | 4384 | case AnyNull: { |
kvn@6429 | 4385 | return make(ptr, _metadata, offset); |
coleenp@4037 | 4386 | } |
coleenp@4037 | 4387 | case BotPTR: |
coleenp@4037 | 4388 | case NotNull: |
coleenp@4037 | 4389 | return TypePtr::make(AnyPtr, ptr, offset); |
coleenp@4037 | 4390 | default: typerr(t); |
coleenp@4037 | 4391 | } |
coleenp@4037 | 4392 | } |
coleenp@4037 | 4393 | |
coleenp@4037 | 4394 | case RawPtr: |
coleenp@4037 | 4395 | case KlassPtr: |
coleenp@4037 | 4396 | case OopPtr: |
coleenp@4037 | 4397 | case InstPtr: |
coleenp@4037 | 4398 | case AryPtr: |
coleenp@4037 | 4399 | return TypePtr::BOTTOM; // Oop meet raw is not well defined |
coleenp@4037 | 4400 | |
roland@4040 | 4401 | case MetadataPtr: { |
roland@4040 | 4402 | const TypeMetadataPtr *tp = t->is_metadataptr(); |
roland@4040 | 4403 | int offset = meet_offset(tp->offset()); |
roland@4040 | 4404 | PTR tptr = tp->ptr(); |
roland@4040 | 4405 | PTR ptr = meet_ptr(tptr); |
roland@4040 | 4406 | ciMetadata* md = (tptr == TopPTR) ? metadata() : tp->metadata(); |
roland@4040 | 4407 | if (tptr == TopPTR || _ptr == TopPTR || |
roland@4040 | 4408 | metadata()->equals(tp->metadata())) { |
roland@4040 | 4409 | return make(ptr, md, offset); |
roland@4040 | 4410 | } |
roland@4040 | 4411 | // metadata is different |
roland@4040 | 4412 | if( ptr == Constant ) { // Cannot be equal constants, so... |
roland@4040 | 4413 | if( tptr == Constant && _ptr != Constant) return t; |
roland@4040 | 4414 | if( _ptr == Constant && tptr != Constant) return this; |
roland@4040 | 4415 | ptr = NotNull; // Fall down in lattice |
roland@4040 | 4416 | } |
roland@4040 | 4417 | return make(ptr, NULL, offset); |
coleenp@4037 | 4418 | break; |
roland@4040 | 4419 | } |
coleenp@4037 | 4420 | } // End of switch |
coleenp@4037 | 4421 | return this; // Return the double constant |
coleenp@4037 | 4422 | } |
coleenp@4037 | 4423 | |
coleenp@4037 | 4424 | |
coleenp@4037 | 4425 | //------------------------------xdual------------------------------------------ |
coleenp@4037 | 4426 | // Dual of a pure metadata pointer. |
coleenp@4037 | 4427 | const Type *TypeMetadataPtr::xdual() const { |
coleenp@4037 | 4428 | return new TypeMetadataPtr(dual_ptr(), metadata(), dual_offset()); |
coleenp@4037 | 4429 | } |
coleenp@4037 | 4430 | |
coleenp@4037 | 4431 | //------------------------------dump2------------------------------------------ |
coleenp@4037 | 4432 | #ifndef PRODUCT |
coleenp@4037 | 4433 | void TypeMetadataPtr::dump2( Dict &d, uint depth, outputStream *st ) const { |
coleenp@4037 | 4434 | st->print("metadataptr:%s", ptr_msg[_ptr]); |
coleenp@4037 | 4435 | if( metadata() ) st->print(INTPTR_FORMAT, metadata()); |
coleenp@4037 | 4436 | switch( _offset ) { |
coleenp@4037 | 4437 | case OffsetTop: st->print("+top"); break; |
coleenp@4037 | 4438 | case OffsetBot: st->print("+any"); break; |
coleenp@4037 | 4439 | case 0: break; |
coleenp@4037 | 4440 | default: st->print("+%d",_offset); break; |
coleenp@4037 | 4441 | } |
coleenp@4037 | 4442 | } |
coleenp@4037 | 4443 | #endif |
coleenp@4037 | 4444 | |
coleenp@4037 | 4445 | |
coleenp@4037 | 4446 | //============================================================================= |
coleenp@4037 | 4447 | // Convenience common pre-built type. |
coleenp@4037 | 4448 | const TypeMetadataPtr *TypeMetadataPtr::BOTTOM; |
coleenp@4037 | 4449 | |
coleenp@4037 | 4450 | TypeMetadataPtr::TypeMetadataPtr(PTR ptr, ciMetadata* metadata, int offset): |
coleenp@4037 | 4451 | TypePtr(MetadataPtr, ptr, offset), _metadata(metadata) { |
coleenp@4037 | 4452 | } |
coleenp@4037 | 4453 | |
coleenp@4037 | 4454 | const TypeMetadataPtr* TypeMetadataPtr::make(ciMethod* m) { |
coleenp@4037 | 4455 | return make(Constant, m, 0); |
coleenp@4037 | 4456 | } |
coleenp@4037 | 4457 | const TypeMetadataPtr* TypeMetadataPtr::make(ciMethodData* m) { |
coleenp@4037 | 4458 | return make(Constant, m, 0); |
coleenp@4037 | 4459 | } |
coleenp@4037 | 4460 | |
coleenp@4037 | 4461 | //------------------------------make------------------------------------------- |
coleenp@4037 | 4462 | // Create a meta data constant |
coleenp@4037 | 4463 | const TypeMetadataPtr *TypeMetadataPtr::make(PTR ptr, ciMetadata* m, int offset) { |
coleenp@4037 | 4464 | assert(m == NULL || !m->is_klass(), "wrong type"); |
coleenp@4037 | 4465 | return (TypeMetadataPtr*)(new TypeMetadataPtr(ptr, m, offset))->hashcons(); |
coleenp@4037 | 4466 | } |
coleenp@4037 | 4467 | |
coleenp@4037 | 4468 | |
coleenp@548 | 4469 | //============================================================================= |
duke@435 | 4470 | // Convenience common pre-built types. |
duke@435 | 4471 | |
duke@435 | 4472 | // Not-null object klass or below |
duke@435 | 4473 | const TypeKlassPtr *TypeKlassPtr::OBJECT; |
duke@435 | 4474 | const TypeKlassPtr *TypeKlassPtr::OBJECT_OR_NULL; |
duke@435 | 4475 | |
coleenp@4037 | 4476 | //------------------------------TypeKlassPtr----------------------------------- |
duke@435 | 4477 | TypeKlassPtr::TypeKlassPtr( PTR ptr, ciKlass* klass, int offset ) |
coleenp@4037 | 4478 | : TypePtr(KlassPtr, ptr, offset), _klass(klass), _klass_is_exact(ptr == Constant) { |
duke@435 | 4479 | } |
duke@435 | 4480 | |
duke@435 | 4481 | //------------------------------make------------------------------------------- |
duke@435 | 4482 | // ptr to klass 'k', if Constant, or possibly to a sub-klass if not a Constant |
duke@435 | 4483 | const TypeKlassPtr *TypeKlassPtr::make( PTR ptr, ciKlass* k, int offset ) { |
duke@435 | 4484 | assert( k != NULL, "Expect a non-NULL klass"); |
coleenp@4037 | 4485 | assert(k->is_instance_klass() || k->is_array_klass(), "Incorrect type of klass oop"); |
duke@435 | 4486 | TypeKlassPtr *r = |
duke@435 | 4487 | (TypeKlassPtr*)(new TypeKlassPtr(ptr, k, offset))->hashcons(); |
duke@435 | 4488 | |
duke@435 | 4489 | return r; |
duke@435 | 4490 | } |
duke@435 | 4491 | |
duke@435 | 4492 | //------------------------------eq--------------------------------------------- |
duke@435 | 4493 | // Structural equality check for Type representations |
duke@435 | 4494 | bool TypeKlassPtr::eq( const Type *t ) const { |
duke@435 | 4495 | const TypeKlassPtr *p = t->is_klassptr(); |
duke@435 | 4496 | return |
duke@435 | 4497 | klass()->equals(p->klass()) && |
coleenp@4037 | 4498 | TypePtr::eq(p); |
duke@435 | 4499 | } |
duke@435 | 4500 | |
duke@435 | 4501 | //------------------------------hash------------------------------------------- |
duke@435 | 4502 | // Type-specific hashing function. |
duke@435 | 4503 | int TypeKlassPtr::hash(void) const { |
coleenp@4037 | 4504 | return klass()->hash() + TypePtr::hash(); |
coleenp@4037 | 4505 | } |
coleenp@4037 | 4506 | |
coleenp@4037 | 4507 | //------------------------------singleton-------------------------------------- |
coleenp@4037 | 4508 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
coleenp@4037 | 4509 | // constants |
coleenp@4037 | 4510 | bool TypeKlassPtr::singleton(void) const { |
coleenp@4037 | 4511 | // detune optimizer to not generate constant klass + constant offset as a constant! |
coleenp@4037 | 4512 | // TopPTR, Null, AnyNull, Constant are all singletons |
coleenp@4037 | 4513 | return (_offset == 0) && !below_centerline(_ptr); |
coleenp@4037 | 4514 | } |
duke@435 | 4515 | |
roland@6043 | 4516 | // Do not allow interface-vs.-noninterface joins to collapse to top. |
roland@6313 | 4517 | const Type *TypeKlassPtr::filter_helper(const Type *kills, bool include_speculative) const { |
roland@6043 | 4518 | // logic here mirrors the one from TypeOopPtr::filter. See comments |
roland@6043 | 4519 | // there. |
roland@6313 | 4520 | const Type* ft = join_helper(kills, include_speculative); |
roland@6043 | 4521 | const TypeKlassPtr* ftkp = ft->isa_klassptr(); |
roland@6043 | 4522 | const TypeKlassPtr* ktkp = kills->isa_klassptr(); |
roland@6043 | 4523 | |
roland@6043 | 4524 | if (ft->empty()) { |
roland@6043 | 4525 | if (!empty() && ktkp != NULL && ktkp->klass()->is_loaded() && ktkp->klass()->is_interface()) |
roland@6043 | 4526 | return kills; // Uplift to interface |
roland@6043 | 4527 | |
roland@6043 | 4528 | return Type::TOP; // Canonical empty value |
roland@6043 | 4529 | } |
roland@6043 | 4530 | |
roland@6043 | 4531 | // Interface klass type could be exact in opposite to interface type, |
roland@6043 | 4532 | // return it here instead of incorrect Constant ptr J/L/Object (6894807). |
roland@6043 | 4533 | if (ftkp != NULL && ktkp != NULL && |
roland@6043 | 4534 | ftkp->is_loaded() && ftkp->klass()->is_interface() && |
roland@6043 | 4535 | !ftkp->klass_is_exact() && // Keep exact interface klass |
roland@6043 | 4536 | ktkp->is_loaded() && !ktkp->klass()->is_interface()) { |
roland@6043 | 4537 | return ktkp->cast_to_ptr_type(ftkp->ptr()); |
roland@6043 | 4538 | } |
roland@6043 | 4539 | |
roland@6043 | 4540 | return ft; |
roland@6043 | 4541 | } |
roland@6043 | 4542 | |
kvn@2116 | 4543 | //----------------------compute_klass------------------------------------------ |
kvn@2116 | 4544 | // Compute the defining klass for this class |
kvn@2116 | 4545 | ciKlass* TypeAryPtr::compute_klass(DEBUG_ONLY(bool verify)) const { |
kvn@2116 | 4546 | // Compute _klass based on element type. |
duke@435 | 4547 | ciKlass* k_ary = NULL; |
duke@435 | 4548 | const TypeInstPtr *tinst; |
duke@435 | 4549 | const TypeAryPtr *tary; |
coleenp@548 | 4550 | const Type* el = elem(); |
coleenp@548 | 4551 | if (el->isa_narrowoop()) { |
kvn@656 | 4552 | el = el->make_ptr(); |
coleenp@548 | 4553 | } |
coleenp@548 | 4554 | |
duke@435 | 4555 | // Get element klass |
coleenp@548 | 4556 | if ((tinst = el->isa_instptr()) != NULL) { |
duke@435 | 4557 | // Compute array klass from element klass |
duke@435 | 4558 | k_ary = ciObjArrayKlass::make(tinst->klass()); |
coleenp@548 | 4559 | } else if ((tary = el->isa_aryptr()) != NULL) { |
duke@435 | 4560 | // Compute array klass from element klass |
duke@435 | 4561 | ciKlass* k_elem = tary->klass(); |
duke@435 | 4562 | // If element type is something like bottom[], k_elem will be null. |
duke@435 | 4563 | if (k_elem != NULL) |
duke@435 | 4564 | k_ary = ciObjArrayKlass::make(k_elem); |
coleenp@548 | 4565 | } else if ((el->base() == Type::Top) || |
coleenp@548 | 4566 | (el->base() == Type::Bottom)) { |
duke@435 | 4567 | // element type of Bottom occurs from meet of basic type |
duke@435 | 4568 | // and object; Top occurs when doing join on Bottom. |
duke@435 | 4569 | // Leave k_ary at NULL. |
duke@435 | 4570 | } else { |
duke@435 | 4571 | // Cannot compute array klass directly from basic type, |
duke@435 | 4572 | // since subtypes of TypeInt all have basic type T_INT. |
kvn@2116 | 4573 | #ifdef ASSERT |
kvn@2116 | 4574 | if (verify && el->isa_int()) { |
kvn@2116 | 4575 | // Check simple cases when verifying klass. |
kvn@2116 | 4576 | BasicType bt = T_ILLEGAL; |
kvn@2116 | 4577 | if (el == TypeInt::BYTE) { |
kvn@2116 | 4578 | bt = T_BYTE; |
kvn@2116 | 4579 | } else if (el == TypeInt::SHORT) { |
kvn@2116 | 4580 | bt = T_SHORT; |
kvn@2116 | 4581 | } else if (el == TypeInt::CHAR) { |
kvn@2116 | 4582 | bt = T_CHAR; |
kvn@2116 | 4583 | } else if (el == TypeInt::INT) { |
kvn@2116 | 4584 | bt = T_INT; |
kvn@2116 | 4585 | } else { |
kvn@2116 | 4586 | return _klass; // just return specified klass |
kvn@2116 | 4587 | } |
kvn@2116 | 4588 | return ciTypeArrayKlass::make(bt); |
kvn@2116 | 4589 | } |
kvn@2116 | 4590 | #endif |
coleenp@548 | 4591 | assert(!el->isa_int(), |
duke@435 | 4592 | "integral arrays must be pre-equipped with a class"); |
duke@435 | 4593 | // Compute array klass directly from basic type |
coleenp@548 | 4594 | k_ary = ciTypeArrayKlass::make(el->basic_type()); |
duke@435 | 4595 | } |
kvn@2116 | 4596 | return k_ary; |
kvn@2116 | 4597 | } |
kvn@2116 | 4598 | |
kvn@2116 | 4599 | //------------------------------klass------------------------------------------ |
kvn@2116 | 4600 | // Return the defining klass for this class |
kvn@2116 | 4601 | ciKlass* TypeAryPtr::klass() const { |
kvn@2116 | 4602 | if( _klass ) return _klass; // Return cached value, if possible |
kvn@2116 | 4603 | |
kvn@2116 | 4604 | // Oops, need to compute _klass and cache it |
kvn@2116 | 4605 | ciKlass* k_ary = compute_klass(); |
duke@435 | 4606 | |
kvn@2636 | 4607 | if( this != TypeAryPtr::OOPS && this->dual() != TypeAryPtr::OOPS ) { |
duke@435 | 4608 | // The _klass field acts as a cache of the underlying |
duke@435 | 4609 | // ciKlass for this array type. In order to set the field, |
duke@435 | 4610 | // we need to cast away const-ness. |
duke@435 | 4611 | // |
duke@435 | 4612 | // IMPORTANT NOTE: we *never* set the _klass field for the |
duke@435 | 4613 | // type TypeAryPtr::OOPS. This Type is shared between all |
duke@435 | 4614 | // active compilations. However, the ciKlass which represents |
duke@435 | 4615 | // this Type is *not* shared between compilations, so caching |
duke@435 | 4616 | // this value would result in fetching a dangling pointer. |
duke@435 | 4617 | // |
duke@435 | 4618 | // Recomputing the underlying ciKlass for each request is |
duke@435 | 4619 | // a bit less efficient than caching, but calls to |
duke@435 | 4620 | // TypeAryPtr::OOPS->klass() are not common enough to matter. |
duke@435 | 4621 | ((TypeAryPtr*)this)->_klass = k_ary; |
kvn@598 | 4622 | if (UseCompressedOops && k_ary != NULL && k_ary->is_obj_array_klass() && |
kvn@598 | 4623 | _offset != 0 && _offset != arrayOopDesc::length_offset_in_bytes()) { |
kvn@598 | 4624 | ((TypeAryPtr*)this)->_is_ptr_to_narrowoop = true; |
kvn@598 | 4625 | } |
kvn@598 | 4626 | } |
duke@435 | 4627 | return k_ary; |
duke@435 | 4628 | } |
duke@435 | 4629 | |
duke@435 | 4630 | |
duke@435 | 4631 | //------------------------------add_offset------------------------------------- |
duke@435 | 4632 | // Access internals of klass object |
kvn@741 | 4633 | const TypePtr *TypeKlassPtr::add_offset( intptr_t offset ) const { |
duke@435 | 4634 | return make( _ptr, klass(), xadd_offset(offset) ); |
duke@435 | 4635 | } |
duke@435 | 4636 | |
duke@435 | 4637 | //------------------------------cast_to_ptr_type------------------------------- |
duke@435 | 4638 | const Type *TypeKlassPtr::cast_to_ptr_type(PTR ptr) const { |
kvn@992 | 4639 | assert(_base == KlassPtr, "subclass must override cast_to_ptr_type"); |
duke@435 | 4640 | if( ptr == _ptr ) return this; |
duke@435 | 4641 | return make(ptr, _klass, _offset); |
duke@435 | 4642 | } |
duke@435 | 4643 | |
duke@435 | 4644 | |
duke@435 | 4645 | //-----------------------------cast_to_exactness------------------------------- |
duke@435 | 4646 | const Type *TypeKlassPtr::cast_to_exactness(bool klass_is_exact) const { |
duke@435 | 4647 | if( klass_is_exact == _klass_is_exact ) return this; |
duke@435 | 4648 | if (!UseExactTypes) return this; |
duke@435 | 4649 | return make(klass_is_exact ? Constant : NotNull, _klass, _offset); |
duke@435 | 4650 | } |
duke@435 | 4651 | |
duke@435 | 4652 | |
duke@435 | 4653 | //-----------------------------as_instance_type-------------------------------- |
duke@435 | 4654 | // Corresponding type for an instance of the given class. |
duke@435 | 4655 | // It will be NotNull, and exact if and only if the klass type is exact. |
duke@435 | 4656 | const TypeOopPtr* TypeKlassPtr::as_instance_type() const { |
duke@435 | 4657 | ciKlass* k = klass(); |
duke@435 | 4658 | bool xk = klass_is_exact(); |
duke@435 | 4659 | //return TypeInstPtr::make(TypePtr::NotNull, k, xk, NULL, 0); |
duke@435 | 4660 | const TypeOopPtr* toop = TypeOopPtr::make_from_klass_raw(k); |
morris@4760 | 4661 | guarantee(toop != NULL, "need type for given klass"); |
duke@435 | 4662 | toop = toop->cast_to_ptr_type(TypePtr::NotNull)->is_oopptr(); |
duke@435 | 4663 | return toop->cast_to_exactness(xk)->is_oopptr(); |
duke@435 | 4664 | } |
duke@435 | 4665 | |
duke@435 | 4666 | |
duke@435 | 4667 | //------------------------------xmeet------------------------------------------ |
duke@435 | 4668 | // Compute the MEET of two types, return a new Type object. |
duke@435 | 4669 | const Type *TypeKlassPtr::xmeet( const Type *t ) const { |
duke@435 | 4670 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 4671 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 4672 | |
duke@435 | 4673 | // Current "this->_base" is Pointer |
duke@435 | 4674 | switch (t->base()) { // switch on original type |
duke@435 | 4675 | |
duke@435 | 4676 | case Int: // Mixing ints & oops happens when javac |
duke@435 | 4677 | case Long: // reuses local variables |
duke@435 | 4678 | case FloatTop: |
duke@435 | 4679 | case FloatCon: |
duke@435 | 4680 | case FloatBot: |
duke@435 | 4681 | case DoubleTop: |
duke@435 | 4682 | case DoubleCon: |
duke@435 | 4683 | case DoubleBot: |
kvn@728 | 4684 | case NarrowOop: |
roland@4159 | 4685 | case NarrowKlass: |
duke@435 | 4686 | case Bottom: // Ye Olde Default |
duke@435 | 4687 | return Type::BOTTOM; |
duke@435 | 4688 | case Top: |
duke@435 | 4689 | return this; |
duke@435 | 4690 | |
duke@435 | 4691 | default: // All else is a mistake |
duke@435 | 4692 | typerr(t); |
duke@435 | 4693 | |
duke@435 | 4694 | case AnyPtr: { // Meeting to AnyPtrs |
duke@435 | 4695 | // Found an AnyPtr type vs self-KlassPtr type |
duke@435 | 4696 | const TypePtr *tp = t->is_ptr(); |
duke@435 | 4697 | int offset = meet_offset(tp->offset()); |
duke@435 | 4698 | PTR ptr = meet_ptr(tp->ptr()); |
duke@435 | 4699 | switch (tp->ptr()) { |
duke@435 | 4700 | case TopPTR: |
duke@435 | 4701 | return this; |
duke@435 | 4702 | case Null: |
duke@435 | 4703 | if( ptr == Null ) return TypePtr::make( AnyPtr, ptr, offset ); |
duke@435 | 4704 | case AnyNull: |
duke@435 | 4705 | return make( ptr, klass(), offset ); |
duke@435 | 4706 | case BotPTR: |
duke@435 | 4707 | case NotNull: |
duke@435 | 4708 | return TypePtr::make(AnyPtr, ptr, offset); |
duke@435 | 4709 | default: typerr(t); |
duke@435 | 4710 | } |
duke@435 | 4711 | } |
duke@435 | 4712 | |
coleenp@4037 | 4713 | case RawPtr: |
coleenp@4037 | 4714 | case MetadataPtr: |
coleenp@4037 | 4715 | case OopPtr: |
duke@435 | 4716 | case AryPtr: // Meet with AryPtr |
duke@435 | 4717 | case InstPtr: // Meet with InstPtr |
coleenp@4037 | 4718 | return TypePtr::BOTTOM; |
duke@435 | 4719 | |
duke@435 | 4720 | // |
duke@435 | 4721 | // A-top } |
duke@435 | 4722 | // / | \ } Tops |
duke@435 | 4723 | // B-top A-any C-top } |
duke@435 | 4724 | // | / | \ | } Any-nulls |
duke@435 | 4725 | // B-any | C-any } |
duke@435 | 4726 | // | | | |
duke@435 | 4727 | // B-con A-con C-con } constants; not comparable across classes |
duke@435 | 4728 | // | | | |
duke@435 | 4729 | // B-not | C-not } |
duke@435 | 4730 | // | \ | / | } not-nulls |
duke@435 | 4731 | // B-bot A-not C-bot } |
duke@435 | 4732 | // \ | / } Bottoms |
duke@435 | 4733 | // A-bot } |
duke@435 | 4734 | // |
duke@435 | 4735 | |
duke@435 | 4736 | case KlassPtr: { // Meet two KlassPtr types |
duke@435 | 4737 | const TypeKlassPtr *tkls = t->is_klassptr(); |
duke@435 | 4738 | int off = meet_offset(tkls->offset()); |
duke@435 | 4739 | PTR ptr = meet_ptr(tkls->ptr()); |
duke@435 | 4740 | |
duke@435 | 4741 | // Check for easy case; klasses are equal (and perhaps not loaded!) |
duke@435 | 4742 | // If we have constants, then we created oops so classes are loaded |
duke@435 | 4743 | // and we can handle the constants further down. This case handles |
duke@435 | 4744 | // not-loaded classes |
duke@435 | 4745 | if( ptr != Constant && tkls->klass()->equals(klass()) ) { |
duke@435 | 4746 | return make( ptr, klass(), off ); |
duke@435 | 4747 | } |
duke@435 | 4748 | |
duke@435 | 4749 | // Classes require inspection in the Java klass hierarchy. Must be loaded. |
duke@435 | 4750 | ciKlass* tkls_klass = tkls->klass(); |
duke@435 | 4751 | ciKlass* this_klass = this->klass(); |
duke@435 | 4752 | assert( tkls_klass->is_loaded(), "This class should have been loaded."); |
duke@435 | 4753 | assert( this_klass->is_loaded(), "This class should have been loaded."); |
duke@435 | 4754 | |
duke@435 | 4755 | // If 'this' type is above the centerline and is a superclass of the |
duke@435 | 4756 | // other, we can treat 'this' as having the same type as the other. |
duke@435 | 4757 | if ((above_centerline(this->ptr())) && |
duke@435 | 4758 | tkls_klass->is_subtype_of(this_klass)) { |
duke@435 | 4759 | this_klass = tkls_klass; |
duke@435 | 4760 | } |
duke@435 | 4761 | // If 'tinst' type is above the centerline and is a superclass of the |
duke@435 | 4762 | // other, we can treat 'tinst' as having the same type as the other. |
duke@435 | 4763 | if ((above_centerline(tkls->ptr())) && |
duke@435 | 4764 | this_klass->is_subtype_of(tkls_klass)) { |
duke@435 | 4765 | tkls_klass = this_klass; |
duke@435 | 4766 | } |
duke@435 | 4767 | |
duke@435 | 4768 | // Check for classes now being equal |
duke@435 | 4769 | if (tkls_klass->equals(this_klass)) { |
duke@435 | 4770 | // If the klasses are equal, the constants may still differ. Fall to |
duke@435 | 4771 | // NotNull if they do (neither constant is NULL; that is a special case |
duke@435 | 4772 | // handled elsewhere). |
duke@435 | 4773 | if( ptr == Constant ) { |
coleenp@4037 | 4774 | if (this->_ptr == Constant && tkls->_ptr == Constant && |
coleenp@4037 | 4775 | this->klass()->equals(tkls->klass())); |
coleenp@4037 | 4776 | else if (above_centerline(this->ptr())); |
coleenp@4037 | 4777 | else if (above_centerline(tkls->ptr())); |
duke@435 | 4778 | else |
duke@435 | 4779 | ptr = NotNull; |
duke@435 | 4780 | } |
duke@435 | 4781 | return make( ptr, this_klass, off ); |
duke@435 | 4782 | } // Else classes are not equal |
duke@435 | 4783 | |
duke@435 | 4784 | // Since klasses are different, we require the LCA in the Java |
duke@435 | 4785 | // class hierarchy - which means we have to fall to at least NotNull. |
duke@435 | 4786 | if( ptr == TopPTR || ptr == AnyNull || ptr == Constant ) |
duke@435 | 4787 | ptr = NotNull; |
duke@435 | 4788 | // Now we find the LCA of Java classes |
duke@435 | 4789 | ciKlass* k = this_klass->least_common_ancestor(tkls_klass); |
duke@435 | 4790 | return make( ptr, k, off ); |
duke@435 | 4791 | } // End of case KlassPtr |
duke@435 | 4792 | |
duke@435 | 4793 | } // End of switch |
duke@435 | 4794 | return this; // Return the double constant |
duke@435 | 4795 | } |
duke@435 | 4796 | |
duke@435 | 4797 | //------------------------------xdual------------------------------------------ |
duke@435 | 4798 | // Dual: compute field-by-field dual |
duke@435 | 4799 | const Type *TypeKlassPtr::xdual() const { |
duke@435 | 4800 | return new TypeKlassPtr( dual_ptr(), klass(), dual_offset() ); |
duke@435 | 4801 | } |
duke@435 | 4802 | |
coleenp@4037 | 4803 | //------------------------------get_con---------------------------------------- |
coleenp@4037 | 4804 | intptr_t TypeKlassPtr::get_con() const { |
coleenp@4037 | 4805 | assert( _ptr == Null || _ptr == Constant, "" ); |
coleenp@4037 | 4806 | assert( _offset >= 0, "" ); |
coleenp@4037 | 4807 | |
coleenp@4037 | 4808 | if (_offset != 0) { |
coleenp@4037 | 4809 | // After being ported to the compiler interface, the compiler no longer |
coleenp@4037 | 4810 | // directly manipulates the addresses of oops. Rather, it only has a pointer |
coleenp@4037 | 4811 | // to a handle at compile time. This handle is embedded in the generated |
coleenp@4037 | 4812 | // code and dereferenced at the time the nmethod is made. Until that time, |
coleenp@4037 | 4813 | // it is not reasonable to do arithmetic with the addresses of oops (we don't |
coleenp@4037 | 4814 | // have access to the addresses!). This does not seem to currently happen, |
coleenp@4037 | 4815 | // but this assertion here is to help prevent its occurence. |
coleenp@4037 | 4816 | tty->print_cr("Found oop constant with non-zero offset"); |
coleenp@4037 | 4817 | ShouldNotReachHere(); |
coleenp@4037 | 4818 | } |
coleenp@4037 | 4819 | |
coleenp@4037 | 4820 | return (intptr_t)klass()->constant_encoding(); |
coleenp@4037 | 4821 | } |
duke@435 | 4822 | //------------------------------dump2------------------------------------------ |
duke@435 | 4823 | // Dump Klass Type |
duke@435 | 4824 | #ifndef PRODUCT |
duke@435 | 4825 | void TypeKlassPtr::dump2( Dict & d, uint depth, outputStream *st ) const { |
duke@435 | 4826 | switch( _ptr ) { |
duke@435 | 4827 | case Constant: |
duke@435 | 4828 | st->print("precise "); |
duke@435 | 4829 | case NotNull: |
duke@435 | 4830 | { |
duke@435 | 4831 | const char *name = klass()->name()->as_utf8(); |
duke@435 | 4832 | if( name ) { |
duke@435 | 4833 | st->print("klass %s: " INTPTR_FORMAT, name, klass()); |
duke@435 | 4834 | } else { |
duke@435 | 4835 | ShouldNotReachHere(); |
duke@435 | 4836 | } |
duke@435 | 4837 | } |
duke@435 | 4838 | case BotPTR: |
duke@435 | 4839 | if( !WizardMode && !Verbose && !_klass_is_exact ) break; |
duke@435 | 4840 | case TopPTR: |
duke@435 | 4841 | case AnyNull: |
duke@435 | 4842 | st->print(":%s", ptr_msg[_ptr]); |
duke@435 | 4843 | if( _klass_is_exact ) st->print(":exact"); |
duke@435 | 4844 | break; |
duke@435 | 4845 | } |
duke@435 | 4846 | |
duke@435 | 4847 | if( _offset ) { // Dump offset, if any |
duke@435 | 4848 | if( _offset == OffsetBot ) { st->print("+any"); } |
duke@435 | 4849 | else if( _offset == OffsetTop ) { st->print("+unknown"); } |
duke@435 | 4850 | else { st->print("+%d", _offset); } |
duke@435 | 4851 | } |
duke@435 | 4852 | |
duke@435 | 4853 | st->print(" *"); |
duke@435 | 4854 | } |
duke@435 | 4855 | #endif |
duke@435 | 4856 | |
duke@435 | 4857 | |
duke@435 | 4858 | |
duke@435 | 4859 | //============================================================================= |
duke@435 | 4860 | // Convenience common pre-built types. |
duke@435 | 4861 | |
duke@435 | 4862 | //------------------------------make------------------------------------------- |
duke@435 | 4863 | const TypeFunc *TypeFunc::make( const TypeTuple *domain, const TypeTuple *range ) { |
duke@435 | 4864 | return (TypeFunc*)(new TypeFunc(domain,range))->hashcons(); |
duke@435 | 4865 | } |
duke@435 | 4866 | |
duke@435 | 4867 | //------------------------------make------------------------------------------- |
duke@435 | 4868 | const TypeFunc *TypeFunc::make(ciMethod* method) { |
duke@435 | 4869 | Compile* C = Compile::current(); |
duke@435 | 4870 | const TypeFunc* tf = C->last_tf(method); // check cache |
duke@435 | 4871 | if (tf != NULL) return tf; // The hit rate here is almost 50%. |
duke@435 | 4872 | const TypeTuple *domain; |
twisti@1572 | 4873 | if (method->is_static()) { |
duke@435 | 4874 | domain = TypeTuple::make_domain(NULL, method->signature()); |
duke@435 | 4875 | } else { |
duke@435 | 4876 | domain = TypeTuple::make_domain(method->holder(), method->signature()); |
duke@435 | 4877 | } |
duke@435 | 4878 | const TypeTuple *range = TypeTuple::make_range(method->signature()); |
duke@435 | 4879 | tf = TypeFunc::make(domain, range); |
duke@435 | 4880 | C->set_last_tf(method, tf); // fill cache |
duke@435 | 4881 | return tf; |
duke@435 | 4882 | } |
duke@435 | 4883 | |
duke@435 | 4884 | //------------------------------meet------------------------------------------- |
duke@435 | 4885 | // Compute the MEET of two types. It returns a new Type object. |
duke@435 | 4886 | const Type *TypeFunc::xmeet( const Type *t ) const { |
duke@435 | 4887 | // Perform a fast test for common case; meeting the same types together. |
duke@435 | 4888 | if( this == t ) return this; // Meeting same type-rep? |
duke@435 | 4889 | |
duke@435 | 4890 | // Current "this->_base" is Func |
duke@435 | 4891 | switch (t->base()) { // switch on original type |
duke@435 | 4892 | |
duke@435 | 4893 | case Bottom: // Ye Olde Default |
duke@435 | 4894 | return t; |
duke@435 | 4895 | |
duke@435 | 4896 | default: // All else is a mistake |
duke@435 | 4897 | typerr(t); |
duke@435 | 4898 | |
duke@435 | 4899 | case Top: |
duke@435 | 4900 | break; |
duke@435 | 4901 | } |
duke@435 | 4902 | return this; // Return the double constant |
duke@435 | 4903 | } |
duke@435 | 4904 | |
duke@435 | 4905 | //------------------------------xdual------------------------------------------ |
duke@435 | 4906 | // Dual: compute field-by-field dual |
duke@435 | 4907 | const Type *TypeFunc::xdual() const { |
duke@435 | 4908 | return this; |
duke@435 | 4909 | } |
duke@435 | 4910 | |
duke@435 | 4911 | //------------------------------eq--------------------------------------------- |
duke@435 | 4912 | // Structural equality check for Type representations |
duke@435 | 4913 | bool TypeFunc::eq( const Type *t ) const { |
duke@435 | 4914 | const TypeFunc *a = (const TypeFunc*)t; |
duke@435 | 4915 | return _domain == a->_domain && |
duke@435 | 4916 | _range == a->_range; |
duke@435 | 4917 | } |
duke@435 | 4918 | |
duke@435 | 4919 | //------------------------------hash------------------------------------------- |
duke@435 | 4920 | // Type-specific hashing function. |
duke@435 | 4921 | int TypeFunc::hash(void) const { |
duke@435 | 4922 | return (intptr_t)_domain + (intptr_t)_range; |
duke@435 | 4923 | } |
duke@435 | 4924 | |
duke@435 | 4925 | //------------------------------dump2------------------------------------------ |
duke@435 | 4926 | // Dump Function Type |
duke@435 | 4927 | #ifndef PRODUCT |
duke@435 | 4928 | void TypeFunc::dump2( Dict &d, uint depth, outputStream *st ) const { |
duke@435 | 4929 | if( _range->_cnt <= Parms ) |
duke@435 | 4930 | st->print("void"); |
duke@435 | 4931 | else { |
duke@435 | 4932 | uint i; |
duke@435 | 4933 | for (i = Parms; i < _range->_cnt-1; i++) { |
duke@435 | 4934 | _range->field_at(i)->dump2(d,depth,st); |
duke@435 | 4935 | st->print("/"); |
duke@435 | 4936 | } |
duke@435 | 4937 | _range->field_at(i)->dump2(d,depth,st); |
duke@435 | 4938 | } |
duke@435 | 4939 | st->print(" "); |
duke@435 | 4940 | st->print("( "); |
duke@435 | 4941 | if( !depth || d[this] ) { // Check for recursive dump |
duke@435 | 4942 | st->print("...)"); |
duke@435 | 4943 | return; |
duke@435 | 4944 | } |
duke@435 | 4945 | d.Insert((void*)this,(void*)this); // Stop recursion |
duke@435 | 4946 | if (Parms < _domain->_cnt) |
duke@435 | 4947 | _domain->field_at(Parms)->dump2(d,depth-1,st); |
duke@435 | 4948 | for (uint i = Parms+1; i < _domain->_cnt; i++) { |
duke@435 | 4949 | st->print(", "); |
duke@435 | 4950 | _domain->field_at(i)->dump2(d,depth-1,st); |
duke@435 | 4951 | } |
duke@435 | 4952 | st->print(" )"); |
duke@435 | 4953 | } |
duke@435 | 4954 | #endif |
duke@435 | 4955 | |
duke@435 | 4956 | //------------------------------singleton-------------------------------------- |
duke@435 | 4957 | // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple |
duke@435 | 4958 | // constants (Ldi nodes). Singletons are integer, float or double constants |
duke@435 | 4959 | // or a single symbol. |
duke@435 | 4960 | bool TypeFunc::singleton(void) const { |
duke@435 | 4961 | return false; // Never a singleton |
duke@435 | 4962 | } |
duke@435 | 4963 | |
duke@435 | 4964 | bool TypeFunc::empty(void) const { |
duke@435 | 4965 | return false; // Never empty |
duke@435 | 4966 | } |
duke@435 | 4967 | |
duke@435 | 4968 | |
duke@435 | 4969 | BasicType TypeFunc::return_type() const{ |
duke@435 | 4970 | if (range()->cnt() == TypeFunc::Parms) { |
duke@435 | 4971 | return T_VOID; |
duke@435 | 4972 | } |
duke@435 | 4973 | return range()->field_at(TypeFunc::Parms)->basic_type(); |
duke@435 | 4974 | } |