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