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