type.cpp revision 366
0N/A * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 0N/A * published by the Free Software Foundation. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 0N/A * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 0N/A * CA 95054 USA or visit www.sun.com if you need additional information or 0N/A * have any questions. 0N/A// Portions of code courtesy of Clifford Click 0N/A// Optimization - Graph Style 0N/A#
include "incls/_precompiled.incl" 0N/A// Dictionary of types shared among compilations. 0N/A// Array which maps compiler types to Basic Types 0N/A T_ADDRESS,
// AnyPtr // shows up in factory methods for NULL_PTR 63N/A// Map ideal registers (machine types) to ideal types 63N/A// Map basic types to canonical Type* pointers. 0N/A// Map basic types to constant-zero Types. 0N/A// Map basic types to array-body alias types. 63N/A//============================================================================= 0N/A// Convenience common pre-built types. 0N/A//------------------------------get_const_type--------------------------- 0N/A//---------------------------array_element_basic_type--------------------------------- 0N/A// Mapping to the array element's basic type. 0N/A//---------------------------get_typeflow_type--------------------------------- 0N/A// Import a type produced by ciTypeFlow. 0N/A // The ciTypeFlow pass pushes a long, then the half. 0N/A // The ciTypeFlow pass pushes double, then the half. 0N/A // Our convention is the same. 0N/A // make sure we did not mix up the cases: 0N/A//------------------------------make------------------------------------------- 0N/A// Create a simple Type, with default empty symbol sets. Then hashcons it 0N/A// and look for an existing copy in the type dictionary. 0N/A//------------------------------cmp-------------------------------------------- 0N/A return 1;
// Missed badly 0N/A//------------------------------hash------------------------------------------- 73N/A//--------------------------Initialize_shared---------------------------------- 73N/A // This method does not need to be locked because the first system 73N/A // compilations (stub compilations) occur serially. If they are 73N/A // changed to proceed in parallel, then this section will need 73N/A // Make shared pre-built types. 73N/A // CmpL is overloaded both as the bytecode computation returning 73N/A // a trinary (-1,0,+1) integer result AND as an efficient long 73N/A // compare returning optimizer ideal-type flags. 73N/A // There is no shared klass for Object[]. See note in TypeAryPtr::klass(). 73N/A // Nobody should ask _array_body_type[T_NARROWOOP]. Use NULL as assert. 73N/A // get_zero_type() should not happen for T_CONFLICT 73N/A // Restore working type arena. 73N/A//------------------------------Initialize------------------------------------- 73N/A // Create the hash-cons'ing dictionary with top-level storage allocation 73N/A // Transfer the shared types. 73N/A//------------------------------hashcons--------------------------------------- 73N/A// Do the hash-cons trick. If the Type already exists in the type table, 73N/A// delete the current Type and return the existing Type. Otherwise stick the 73N/A// current Type in the Type table. 73N/A // Look up the Type in the Type dictionary 73N/A if(
old !=
this )
// Yes, this guy is not the pre-existing? 73N/A delete this;
// Yes, Nuke this guy 73N/A return old;
// Return pre-existing 73N/A // Every type has a dual (to make my lattice symmetric). 73N/A // Since we just discovered a new Type, compute its dual right now. 73N/A // New Type, insert into Type table 73N/A return this;
// Return new Type 73N/A//------------------------------eq--------------------------------------------- 73N/A// Structural equality check for Type representations 73N/A return true;
// Nothing else can go wrong 73N/A//------------------------------hash------------------------------------------- 73N/A// Type-specific hashing function. 73N/A//------------------------------is_finite-------------------------------------- 73N/A// Has a finite value 73N/A//------------------------------is_nan----------------------------------------- 73N/A// Is not a number (NaN) 73N/A//------------------------------meet------------------------------------------- 73N/A// Compute the MEET of two types. NOT virtual. It enforces that meet is 73N/A// commutative and the lattice is symmetric. 73N/A // Interface meet Oop is Not Symmetric: 73N/A // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull 73N/A//------------------------------xmeet------------------------------------------ 73N/A// Compute the MEET of two types. It returns a new Type object. 73N/A // Perform a fast test for common case; meeting the same types together. 73N/A if(
this == t )
return this;
// Meeting same type-rep? 73N/A // Meeting TOP with anything? 73N/A // Meeting BOTTOM with anything? 73N/A // Current "this->_base" is one of: Bad, Multi, Control, Top, 73N/A // Abio, Abstore, Floatxxx, Doublexxx, Bottom, lastype. 73N/A switch (t->
base()) {
// Switch on original type 73N/A // Cut in half the number of cases I must handle. Only need cases for when 73N/A // the given enum "t->type" is less than or equal to the local enum "type". 73N/A default:
// Bogus type not in lattice 124N/A // These next few cases must match exactly or it is a compile-time error. 124N/A case Abio:
// State of world outside of program 73N/A // The type is unchanged 73N/A//-----------------------------filter------------------------------------------ 73N/A//------------------------------xdual------------------------------------------ 73N/A// Compute dual right now. 73N/A Bad,
// NarrowOop - handled in v-call 73N/A Bad,
// AnyPtr - handled in v-call 73N/A Bad,
// RawPtr - handled in v-call 73N/A Bad,
// OopPtr - handled in v-call 73N/A Bad,
// InstPtr - handled in v-call 73N/A Bad,
// AryPtr - handled in v-call 73N/A Bad,
// KlassPtr - handled in v-call 73N/A Bad,
// Function - handled in v-call 73N/A // Note: the base() accessor asserts the sanity of _base. 73N/A//------------------------------has_memory------------------------------------- 73N/A//------------------------------dump2------------------------------------------ 73N/A//------------------------------dump------------------------------------------- 73N/A//------------------------------data------------------------------------------- 73N/A "bad",
"control",
"top",
"int:",
"long:",
"half",
"narrowoop:",
73N/A "tuple:",
"aryptr",
73N/A "anyptr:",
"rawptr:",
"java:",
"inst:",
"ary:",
"klass:",
73N/A "func",
"abIO",
"return_address",
"memory",
73N/A "float_top",
"ftcon:",
"float",
73N/A "double_top",
"dblcon:",
"double",
73N/A//------------------------------singleton-------------------------------------- 73N/A// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple 73N/A// constants (Ldi nodes). Singletons are integer, float or double constants. 73N/A//------------------------------empty------------------------------------------ 73N/A// TRUE if Type is a type with no values, FALSE otherwise. 73N/A return false;
// never a singleton, therefore never empty 73N/A//------------------------------dump_stats------------------------------------- 73N/A// Dump collected statistics to stderr 73N/A//------------------------------typerr----------------------------------------- 73N/A//------------------------------isa_oop_ptr------------------------------------ 73N/A// Return true if type is an oop pointer type. False for raw pointers. 73N/A 0,0,0,0,0,0,0
/*narrowoop*/,0
/*tuple*/, 0
/*ary*/,
73N/A 0
/*anyptr*/,0
/*rawptr*/,
1/*OopPtr*/,
1/*InstPtr*/,
1/*AryPtr*/,
1/*KlassPtr*/,
73N/A 0
/*func*/,0,0
/*return_address*/,0,
73N/A /*floats*/0,0,0,
/*doubles*/0,0,0,
73N/A//------------------------------dump_stats------------------------------------- 73N/A// // Check that arrays match type enum 73N/A // Check that arrays match enumeration 73N/A // assert( PhiNode::tbl [Type::lastype - 1] == NULL, "did not update array"); 73N/A//============================================================================= 73N/A// Convenience common pre-built types. 73N/A//------------------------------make------------------------------------------- 73N/A// Create a float constant 73N/A//------------------------------meet------------------------------------------- 73N/A// Compute the MEET of two types. It returns a new Type object. 73N/A // Perform a fast test for common case; meeting the same types together. 73N/A if(
this == t )
return this;
// Meeting same type-rep? 73N/A // Current "this->_base" is FloatCon 73N/A switch (t->
base()) {
// Switch on original type 73N/A case AnyPtr:
// Mixing with oops happens when javac 0N/A default:
// All else is a mistake 0N/A // must compare bitwise as positive zero, negative zero and NaN have 0N/A // all the same representation in C++ 0N/A break;
// Return the float constant 0N/A return this;
// Return the float constant 0N/A//------------------------------xdual------------------------------------------ 113N/A//------------------------------eq--------------------------------------------- 0N/A// Structural equality check for Type representations 0N/A // One or both are NANs. If both are NANs return true, else false. 0N/A // (NaN is impossible at this point, since it is not equal even to itself) 0N/A // difference between positive and negative zero 0N/A//------------------------------hash------------------------------------------- 0N/A// Type-specific hashing function. 0N/A//------------------------------is_finite-------------------------------------- 0N/A// Has a finite value 0N/A//------------------------------is_nan----------------------------------------- 0N/A// Is not a number (NaN) 0N/A//------------------------------dump2------------------------------------------ 0N/A// Dump float constant Type 0N/A//------------------------------singleton-------------------------------------- 0N/A// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple 0N/A// constants (Ldi nodes). Singletons are integer, float or double constants 0N/A// or a single symbol. 0N/A return true;
// Always a singleton 0N/A return false;
// always exactly a singleton 0N/A//============================================================================= 0N/A// Convenience common pre-built types. 0N/A//------------------------------make------------------------------------------- 0N/A//------------------------------meet------------------------------------------- 0N/A// Compute the MEET of two types. It returns a new Type object. 0N/A // Perform a fast test for common case; meeting the same types together. 0N/A if(
this == t )
return this;
// Meeting same type-rep? 73N/A // Current "this->_base" is DoubleCon 73N/A switch (t->
base()) {
// Switch on original type 73N/A case AnyPtr:
// Mixing with oops happens when javac 0N/A default:
// All else is a mistake 0N/A return this;
// Return the double constant 342N/A//------------------------------xdual------------------------------------------ 342N/A//------------------------------eq--------------------------------------------- 0N/A// Structural equality check for Type representations 0N/A // One or both are NANs. If both are NANs return true, else false. 0N/A // (NaN is impossible at this point, since it is not equal even to itself) 0N/A // difference between positive and negative zero 0N/A//------------------------------hash------------------------------------------- 0N/A// Type-specific hashing function. 0N/A//------------------------------is_finite-------------------------------------- 0N/A// Has a finite value 342N/A//------------------------------is_nan----------------------------------------- 342N/A// Is not a number (NaN) 342N/A//------------------------------dump2------------------------------------------ 342N/A// Dump double constant Type 0N/A//------------------------------singleton-------------------------------------- 0N/A// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple 0N/A// constants (Ldi nodes). Singletons are integer, float or double constants 0N/A// or a single symbol. 0N/A return true;
// Always a singleton 0N/A return false;
// always exactly a singleton 0N/A//============================================================================= 0N/A// Convience common pre-built types. 0N/A//------------------------------TypeInt---------------------------------------- 0N/A//------------------------------make------------------------------------------- 0N/A // Certain normalizations keep us sane when comparing types. 0N/A // The 'SMALLINT' covers constants and also CC and its relatives. 0N/A//------------------------------meet------------------------------------------- 0N/A// Compute the MEET of two types. It returns a new Type representation object 0N/A// with reference count equal to the number of Types pointing at it. 0N/A// Caller should wrap a Types around it. 0N/A // Perform a fast test for common case; meeting the same types together. 0N/A if(
this == t )
return this;
// Meeting same type? 0N/A // Currently "this->_base" is a TypeInt 0N/A switch (t->
base()) {
// Switch on original type 0N/A case AnyPtr:
// Mixing with oops happens when javac 0N/A default:
// All else is a mistake 0N/A // Expand covered set 0N/A // (Avoid TypeInt::make, to avoid the argument normalizations it enforces.) 0N/A//------------------------------xdual------------------------------------------ 0N/A// Dual: reverse hi & lo; flip widen 0N/A//------------------------------widen------------------------------------------ 0N/A// Only happens for optimistic top-down optimizations. 0N/A // Coming from TOP or such; no widening 0N/A // If new guy is equal to old guy, no widening 0N/A // If new guy contains old, then we widened 0N/A // If new guy is already wider than old, no widening 0N/A // If old guy was a constant, do not bother 0N/A // Now widen new guy. 0N/A // Check for widening too far 0N/A // If neither endpoint is extremal yet, push out the endpoint 0N/A // which is closer to its respective limit. 0N/A if (
_lo >= 0 ||
// easy common case 0N/A // Try to widen to an unsigned range type of 31 bits: 0N/A // Returned widened new guy 0N/A // If old guy contains new, then we probably widened too far & dropped to 0N/A // bottom. Return the wider fellow. 0N/A //fatal("Integer value range is not subset"); 0N/A//------------------------------narrow--------------------------------------- 0N/A// Only happens for pessimistic optimizations. 0N/A if (
_lo >=
_hi)
return this;
// already narrow enough 0N/A // If new guy is equal to old guy, no narrowing 0N/A // If old guy was maximum range, allow the narrowing 0N/A return this;
// doesn't narrow; pretty wierd 0N/A // The new type narrows the old type, so look for a "death march". 0N/A // See comments on PhaseTransform::saturate. 0N/A // Use the new type only if the range shrinks a lot. 0N/A // We do not want the optimizer computing 2^31 point by point. 0N/A//-----------------------------filter------------------------------------------ 0N/A // Do not allow the value of kill->_widen to affect the outcome. 0N/A // The widen bits must be allowed to run freely through the graph. 0N/A//------------------------------eq--------------------------------------------- 0N/A// Structural equality check for Type representations 0N/A//------------------------------hash------------------------------------------- 0N/A// Type-specific hashing function. 0N/A//------------------------------is_finite-------------------------------------- 0N/A// Has a finite value 0N/A//------------------------------dump2------------------------------------------ 0N/A//------------------------------singleton-------------------------------------- 0N/A// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple 0N/A//============================================================================= 0N/A// Convenience common pre-built types. 0N/A//------------------------------TypeLong--------------------------------------- 0N/A//------------------------------make------------------------------------------- 0N/A // Certain normalizations keep us sane when comparing types. 0N/A // The '1' covers constants. 113N/A//------------------------------meet------------------------------------------- 0N/A// Compute the MEET of two types. It returns a new Type representation object 0N/A// with reference count equal to the number of Types pointing at it. 0N/A// Caller should wrap a Types around it. 0N/A // Perform a fast test for common case; meeting the same types together. 0N/A if(
this == t )
return this;
// Meeting same type? 113N/A // Currently "this->_base" is a TypeLong 0N/A switch (t->
base()) {
// Switch on original type 0N/A case AnyPtr:
// Mixing with oops happens when javac 0N/A default:
// All else is a mistake 0N/A // Expand covered set 0N/A // (Avoid TypeLong::make, to avoid the argument normalizations it enforces.) 0N/A//------------------------------xdual------------------------------------------ 0N/A// Dual: reverse hi & lo; flip widen 0N/A//------------------------------widen------------------------------------------ 0N/A// Only happens for optimistic top-down optimizations. 0N/A // Coming from TOP or such; no widening 0N/A // If new guy is equal to old guy, no widening 0N/A // If new guy contains old, then we widened 0N/A // If new guy is already wider than old, no widening 0N/A // If old guy was a constant, do not bother 0N/A // Now widen new guy. 0N/A // Check for widening too far 0N/A // If neither endpoint is extremal yet, push out the endpoint 0N/A // which is closer to its respective limit. 0N/A if (
_lo >= 0 ||
// easy common case 0N/A // Try to widen to an unsigned range type of 32/63 bits: 0N/A // Returned widened new guy 0N/A // If old guy contains new, then we probably widened too far & dropped to 0N/A // bottom. Return the wider fellow. 0N/A // fatal("Long value range is not subset"); 0N/A//------------------------------narrow---------------------------------------- 0N/A// Only happens for pessimistic optimizations. 0N/A if (
_lo >=
_hi)
return this;
// already narrow enough 0N/A // If new guy is equal to old guy, no narrowing 0N/A // If old guy was maximum range, allow the narrowing 0N/A return this;
// doesn't narrow; pretty wierd 0N/A // The new type narrows the old type, so look for a "death march". 0N/A // See comments on PhaseTransform::saturate. 0N/A // Use the new type only if the range shrinks a lot. 0N/A // We do not want the optimizer computing 2^31 point by point. 0N/A//-----------------------------filter------------------------------------------ 0N/A // Do not allow the value of kill->_widen to affect the outcome. 0N/A // The widen bits must be allowed to run freely through the graph. 0N/A//------------------------------eq--------------------------------------------- 0N/A// Structural equality check for Type representations 0N/A//------------------------------hash------------------------------------------- 0N/A// Type-specific hashing function. 0N/A//------------------------------is_finite-------------------------------------- 0N/A// Has a finite value 0N/A//------------------------------dump2------------------------------------------ 66N/A//------------------------------singleton-------------------------------------- 66N/A// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple 0N/A//============================================================================= 0N/A// Convenience common pre-built types. 66N/A//------------------------------make------------------------------------------- 66N/A// Make a TypeTuple from the range of a method signature 0N/A// Make a TypeTuple from the domain of a method signature 0N/A // Use get_const_type here because it respects UseUniqueSubclasses: 0N/A//------------------------------fields----------------------------------------- 0N/A// Subroutine call type with space allocated for argument types 0N/A//------------------------------meet------------------------------------------- 0N/A// Compute the MEET of two types. It returns a new Type object. 0N/A // Perform a fast test for common case; meeting the same types together. 0N/A if(
this == t )
return this;
// Meeting same type-rep? 0N/A // Current "this->_base" is Tuple 0N/A switch (t->
base()) {
// switch on original type 0N/A default:
// All else is a mistake 0N/A return this;
// Return the double constant 0N/A//------------------------------xdual------------------------------------------ 0N/A// Dual: compute field-by-field dual 73N/A//------------------------------eq--------------------------------------------- 73N/A// Structural equality check for Type representations 73N/A return false;
// Missed 73N/A//------------------------------hash------------------------------------------- 73N/A// Type-specific hashing function. 73N/A//------------------------------dump2------------------------------------------ 73N/A// Dump signature Type 73N/A if( !
depth || d[
this] ) {
// Check for recursive print 73N/A d.
Insert((
void*)
this, (
void*)
this);
// Stop recursion 0N/A//------------------------------singleton-------------------------------------- 0N/A// TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple 0N/A// constants (Ldi nodes). Singletons are integer, float or double constants 0N/A// or a single symbol. 0N/A return false;
// Never a singleton 0N/A//============================================================================= 113N/A// Convenience common pre-built types. 0N/A // Certain normalizations keep us sane when comparing types. 0N/A // We do not want arrayOop variables to differ only by the wideness // of their index types. Pick minimum wideness, since that is the // forced wideness of small ranges anyway. //------------------------------make------------------------------------------- //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type-rep? // Current "this->_base" is Ary switch (t->
base()) {
// switch on original type case Bottom:
// Ye Olde Default default:
// All else is a mistake case Array: {
// Meeting 2 arrays? return this;
// Return the double constant //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------dump2------------------------------------------ //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // constants (Ldi nodes). Singletons are integer, float or double constants return false;
// Never a singleton //--------------------------ary_must_be_exact---------------------------------- // This logic looks at the element type of an array, and returns true // if the element type is either a primitive or a final instance class. // In such cases, an array built on this ary must have no subclasses. if (
_elem ==
BOTTOM)
return false;
// general array not exact if (
_elem ==
TOP )
return false;
// inverted general array not exact if (!
toop)
return true;
// a primitive type, like int if (
tklass ==
NULL)
return false;
// unloaded class //============================================================================= // Convenience common pre-built types. //------------------------------meet------------------------------------------- // Meet over the PTR enum // TopPTR, AnyNull, Constant, Null, NotNull, BotPTR, //------------------------------make------------------------------------------- //------------------------------cast_to_ptr_type------------------------------- //------------------------------get_con---------------------------------------- //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type-rep? // Current "this->_base" is AnyPtr switch (t->
base()) {
// switch on original type case Int:
// Mixing ints & oops happens when javac case Long:
// reuses local variables case Bottom:
// Ye Olde Default case AnyPtr: {
// Meeting to AnyPtrs case RawPtr:
// For these, flip the call around to cut down case InstPtr:
// on the cases I have to handle. return t->
xmeet(
this);
// Call in reverse direction default:
// All else is a mistake //------------------------------meet_offset------------------------------------ // Either is 'TOP' offset? Return the other offset! // If either is different, return 'BOTTOM' offset //------------------------------dual_offset------------------------------------ return _offset;
// Map everything else into self //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual //------------------------------xadd_offset------------------------------------ // Adding to 'TOP' offset? Return 'TOP'! // Adding to 'BOTTOM' offset? Return 'BOTTOM'! // Addition overflows or "accidentally" equals to OffsetTop? Return 'BOTTOM'! // assert( _offset >= 0 && _offset+offset >= 0, "" ); // It is possible to construct a negative offset during PhaseCCP return (
int)
offset;
// Sum valid offsets //------------------------------add_offset------------------------------------- //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------dump2------------------------------------------ "TopPTR",
"AnyNull",
"Constant",
"NULL",
"NotNull",
"BotPTR" //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // TopPTR, Null, AnyNull, Constant are all singletons //============================================================================= // Convenience common pre-built types. //------------------------------make------------------------------------------- //------------------------------cast_to_ptr_type------------------------------- //------------------------------get_con---------------------------------------- //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type-rep? // Current "this->_base" is RawPtr switch( t->
base() ) {
// switch on original type case Bottom:
// Ye Olde Default case AnyPtr:
// Meeting to AnyPtrs if(
ptr ==
Constant ) {
// Cannot be equal constants, so... default:
// All else is a mistake // Found an AnyPtr type vs self-RawPtr type //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual //------------------------------add_offset------------------------------------- if(
offset == 0 )
return this;
// No change return NULL;
// Lint noise //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------dump2------------------------------------------ //============================================================================= // Convenience common pre-built type. //------------------------------TypeOopPtr------------------------------------- // Special hidden fields from the Class. // Perm objects don't use compressed references, except for // static fields which are currently compressed. }
else {
// exclude unsafe ops // Field which contains a compressed oop references. // Compile::find_alias_type() cast exactness on all types to verify // that it does not affect alias type. // Type for the copy start in LibraryCallKit::inline_native_clone(). //------------------------------make------------------------------------------- //------------------------------cast_to_ptr_type------------------------------- //-----------------------------cast_to_instance_id---------------------------- // There are no instances of a general oop. // Return self unchanged. //-----------------------------cast_to_exactness------------------------------- // There is no such thing as an exact general oop. // Return self unchanged. //------------------------------as_klass_type---------------------------------- // Return the klass type corresponding to this instance or array type. // It is the type that is loaded from an object of this type. //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type-rep? // Current "this->_base" is OopPtr switch (t->
base()) {
// switch on original type case Int:
// Mixing ints & oops happens when javac case Long:
// reuses local variables case Bottom:
// Ye Olde Default default:
// All else is a mistake // Found an AnyPtr type vs self-OopPtr type case OopPtr: {
// Meeting to other OopPtrs case InstPtr:
// For these, flip the call around to cut down case KlassPtr:
// on the cases I have to handle. return t->
xmeet(
this);
// Call in reverse direction return this;
// Return the double constant //------------------------------xdual------------------------------------------ // Dual of a pure heap pointer. No relevant klass or oop information. //--------------------------make_from_klass_common----------------------------- // Computes the element-type given a klass. // Element is an instance // Try to set klass_is_exact. // Add a dependence; if concrete subclass added we need to recompile // Element is an object array. Recursively call ourself. // We used to pass NotNull in here, asserting that the sub-arrays // are all not-null. This is not true in generally, as code can // slam NULLs down in the subarrays. // Element is an typeArray // We used to pass NotNull in here, asserting that the array pointer // is not-null. That was not true in general. //------------------------------make_from_constant----------------------------- // Make a java pointer from an oop constant // Treat much like a typeArray of bytes, like below, but fake the type... // Element is an instance // %%% remove this restriction by rewriting non-perm ConPNodes in a later phase // Element is an object array. Recursively call ourself. // We used to pass NotNull in here, asserting that the sub-arrays // are all not-null. This is not true in generally, as code can // slam NULLs down in the subarrays. // %%% remove this restriction by rewriting non-perm ConPNodes in a later phase // Element is an typeArray // We used to pass NotNull in here, asserting that the array pointer // is not-null. That was not true in general. // %%% remove this restriction by rewriting non-perm ConPNodes in a later phase //------------------------------get_con---------------------------------------- // After being ported to the compiler interface, the compiler no longer // directly manipulates the addresses of oops. Rather, it only has a pointer // to a handle at compile time. This handle is embedded in the generated // code and dereferenced at the time the nmethod is made. Until that time, // it is not reasonable to do arithmetic with the addresses of oops (we don't // have access to the addresses!). This does not seem to currently happen, // but this assertion here is to help prevent its occurrance. tty->
print_cr(
"Found oop constant with non-zero offset");
//-----------------------------filter------------------------------------------ // Do not allow interface-vs.-noninterface joins to collapse to top. // Check for evil case of 'this' being a class and 'kills' expecting an // interface. This can happen because the bytecodes do not contain // enough type info to distinguish a Java-level interface variable // from a Java-level object variable. If we meet 2 classes which // both implement interface I, but their meet is at 'j/l/O' which // doesn't implement I, we have no way to tell if the result should // be 'I' or 'j/l/O'. Thus we'll pick 'j/l/O'. If this then flows // into a Phi which "knows" it's an Interface type we'll have to return kills;
// Uplift to interface return Type::
TOP;
// Canonical empty value // If we have an interface-typed Phi or cast and we narrow to a class type, // the join should report back the class. However, if we have a J/L/Object // class-typed Phi and an interface flows in, it's possible that the meet & // join report an interface back out. This isn't possible but happens // because the type system doesn't interact well with interfaces. // Happens in a CTW of rt.jar, 320-341, no extra flags //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------dump2------------------------------------------ //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // detune optimizer to not generate constant oop + constant offset as a constant! // TopPTR, Null, AnyNull, Constant are all singletons //------------------------------add_offset------------------------------------- //------------------------------meet_instance_id-------------------------------- // Either is 'TOP' instance? Return the other instance! // If either is different, return 'BOTTOM' instance //------------------------------dual_instance_id-------------------------------- //============================================================================= // Convenience common pre-built types. //------------------------------TypeInstPtr------------------------------------- "cannot have constants with non-loaded klass");
//------------------------------make------------------------------------------- // Either const_oop() is NULL or else ptr is Constant "constant pointers must have a value supplied" );
// Note: This case includes meta-object constants, such as methods. //------------------------------cast_to_ptr_type------------------------------- // Reconstruct _sig info here since not a problem with later lazy // construction, _sig will show up on demand. //-----------------------------cast_to_exactness------------------------------- //-----------------------------cast_to_instance_id---------------------------- //------------------------------xmeet_unloaded--------------------------------- // Compute the MEET of two InstPtrs when at least one is unloaded. // Assume classes are different since called after check for same name/class-loader // Object | TOP | AnyNull | Constant | NotNull | BOTTOM | // =================================================================== // TOP | ..........................Unloaded......................| // AnyNull | U-AN |................Unloaded......................| // Constant | ... O-NN .................................. | O-BOT | // NotNull | ... O-NN .................................. | O-BOT | // BOTTOM | ........................Object-BOTTOM ..................| // Both are unloaded, not the same class, not Object // Or meet unloaded with a different loaded class, not java/lang/Object //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type-rep? // Current "this->_base" is Pointer switch (t->
base()) {
// switch on original type case Int:
// Mixing ints & oops happens when javac case Long:
// reuses local variables case Bottom:
// Ye Olde Default default:
// All else is a mistake case AryPtr: {
// All arrays inherit from Object class case AnyNull:
// Fall 'down' to dual of object klass // cannot subclass, so the meet has to fall badly below the centerline case BotPTR:
// Fall down to object klass // LCA is object_klass, but if we subclass from the top we can do better // If 'this' (InstPtr) is above the centerline and it is Object class // then we can subclass in the Java class heirarchy. // that is, tp's array type is a subtype of my klass // The other case cannot happen, since I cannot be a subtype of an array. // The meet falls down to Object class below centerline. case OopPtr: {
// Meeting to OopPtrs // Found a OopPtr type vs self-InstPtr type case AnyPtr: {
// Meeting to AnyPtrs // Found an AnyPtr type vs self-InstPtr type // else fall through to AnyNull B-con A-con C-con } constants; not comparable across classes // Found an InstPtr sub-type vs self-InstPtr type // Check for easy case; klasses are equal (and perhaps not loaded!) // If we have constants, then we created oops so classes are loaded // and we can handle the constants further down. This case handles // both-not-loaded or both-loaded classes // Classes require inspection in the Java klass hierarchy. Must be loaded. // One of these classes has not been loaded // Handle mixing oops and interfaces first. // because we need a bottom for the interface hierarchy. // See if the oop subtypes (implements) interface. // Oop indeed subtypes. Now keep oop or interface depending // on whether we are both above the centerline or either is // below the centerline. If we are on the centerline // (e.g., Constant vs. AnyNull interface), use the constant. // If we are keeping this_klass, keep its exactness too. }
else {
// Does not implement, fall to Object // Oop does not implement interface, so mixing falls to Object // just like the verifier does (if both are above the // centerline fall to interface) // Watch out for Constant vs. AnyNull interface. // Find out which constant. // Either oop vs oop or interface vs interface or interface vs Object // !!! Here's how the symmetry requirement breaks down into invariants: // If we split one up & one down AND they subtype, take the down man. // If we split one up & one down AND they do NOT subtype, "fall hard". // If both are up and they subtype, take the subtype class. // If both are up and they do NOT subtype, "fall hard". // If both are down and they subtype, take the supertype class. // If both are down and they do NOT subtype, "fall hard". // Constants treated as down. // Now, reorder the above list; observe that both-down+subtype is also // "fall hard"; "fall hard" becomes the default case: // If we split one up & one down AND they subtype, take the down man. // If both are up and they subtype, take the subtype class. // If both are down and they subtype, "fall hard". // If both are down and they do NOT subtype, "fall hard". // If both are up and they do NOT subtype, "fall hard". // If we split one up & one down AND they do NOT subtype, "fall hard". // If a proper subtype is exact, and we return it, we return it exactly. // If a proper supertype is exact, there can be no subtyping relationship! // If both types are equal to the subtype, exactness is and-ed below the // centerline and or-ed above it. (N.B. Constants are always exact.) // Check for classes now being equal // If the klasses are equal, the constants may still differ. Fall to // NotNull if they do (neither constant is NULL; that is a special case }
// Else classes are not equal // Since klasses are different, we require a LCA in the Java // class hierarchy - which means we have to fall to at least NotNull. // Now we find the LCA of Java classes return this;
// Return the double constant //------------------------java_mirror_type-------------------------------------- // must be a singleton type // must be of type java.lang.Class //------------------------------xdual------------------------------------------ // Dual: do NOT dual on klasses. This means I do NOT understand the Java // inheritence mechanism. //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------dump2------------------------------------------ // Print the name of the klass. // TO DO: Make CI print the hex address of the underlying oop. if(
_offset ) {
// Dump offset, if any //------------------------------add_offset------------------------------------- //============================================================================= // Convenience common pre-built types. //------------------------------make------------------------------------------- "integral arrays must be pre-equipped with a class");
//------------------------------make------------------------------------------- "integral arrays must be pre-equipped with a class");
//------------------------------cast_to_ptr_type------------------------------- //-----------------------------cast_to_exactness------------------------------- //-----------------------------cast_to_instance_id---------------------------- //-----------------------------narrow_size_type------------------------------- // Local cache for arrayOopDesc::max_array_length(etype), // which is kind of slow (and cached elsewhere by other users). etype =
T_BYTE;
// will produce conservatively high value // Narrow the given size type to the index range for the given array base type. // Return NULL if the resulting int type becomes empty. //if (index_not_size) --max_hi; // type of a valid array index, FTR // Negative length arrays will produce weird intermediate dead fath-path code //-------------------------------cast_to_size---------------------------------- //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type-rep? // Current "this->_base" is Pointer switch (t->
base()) {
// switch on original type // Mixing ints & oops happens when javac reuses local variables case Bottom:
// Ye Olde Default default:
// All else is a mistake case OopPtr: {
// Meeting to OopPtrs // Found a OopPtr type vs self-AryPtr type case AnyPtr: {
// Meeting two AnyPtrs // Found an AnyPtr type vs self-AryPtr type // else fall through to AnyNull case AryPtr: {
// Meeting 2 references? // Integral array element types have irrelevant lattice relations. // It is the klass that determines array layout, not the element type. // Something like byte[int+] meets char[int+]. // This must fall to bottom, not (int[-128..65535])[int+]. // Compute new klass on demand, do not use tap->_klass // Compute new klass on demand, do not use tap->_klass // All arrays inherit from Object class case AnyNull:
// Fall 'down' to dual of object klass // cannot subclass, so the meet has to fall badly below the centerline case BotPTR:
// Fall down to object klass // LCA is object_klass, but if we subclass from the top we can do better // If 'tp' is above the centerline and it is Object class // then we can subclass in the Java class heirarchy. // that is, my array type is a subtype of 'tp' klass // The other case cannot happen, since t cannot be a subtype of an array. // The meet falls down to Object class below centerline. return this;
// Lint noise //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual //------------------------------dump2------------------------------------------ //------------------------------add_offset------------------------------------- //============================================================================= //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------xmeet------------------------------------------ // Compute the MEET of two types. It returns a new Type object. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type-rep? // Current "this->_base" is OopPtr switch (t->
base()) {
// switch on original type case Int:
// Mixing ints & oops happens when javac case Long:
// reuses local variables case Bottom:
// Ye Olde Default default:
// All else is a mistake return Type::
TOP;
// Canonical empty value return Type::
TOP;
// Canonical empty value //============================================================================= // Convenience common pre-built types. // Not-null object klass or below //------------------------------TypeKlasPtr------------------------------------ //------------------------------make------------------------------------------- // ptr to klass 'k', if Constant, or possibly to a sub-klass if not a Constant //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------klass------------------------------------------ // Return the defining klass for this class if(
_klass )
return _klass;
// Return cached value, if possible // Oops, need to compute _klass and cache it // Compute array klass from element klass // Compute array klass from element klass // If element type is something like bottom[], k_elem will be null. // element type of Bottom occurs from meet of basic type // and object; Top occurs when doing join on Bottom. // Cannot compute array klass directly from basic type, // since subtypes of TypeInt all have basic type T_INT. "integral arrays must be pre-equipped with a class");
// Compute array klass directly from basic type // The _klass field acts as a cache of the underlying // ciKlass for this array type. In order to set the field, // we need to cast away const-ness. // IMPORTANT NOTE: we *never* set the _klass field for the // type TypeAryPtr::OOPS. This Type is shared between all // active compilations. However, the ciKlass which represents // this Type is *not* shared between compilations, so caching // this value would result in fetching a dangling pointer. // Recomputing the underlying ciKlass for each request is // a bit less efficient than caching, but calls to // TypeAryPtr::OOPS->klass() are not common enough to matter. //------------------------------add_offset------------------------------------- // Access internals of klass object //------------------------------cast_to_ptr_type------------------------------- //-----------------------------cast_to_exactness------------------------------- //-----------------------------as_instance_type-------------------------------- // Corresponding type for an instance of the given class. // It will be NotNull, and exact if and only if the klass type is exact. //return TypeInstPtr::make(TypePtr::NotNull, k, xk, NULL, 0); //------------------------------xmeet------------------------------------------ // Compute the MEET of two types, return a new Type object. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type-rep? // Current "this->_base" is Pointer switch (t->
base()) {
// switch on original type case Int:
// Mixing ints & oops happens when javac case Long:
// reuses local variables case Bottom:
// Ye Olde Default default:
// All else is a mistake case OopPtr: {
// Meeting to OopPtrs // Found a OopPtr type vs self-KlassPtr type case AnyPtr: {
// Meeting to AnyPtrs // Found an AnyPtr type vs self-KlassPtr type case AryPtr:
// Meet with AryPtr // B-con A-con C-con } constants; not comparable across classes case KlassPtr: {
// Meet two KlassPtr types // Check for easy case; klasses are equal (and perhaps not loaded!) // If we have constants, then we created oops so classes are loaded // and we can handle the constants further down. This case handles // Classes require inspection in the Java klass hierarchy. Must be loaded. // If 'this' type is above the centerline and is a superclass of the // other, we can treat 'this' as having the same type as the other. // If 'tinst' type is above the centerline and is a superclass of the // other, we can treat 'tinst' as having the same type as the other. // Check for classes now being equal // If the klasses are equal, the constants may still differ. Fall to // NotNull if they do (neither constant is NULL; that is a special case }
// Else classes are not equal // Since klasses are different, we require the LCA in the Java // class hierarchy - which means we have to fall to at least NotNull. // Now we find the LCA of Java classes }
// End of case KlassPtr return this;
// Return the double constant //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual //------------------------------dump2------------------------------------------ if(
_offset ) {
// Dump offset, if any //============================================================================= // Convenience common pre-built types. //------------------------------make------------------------------------------- //------------------------------make------------------------------------------- if (
tf !=
NULL)
return tf;
// The hit rate here is almost 50%. //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type object. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type-rep? // Current "this->_base" is Func switch (t->
base()) {
// switch on original type case Bottom:
// Ye Olde Default default:
// All else is a mistake return this;
// Return the double constant //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------dump2------------------------------------------ if( !
depth || d[
this] ) {
// Check for recursive dump d.
Insert((
void*)
this,(
void*)
this);
// Stop recursion//------------------------------print_flattened-------------------------------- // Print a 'flattened' signature "bad",
"control",
"top",
"int",
"long",
"_",
"narrowoop",
"ptr",
"rawptr",
"ptr",
"ptr",
"ptr",
"ptr",
"func",
"abIO",
"return_address",
"mem",
"float_top",
"ftcon:",
"flt",
"double_top",
"dblcon:",
"dbl",
//------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // constants (Ldi nodes). Singletons are integer, float or double constants return false;
// Never a singleton return false;
// Never empty