type.cpp revision 3848
553N/A * Copyright (c) 1997, 2012, Oracle and/or its affiliates. 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 553N/A * published by the Free Software Foundation. 553N/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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 139N/A// Portions of code courtesy of Clifford Click 139N/A// Optimization - Graph Style 0N/A// Dictionary of types shared among compilations. 139N/A// Array which maps compiler types to Basic Types 0N/A T_ADDRESS,
// AnyPtr // shows up in factory methods for NULL_PTR 0N/A// Map ideal registers (machine types) to ideal types 0N/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. 0N/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------------------------------------------- 0N/A//--------------------------Initialize_shared---------------------------------- 0N/A // This method does not need to be locked because the first system 0N/A // compilations (stub compilations) occur serially. If they are 0N/A // changed to proceed in parallel, then this section will need 0N/A // Make shared pre-built types. 0N/A // CmpL is overloaded both as the bytecode computation returning 0N/A // a trinary (-1,0,+1) integer result AND as an efficient long 0N/A // compare returning optimizer ideal-type flags. // There is no shared klass for Object[]. See note in TypeAryPtr::klass(). // Nobody should ask _array_body_type[T_NARROWOOP]. Use NULL as assert. // get_zero_type() should not happen for T_CONFLICT // Vector predefined types, it needs initialized _const_basic_type[]. // Restore working type arena. //------------------------------Initialize------------------------------------- // Create the hash-cons'ing dictionary with top-level storage allocation // Transfer the shared types. tdic->
Insert(t,t);
// New Type, insert into Type table //------------------------------hashcons--------------------------------------- // Do the hash-cons trick. If the Type already exists in the type table, // delete the current Type and return the existing Type. Otherwise stick the // current Type in the Type table. // Look up the Type in the Type dictionary if(
old ) {
// Pre-existing Type? if(
old !=
this )
// Yes, this guy is not the pre-existing? delete this;
// Yes, Nuke this guy return old;
// Return pre-existing // Every type has a dual (to make my lattice symmetric). // Since we just discovered a new Type, compute its dual right now. if(
cmp(
this,
_dual)==0 ) {
// Handle self-symmetric // New Type, insert into Type table return this;
// Return new Type //------------------------------eq--------------------------------------------- // Structural equality check for Type representations return true;
// Nothing else can go wrong //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------is_finite-------------------------------------- //------------------------------is_nan----------------------------------------- //----------------------interface_vs_oop--------------------------------------- //------------------------------meet------------------------------------------- // Compute the MEET of two types. NOT virtual. It enforces that meet is // commutative and the lattice is symmetric. // Interface meet Oop is Not Symmetric: // Interface:AnyNull meet Oop:AnyNull == Interface:AnyNull fatal(
"meet not symmetric" );
//------------------------------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? // Meeting TOP with anything? // Meeting BOTTOM with anything? // Current "this->_base" is one of: Bad, Multi, Control, Top, // Abio, Abstore, Floatxxx, Doublexxx, Bottom, lastype. switch (t->
base()) {
// Switch on original type // Cut in half the number of cases I must handle. Only need cases for when // the given enum "t->type" is less than or equal to the local enum "type". default:
// Bogus type not in lattice case Bottom:
// Ye Olde Default // These next few cases must match exactly or it is a compile-time error. case Abio:
// State of world outside of program case Top:
// Top of the lattice //-----------------------------filter------------------------------------------ return Type::
TOP;
// Canonical empty value //------------------------------xdual------------------------------------------ // Compute dual right now. Bad,
// Int - handled in v-call Bad,
// Long - handled in v-call Bad,
// NarrowOop - handled in v-call Bad,
// Tuple - handled in v-call Bad,
// Array - handled in v-call Bad,
// VectorS - handled in v-call Bad,
// VectorD - handled in v-call Bad,
// VectorX - handled in v-call Bad,
// VectorY - handled in v-call Bad,
// AnyPtr - handled in v-call Bad,
// RawPtr - handled in v-call Bad,
// OopPtr - handled in v-call Bad,
// InstPtr - handled in v-call Bad,
// AryPtr - handled in v-call Bad,
// KlassPtr - handled in v-call Bad,
// Function - handled in v-call // Note: the base() accessor asserts the sanity of _base. //------------------------------has_memory------------------------------------- for (
uint i=0; i < t->
cnt(); i++) {
//------------------------------dump2------------------------------------------ //------------------------------dump------------------------------------------- //------------------------------data------------------------------------------- "bad",
"control",
"top",
"int:",
"long:",
"half",
"narrowoop:",
"tuple:",
"array:",
"vectors:",
"vectord:",
"vectorx:",
"vectory:",
"anyptr:",
"rawptr:",
"java:",
"inst:",
"aryptr:",
"klass:",
"func",
"abIO",
"return_address",
"memory",
"float_top",
"ftcon:",
"float",
"double_top",
"dblcon:",
"double",
//------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // constants (Ldi nodes). Singletons are integer, float or double constants. //------------------------------empty------------------------------------------ // TRUE if Type is a type with no values, FALSE otherwise. return false;
// never a singleton, therefore never empty //------------------------------dump_stats------------------------------------- // Dump collected statistics to stderr //------------------------------typerr----------------------------------------- //------------------------------isa_oop_ptr------------------------------------ // Return true if type is an oop pointer type. False for raw pointers. 0,0,0,0,0,0,0
/*narrowoop*/,0
/*tuple*/, 0
/*array*/, 0, 0, 0, 0
/*vector*/,
0
/*anyptr*/,0
/*rawptr*/,
1/*OopPtr*/,
1/*InstPtr*/,
1/*AryPtr*/,
1/*KlassPtr*/,
0
/*func*/,0,0
/*return_address*/,0,
/*floats*/0,0,0,
/*doubles*/0,0,0,
//------------------------------dump_stats------------------------------------- // // Check that arrays match type enum // Check that arrays match enumeration // assert( PhiNode::tbl [Type::lastype - 1] == NULL, "did not update array"); //============================================================================= // Convenience common pre-built types. //------------------------------make------------------------------------------- // Create a float constant //------------------------------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 FloatCon switch (t->
base()) {
// Switch on original type case AnyPtr:
// Mixing with oops happens when javac case RawPtr:
// reuses local variables case Bottom:
// Ye Olde Default default:
// All else is a mistake case FloatCon:
// Float-constant vs Float-constant? // must compare bitwise as positive zero, negative zero and NaN have // all the same representation in C++ return FLOAT;
// Return generic float break;
// Return the float constant return this;
// Return the float constant //------------------------------xdual------------------------------------------ //------------------------------eq--------------------------------------------- // Structural equality check for Type representations // One or both are NANs. If both are NANs return true, else false. // (NaN is impossible at this point, since it is not equal even to itself) // difference between positive and negative zero //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------is_finite-------------------------------------- //------------------------------is_nan----------------------------------------- //------------------------------dump2------------------------------------------ // Dump float constant Type //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // constants (Ldi nodes). Singletons are integer, float or double constants return true;
// Always a singleton return false;
// always exactly a singleton //============================================================================= // Convenience common pre-built types. //------------------------------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 DoubleCon switch (t->
base()) {
// Switch on original type case AnyPtr:
// Mixing with oops happens when javac case RawPtr:
// reuses local variables case Bottom:
// Ye Olde Default default:
// All else is a mistake case DoubleCon:
// Double-constant vs Double-constant? return DOUBLE;
// Return generic double return this;
// Return the double constant //------------------------------xdual------------------------------------------ //------------------------------eq--------------------------------------------- // Structural equality check for Type representations // One or both are NANs. If both are NANs return true, else false. // (NaN is impossible at this point, since it is not equal even to itself) // difference between positive and negative zero //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------is_finite-------------------------------------- //------------------------------is_nan----------------------------------------- //------------------------------dump2------------------------------------------ // Dump double constant Type //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // constants (Ldi nodes). Singletons are integer, float or double constants return true;
// Always a singleton return false;
// always exactly a singleton //============================================================================= // Convience common pre-built types. //------------------------------TypeInt---------------------------------------- //------------------------------make------------------------------------------- // Certain normalizations keep us sane when comparing types. // The 'SMALLINT' covers constants and also CC and its relatives. //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type representation object // with reference count equal to the number of Types pointing at it. // Caller should wrap a Types around it. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type? // Currently "this->_base" is a TypeInt switch (t->
base()) {
// Switch on original type case AnyPtr:
// Mixing with oops happens when javac case RawPtr:
// reuses local variables case Bottom:
// Ye Olde Default default:
// All else is a mistake //------------------------------xdual------------------------------------------ // Dual: reverse hi & lo; flip widen //------------------------------widen------------------------------------------ // Only happens for optimistic top-down optimizations. // Coming from TOP or such; no widening // If new guy is equal to old guy, no widening // If new guy contains old, then we widened // If new guy is already wider than old, no widening // If old guy was a constant, do not bother // Check for widening too far // If neither endpoint is extremal yet, push out the endpoint // which is closer to its respective limit. if (
_lo >= 0 ||
// easy common case // Try to widen to an unsigned range type of 31 bits: // Returned widened new guy // If old guy contains new, then we probably widened too far & dropped to // bottom. Return the wider fellow. //fatal("Integer value range is not subset"); //------------------------------narrow--------------------------------------- // Only happens for pessimistic optimizations. if (
_lo >=
_hi)
return this;
// already narrow enough // If new guy is equal to old guy, no narrowing // If old guy was maximum range, allow the narrowing return this;
// doesn't narrow; pretty wierd // The new type narrows the old type, so look for a "death march". // See comments on PhaseTransform::saturate. // Use the new type only if the range shrinks a lot. // We do not want the optimizer computing 2^31 point by point. //-----------------------------filter------------------------------------------ return Type::
TOP;
// Canonical empty value // Do not allow the value of kill->_widen to affect the outcome. // The widen bits must be allowed to run freely through the graph. //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------is_finite-------------------------------------- //------------------------------dump2------------------------------------------ //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple //============================================================================= // Convenience common pre-built types. //------------------------------TypeLong--------------------------------------- //------------------------------make------------------------------------------- // Certain normalizations keep us sane when comparing types. // The 'SMALLINT' covers constants. //------------------------------meet------------------------------------------- // Compute the MEET of two types. It returns a new Type representation object // with reference count equal to the number of Types pointing at it. // Caller should wrap a Types around it. // Perform a fast test for common case; meeting the same types together. if(
this == t )
return this;
// Meeting same type? // Currently "this->_base" is a TypeLong switch (t->
base()) {
// Switch on original type case AnyPtr:
// Mixing with oops happens when javac case RawPtr:
// reuses local variables case Bottom:
// Ye Olde Default default:
// All else is a mistake case Long:
// Long vs Long? //------------------------------xdual------------------------------------------ // Dual: reverse hi & lo; flip widen //------------------------------widen------------------------------------------ // Only happens for optimistic top-down optimizations. // Coming from TOP or such; no widening // If new guy is equal to old guy, no widening // If new guy contains old, then we widened // If new guy is already wider than old, no widening // If old guy was a constant, do not bother // Check for widening too far // If neither endpoint is extremal yet, push out the endpoint // which is closer to its respective limit. if (
_lo >= 0 ||
// easy common case // Try to widen to an unsigned range type of 32/63 bits: // Returned widened new guy // If old guy contains new, then we probably widened too far & dropped to // bottom. Return the wider fellow. // fatal("Long value range is not subset"); //------------------------------narrow---------------------------------------- // Only happens for pessimistic optimizations. if (
_lo >=
_hi)
return this;
// already narrow enough // If new guy is equal to old guy, no narrowing // If old guy was maximum range, allow the narrowing return this;
// doesn't narrow; pretty wierd // The new type narrows the old type, so look for a "death march". // See comments on PhaseTransform::saturate. // Use the new type only if the range shrinks a lot. // We do not want the optimizer computing 2^31 point by point. //-----------------------------filter------------------------------------------ return Type::
TOP;
// Canonical empty value // Do not allow the value of kill->_widen to affect the outcome. // The widen bits must be allowed to run freely through the graph. //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------is_finite-------------------------------------- //------------------------------dump2------------------------------------------ if (n >= x +
10000)
return NULL;
if (n <= x -
10000)
return NULL;
//------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple //============================================================================= // Convenience common pre-built types. //------------------------------make------------------------------------------- // Make a TypeTuple from the range of a method signature // Make a TypeTuple from the domain of a method signature // Use get_const_type here because it respects UseUniqueSubclasses: //------------------------------fields----------------------------------------- // Subroutine call type with space allocated for argument types //------------------------------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 Tuple switch (t->
base()) {
// switch on original type case Bottom:
// Ye Olde Default default:
// All else is a mistake case Tuple: {
// Meeting 2 signatures? return this;
// Return the double constant //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual //------------------------------eq--------------------------------------------- // Structural equality check for Type representations if (
_cnt != s->
_cnt)
return false;
// Unequal field counts //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------dump2------------------------------------------ if( !
depth || d[
this] ) {
// Check for recursive print d.
Insert((
void*)
this, (
void*)
this);
// Stop recursion for( i=0; i<
_cnt-
1; i++ ) {
//------------------------------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 //============================================================================= // Convenience common pre-built types. // Certain normalizations keep us sane when comparing types. // 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. //----------------------interface_vs_oop--------------------------------------- //------------------------------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 //==============================TypeVect======================================= // Convenience common pre-built types. //------------------------------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 Vector switch (t->
base()) {
// switch on original type case Bottom:
// Ye Olde Default default:
// All else is a mistake case VectorY: {
// Meeting 2 vectors? //------------------------------xdual------------------------------------------ // Dual: compute field-by-field dual //------------------------------eq--------------------------------------------- // Structural equality check for Type representations //------------------------------hash------------------------------------------- // Type-specific hashing function. //------------------------------singleton-------------------------------------- // TRUE if Type is a singleton type, FALSE otherwise. Singletons are simple // constants (Ldi nodes). Vector is singleton if all elements are the same // constant value (when vector is created with Replicate code). // There is no Con node for vectors yet. // return _elem->singleton(); //------------------------------dump2------------------------------------------ //============================================================================= // 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------------------------------------- // Perm objects don't use compressed references }
else {
// exclude unsafe ops // Special hidden fields from the Class. // Instance fields 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... // Treat much like a objArray, like below, but fake the type... // Element is an instance // 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. fatal(
"unhandled object type");
//------------------------------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 occurence. 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 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 // Interface klass type could be exact in opposite to interface type, // return it here instead of incorrect Constant ptr J/L/Object (6894807). //------------------------------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 hierarchy. // 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 // inheritance 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 fast-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+]. }
else // Non integral arrays. // Must fall to bottom if exact klasses in upper lattice // are not equal or super klass is exact. // meet with top[] and bottom[] are processed further down: // both are exact and not equal: // 'tap' is exact and super or unrelated: // 'this' is exact and super or unrelated: // Compute new klass on demand, do not use tap->_klass // Only precise for identical arrays // 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 hierarchy. // 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 //----------------------interface_vs_oop--------------------------------------- //------------------------------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. //----------------------compute_klass------------------------------------------ // Compute the defining klass for this class // Compute _klass based on element type. // 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. // Check simple cases when verifying klass. return _klass;
// just return specified klass "integral arrays must be pre-equipped with a class");
// Compute array klass directly from basic type //------------------------------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 // 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",
"tuple:",
"array:",
"vectors:",
"vectord:",
"vectorx:",
"vectory:",
"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