Mercurial > hg > graal-compiler
comparison src/share/vm/opto/type.cpp @ 12190:edb5ab0f3fe5
8001107: @Stable annotation for constant folding of lazily evaluated variables
Reviewed-by: rbackman, twisti, kvn
Contributed-by: john.r.rose@oracle.com, vladimir.x.ivanov@oracle.com
author | vlivanov |
---|---|
date | Tue, 10 Sep 2013 14:51:48 -0700 |
parents | 6f3fd5150b67 |
children | 884ed7a10f09 |
comparison
equal
deleted
inserted
replaced
12188:cd16d587b0fa | 12190:edb5ab0f3fe5 |
---|---|
184 assert(type != ciTypeFlow::StateVector::double2_type(), ""); | 184 assert(type != ciTypeFlow::StateVector::double2_type(), ""); |
185 assert(!type->is_return_address(), ""); | 185 assert(!type->is_return_address(), ""); |
186 | 186 |
187 return Type::get_const_type(type); | 187 return Type::get_const_type(type); |
188 } | 188 } |
189 } | |
190 | |
191 | |
192 //-----------------------make_from_constant------------------------------------ | |
193 const Type* Type::make_from_constant(ciConstant constant, | |
194 bool require_constant, bool is_autobox_cache) { | |
195 switch (constant.basic_type()) { | |
196 case T_BOOLEAN: return TypeInt::make(constant.as_boolean()); | |
197 case T_CHAR: return TypeInt::make(constant.as_char()); | |
198 case T_BYTE: return TypeInt::make(constant.as_byte()); | |
199 case T_SHORT: return TypeInt::make(constant.as_short()); | |
200 case T_INT: return TypeInt::make(constant.as_int()); | |
201 case T_LONG: return TypeLong::make(constant.as_long()); | |
202 case T_FLOAT: return TypeF::make(constant.as_float()); | |
203 case T_DOUBLE: return TypeD::make(constant.as_double()); | |
204 case T_ARRAY: | |
205 case T_OBJECT: | |
206 { | |
207 // cases: | |
208 // can_be_constant = (oop not scavengable || ScavengeRootsInCode != 0) | |
209 // should_be_constant = (oop not scavengable || ScavengeRootsInCode >= 2) | |
210 // An oop is not scavengable if it is in the perm gen. | |
211 ciObject* oop_constant = constant.as_object(); | |
212 if (oop_constant->is_null_object()) { | |
213 return Type::get_zero_type(T_OBJECT); | |
214 } else if (require_constant || oop_constant->should_be_constant()) { | |
215 return TypeOopPtr::make_from_constant(oop_constant, require_constant, is_autobox_cache); | |
216 } | |
217 } | |
218 } | |
219 // Fall through to failure | |
220 return NULL; | |
189 } | 221 } |
190 | 222 |
191 | 223 |
192 //------------------------------make------------------------------------------- | 224 //------------------------------make------------------------------------------- |
193 // Create a simple Type, with default empty symbol sets. Then hashcons it | 225 // Create a simple Type, with default empty symbol sets. Then hashcons it |
1822 else | 1854 else |
1823 return size; | 1855 return size; |
1824 } | 1856 } |
1825 | 1857 |
1826 //------------------------------make------------------------------------------- | 1858 //------------------------------make------------------------------------------- |
1827 const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) { | 1859 const TypeAry* TypeAry::make(const Type* elem, const TypeInt* size, bool stable) { |
1828 if (UseCompressedOops && elem->isa_oopptr()) { | 1860 if (UseCompressedOops && elem->isa_oopptr()) { |
1829 elem = elem->make_narrowoop(); | 1861 elem = elem->make_narrowoop(); |
1830 } | 1862 } |
1831 size = normalize_array_size(size); | 1863 size = normalize_array_size(size); |
1832 return (TypeAry*)(new TypeAry(elem,size))->hashcons(); | 1864 return (TypeAry*)(new TypeAry(elem,size,stable))->hashcons(); |
1833 } | 1865 } |
1834 | 1866 |
1835 //------------------------------meet------------------------------------------- | 1867 //------------------------------meet------------------------------------------- |
1836 // Compute the MEET of two types. It returns a new Type object. | 1868 // Compute the MEET of two types. It returns a new Type object. |
1837 const Type *TypeAry::xmeet( const Type *t ) const { | 1869 const Type *TypeAry::xmeet( const Type *t ) const { |
1848 typerr(t); | 1880 typerr(t); |
1849 | 1881 |
1850 case Array: { // Meeting 2 arrays? | 1882 case Array: { // Meeting 2 arrays? |
1851 const TypeAry *a = t->is_ary(); | 1883 const TypeAry *a = t->is_ary(); |
1852 return TypeAry::make(_elem->meet(a->_elem), | 1884 return TypeAry::make(_elem->meet(a->_elem), |
1853 _size->xmeet(a->_size)->is_int()); | 1885 _size->xmeet(a->_size)->is_int(), |
1886 _stable & a->_stable); | |
1854 } | 1887 } |
1855 case Top: | 1888 case Top: |
1856 break; | 1889 break; |
1857 } | 1890 } |
1858 return this; // Return the double constant | 1891 return this; // Return the double constant |
1861 //------------------------------xdual------------------------------------------ | 1894 //------------------------------xdual------------------------------------------ |
1862 // Dual: compute field-by-field dual | 1895 // Dual: compute field-by-field dual |
1863 const Type *TypeAry::xdual() const { | 1896 const Type *TypeAry::xdual() const { |
1864 const TypeInt* size_dual = _size->dual()->is_int(); | 1897 const TypeInt* size_dual = _size->dual()->is_int(); |
1865 size_dual = normalize_array_size(size_dual); | 1898 size_dual = normalize_array_size(size_dual); |
1866 return new TypeAry( _elem->dual(), size_dual); | 1899 return new TypeAry(_elem->dual(), size_dual, !_stable); |
1867 } | 1900 } |
1868 | 1901 |
1869 //------------------------------eq--------------------------------------------- | 1902 //------------------------------eq--------------------------------------------- |
1870 // Structural equality check for Type representations | 1903 // Structural equality check for Type representations |
1871 bool TypeAry::eq( const Type *t ) const { | 1904 bool TypeAry::eq( const Type *t ) const { |
1872 const TypeAry *a = (const TypeAry*)t; | 1905 const TypeAry *a = (const TypeAry*)t; |
1873 return _elem == a->_elem && | 1906 return _elem == a->_elem && |
1907 _stable == a->_stable && | |
1874 _size == a->_size; | 1908 _size == a->_size; |
1875 } | 1909 } |
1876 | 1910 |
1877 //------------------------------hash------------------------------------------- | 1911 //------------------------------hash------------------------------------------- |
1878 // Type-specific hashing function. | 1912 // Type-specific hashing function. |
1879 int TypeAry::hash(void) const { | 1913 int TypeAry::hash(void) const { |
1880 return (intptr_t)_elem + (intptr_t)_size; | 1914 return (intptr_t)_elem + (intptr_t)_size + (_stable ? 43 : 0); |
1881 } | 1915 } |
1882 | 1916 |
1883 //----------------------interface_vs_oop--------------------------------------- | 1917 //----------------------interface_vs_oop--------------------------------------- |
1884 #ifdef ASSERT | 1918 #ifdef ASSERT |
1885 bool TypeAry::interface_vs_oop(const Type *t) const { | 1919 bool TypeAry::interface_vs_oop(const Type *t) const { |
1892 #endif | 1926 #endif |
1893 | 1927 |
1894 //------------------------------dump2------------------------------------------ | 1928 //------------------------------dump2------------------------------------------ |
1895 #ifndef PRODUCT | 1929 #ifndef PRODUCT |
1896 void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const { | 1930 void TypeAry::dump2( Dict &d, uint depth, outputStream *st ) const { |
1931 if (_stable) st->print("stable:"); | |
1897 _elem->dump2(d, depth, st); | 1932 _elem->dump2(d, depth, st); |
1898 st->print("["); | 1933 st->print("["); |
1899 _size->dump2(d, depth, st); | 1934 _size->dump2(d, depth, st); |
1900 st->print("]"); | 1935 st->print("]"); |
1901 } | 1936 } |
3455 //-------------------------------cast_to_size---------------------------------- | 3490 //-------------------------------cast_to_size---------------------------------- |
3456 const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const { | 3491 const TypeAryPtr* TypeAryPtr::cast_to_size(const TypeInt* new_size) const { |
3457 assert(new_size != NULL, ""); | 3492 assert(new_size != NULL, ""); |
3458 new_size = narrow_size_type(new_size); | 3493 new_size = narrow_size_type(new_size); |
3459 if (new_size == size()) return this; | 3494 if (new_size == size()) return this; |
3460 const TypeAry* new_ary = TypeAry::make(elem(), new_size); | 3495 const TypeAry* new_ary = TypeAry::make(elem(), new_size, is_stable()); |
3461 return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); | 3496 return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); |
3462 } | 3497 } |
3463 | 3498 |
3499 | |
3500 //------------------------------cast_to_stable--------------------------------- | |
3501 const TypeAryPtr* TypeAryPtr::cast_to_stable(bool stable, int stable_dimension) const { | |
3502 if (stable_dimension <= 0 || (stable_dimension == 1 && stable == this->is_stable())) | |
3503 return this; | |
3504 | |
3505 const Type* elem = this->elem(); | |
3506 const TypePtr* elem_ptr = elem->make_ptr(); | |
3507 | |
3508 if (stable_dimension > 1 && elem_ptr != NULL && elem_ptr->isa_aryptr()) { | |
3509 // If this is widened from a narrow oop, TypeAry::make will re-narrow it. | |
3510 elem = elem_ptr = elem_ptr->is_aryptr()->cast_to_stable(stable, stable_dimension - 1); | |
3511 } | |
3512 | |
3513 const TypeAry* new_ary = TypeAry::make(elem, size(), stable); | |
3514 | |
3515 return make(ptr(), const_oop(), new_ary, klass(), klass_is_exact(), _offset, _instance_id); | |
3516 } | |
3517 | |
3518 //-----------------------------stable_dimension-------------------------------- | |
3519 int TypeAryPtr::stable_dimension() const { | |
3520 if (!is_stable()) return 0; | |
3521 int dim = 1; | |
3522 const TypePtr* elem_ptr = elem()->make_ptr(); | |
3523 if (elem_ptr != NULL && elem_ptr->isa_aryptr()) | |
3524 dim += elem_ptr->is_aryptr()->stable_dimension(); | |
3525 return dim; | |
3526 } | |
3464 | 3527 |
3465 //------------------------------eq--------------------------------------------- | 3528 //------------------------------eq--------------------------------------------- |
3466 // Structural equality check for Type representations | 3529 // Structural equality check for Type representations |
3467 bool TypeAryPtr::eq( const Type *t ) const { | 3530 bool TypeAryPtr::eq( const Type *t ) const { |
3468 const TypeAryPtr *p = t->is_aryptr(); | 3531 const TypeAryPtr *p = t->is_aryptr(); |
3568 lazy_klass = _klass; | 3631 lazy_klass = _klass; |
3569 } else { | 3632 } else { |
3570 // Something like byte[int+] meets char[int+]. | 3633 // Something like byte[int+] meets char[int+]. |
3571 // This must fall to bottom, not (int[-128..65535])[int+]. | 3634 // This must fall to bottom, not (int[-128..65535])[int+]. |
3572 instance_id = InstanceBot; | 3635 instance_id = InstanceBot; |
3573 tary = TypeAry::make(Type::BOTTOM, tary->_size); | 3636 tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); |
3574 } | 3637 } |
3575 } else // Non integral arrays. | 3638 } else // Non integral arrays. |
3576 // Must fall to bottom if exact klasses in upper lattice | 3639 // Must fall to bottom if exact klasses in upper lattice |
3577 // are not equal or super klass is exact. | 3640 // are not equal or super klass is exact. |
3578 if ( above_centerline(ptr) && klass() != tap->klass() && | 3641 if ( above_centerline(ptr) && klass() != tap->klass() && |
3582 ((tap ->_klass_is_exact && this->_klass_is_exact) || | 3645 ((tap ->_klass_is_exact && this->_klass_is_exact) || |
3583 // 'tap' is exact and super or unrelated: | 3646 // 'tap' is exact and super or unrelated: |
3584 (tap ->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || | 3647 (tap ->_klass_is_exact && !tap->klass()->is_subtype_of(klass())) || |
3585 // 'this' is exact and super or unrelated: | 3648 // 'this' is exact and super or unrelated: |
3586 (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { | 3649 (this->_klass_is_exact && !klass()->is_subtype_of(tap->klass())))) { |
3587 tary = TypeAry::make(Type::BOTTOM, tary->_size); | 3650 tary = TypeAry::make(Type::BOTTOM, tary->_size, tary->_stable); |
3588 return make( NotNull, NULL, tary, lazy_klass, false, off, InstanceBot ); | 3651 return make( NotNull, NULL, tary, lazy_klass, false, off, InstanceBot ); |
3589 } | 3652 } |
3590 | 3653 |
3591 bool xk = false; | 3654 bool xk = false; |
3592 switch (tap->ptr()) { | 3655 switch (tap->ptr()) { |