Mercurial > hg > truffle
comparison src/share/vm/opto/type.cpp @ 113:ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
Summary: Compressed oops in instances, arrays, and headers. Code contributors are coleenp, phh, never, swamyv
Reviewed-by: jmasa, kamg, acorn, tbell, kvn, rasbold
author | coleenp |
---|---|
date | Sun, 13 Apr 2008 17:43:42 -0400 |
parents | b8f5ba577b02 |
children | 885ed790ecf0 |
comparison
equal
deleted
inserted
replaced
110:a49a647afe9a | 113:ba764ed4b6f2 |
---|---|
38 T_ILLEGAL, // Control | 38 T_ILLEGAL, // Control |
39 T_VOID, // Top | 39 T_VOID, // Top |
40 T_INT, // Int | 40 T_INT, // Int |
41 T_LONG, // Long | 41 T_LONG, // Long |
42 T_VOID, // Half | 42 T_VOID, // Half |
43 T_NARROWOOP, // NarrowOop | |
43 | 44 |
44 T_ILLEGAL, // Tuple | 45 T_ILLEGAL, // Tuple |
45 T_ARRAY, // Array | 46 T_ARRAY, // Array |
46 | 47 |
47 T_ADDRESS, // AnyPtr // shows up in factory methods for NULL_PTR | 48 T_ADDRESS, // AnyPtr // shows up in factory methods for NULL_PTR |
277 TypePtr::BOTTOM = TypePtr::make( AnyPtr, TypePtr::BotPTR, OffsetBot ); | 278 TypePtr::BOTTOM = TypePtr::make( AnyPtr, TypePtr::BotPTR, OffsetBot ); |
278 | 279 |
279 TypeRawPtr::BOTTOM = TypeRawPtr::make( TypePtr::BotPTR ); | 280 TypeRawPtr::BOTTOM = TypeRawPtr::make( TypePtr::BotPTR ); |
280 TypeRawPtr::NOTNULL= TypeRawPtr::make( TypePtr::NotNull ); | 281 TypeRawPtr::NOTNULL= TypeRawPtr::make( TypePtr::NotNull ); |
281 | 282 |
282 mreg2type[Op_Node] = Type::BOTTOM; | |
283 mreg2type[Op_Set ] = 0; | |
284 mreg2type[Op_RegI] = TypeInt::INT; | |
285 mreg2type[Op_RegP] = TypePtr::BOTTOM; | |
286 mreg2type[Op_RegF] = Type::FLOAT; | |
287 mreg2type[Op_RegD] = Type::DOUBLE; | |
288 mreg2type[Op_RegL] = TypeLong::LONG; | |
289 mreg2type[Op_RegFlags] = TypeInt::CC; | |
290 | |
291 const Type **fmembar = TypeTuple::fields(0); | 283 const Type **fmembar = TypeTuple::fields(0); |
292 TypeTuple::MEMBAR = TypeTuple::make(TypeFunc::Parms+0, fmembar); | 284 TypeTuple::MEMBAR = TypeTuple::make(TypeFunc::Parms+0, fmembar); |
293 | 285 |
294 const Type **fsc = (const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); | 286 const Type **fsc = (const Type**)shared_type_arena->Amalloc_4(2*sizeof(Type*)); |
295 fsc[0] = TypeInt::CC; | 287 fsc[0] = TypeInt::CC; |
302 TypeInstPtr::MARK = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), | 294 TypeInstPtr::MARK = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), |
303 false, 0, oopDesc::mark_offset_in_bytes()); | 295 false, 0, oopDesc::mark_offset_in_bytes()); |
304 TypeInstPtr::KLASS = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), | 296 TypeInstPtr::KLASS = TypeInstPtr::make(TypePtr::BotPTR, current->env()->Object_klass(), |
305 false, 0, oopDesc::klass_offset_in_bytes()); | 297 false, 0, oopDesc::klass_offset_in_bytes()); |
306 TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot); | 298 TypeOopPtr::BOTTOM = TypeOopPtr::make(TypePtr::BotPTR, OffsetBot); |
299 | |
300 TypeNarrowOop::NULL_PTR = TypeNarrowOop::make( TypePtr::NULL_PTR ); | |
301 TypeNarrowOop::BOTTOM = TypeNarrowOop::make( TypeInstPtr::BOTTOM ); | |
302 | |
303 mreg2type[Op_Node] = Type::BOTTOM; | |
304 mreg2type[Op_Set ] = 0; | |
305 mreg2type[Op_RegN] = TypeNarrowOop::BOTTOM; | |
306 mreg2type[Op_RegI] = TypeInt::INT; | |
307 mreg2type[Op_RegP] = TypePtr::BOTTOM; | |
308 mreg2type[Op_RegF] = Type::FLOAT; | |
309 mreg2type[Op_RegD] = Type::DOUBLE; | |
310 mreg2type[Op_RegL] = TypeLong::LONG; | |
311 mreg2type[Op_RegFlags] = TypeInt::CC; | |
307 | 312 |
308 TypeAryPtr::RANGE = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), current->env()->Object_klass(), false, arrayOopDesc::length_offset_in_bytes()); | 313 TypeAryPtr::RANGE = TypeAryPtr::make( TypePtr::BotPTR, TypeAry::make(Type::BOTTOM,TypeInt::POS), current->env()->Object_klass(), false, arrayOopDesc::length_offset_in_bytes()); |
309 // There is no shared klass for Object[]. See note in TypeAryPtr::klass(). | 314 // There is no shared klass for Object[]. See note in TypeAryPtr::klass(). |
310 TypeAryPtr::OOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/, false, Type::OffsetBot); | 315 TypeAryPtr::OOPS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInstPtr::BOTTOM,TypeInt::POS), NULL /*ciArrayKlass::make(o)*/, false, Type::OffsetBot); |
311 TypeAryPtr::BYTES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::BYTE ,TypeInt::POS), ciTypeArrayKlass::make(T_BYTE), true, Type::OffsetBot); | 316 TypeAryPtr::BYTES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::BYTE ,TypeInt::POS), ciTypeArrayKlass::make(T_BYTE), true, Type::OffsetBot); |
314 TypeAryPtr::INTS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::INT ,TypeInt::POS), ciTypeArrayKlass::make(T_INT), true, Type::OffsetBot); | 319 TypeAryPtr::INTS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeInt::INT ,TypeInt::POS), ciTypeArrayKlass::make(T_INT), true, Type::OffsetBot); |
315 TypeAryPtr::LONGS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeLong::LONG ,TypeInt::POS), ciTypeArrayKlass::make(T_LONG), true, Type::OffsetBot); | 320 TypeAryPtr::LONGS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(TypeLong::LONG ,TypeInt::POS), ciTypeArrayKlass::make(T_LONG), true, Type::OffsetBot); |
316 TypeAryPtr::FLOATS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::FLOAT ,TypeInt::POS), ciTypeArrayKlass::make(T_FLOAT), true, Type::OffsetBot); | 321 TypeAryPtr::FLOATS = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::FLOAT ,TypeInt::POS), ciTypeArrayKlass::make(T_FLOAT), true, Type::OffsetBot); |
317 TypeAryPtr::DOUBLES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::DOUBLE ,TypeInt::POS), ciTypeArrayKlass::make(T_DOUBLE), true, Type::OffsetBot); | 322 TypeAryPtr::DOUBLES = TypeAryPtr::make(TypePtr::BotPTR, TypeAry::make(Type::DOUBLE ,TypeInt::POS), ciTypeArrayKlass::make(T_DOUBLE), true, Type::OffsetBot); |
318 | 323 |
324 TypeAryPtr::_array_body_type[T_NARROWOOP] = NULL; // what should this be? | |
319 TypeAryPtr::_array_body_type[T_OBJECT] = TypeAryPtr::OOPS; | 325 TypeAryPtr::_array_body_type[T_OBJECT] = TypeAryPtr::OOPS; |
320 TypeAryPtr::_array_body_type[T_ARRAY] = TypeAryPtr::OOPS; // arrays are stored in oop arrays | 326 TypeAryPtr::_array_body_type[T_ARRAY] = TypeAryPtr::OOPS; // arrays are stored in oop arrays |
321 TypeAryPtr::_array_body_type[T_BYTE] = TypeAryPtr::BYTES; | 327 TypeAryPtr::_array_body_type[T_BYTE] = TypeAryPtr::BYTES; |
322 TypeAryPtr::_array_body_type[T_BOOLEAN] = TypeAryPtr::BYTES; // boolean[] is a byte array | 328 TypeAryPtr::_array_body_type[T_BOOLEAN] = TypeAryPtr::BYTES; // boolean[] is a byte array |
323 TypeAryPtr::_array_body_type[T_SHORT] = TypeAryPtr::SHORTS; | 329 TypeAryPtr::_array_body_type[T_SHORT] = TypeAryPtr::SHORTS; |
343 const Type **longpair = TypeTuple::fields(2); | 349 const Type **longpair = TypeTuple::fields(2); |
344 longpair[0] = TypeLong::LONG; | 350 longpair[0] = TypeLong::LONG; |
345 longpair[1] = TypeLong::LONG; | 351 longpair[1] = TypeLong::LONG; |
346 TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair); | 352 TypeTuple::LONG_PAIR = TypeTuple::make(2, longpair); |
347 | 353 |
354 _const_basic_type[T_NARROWOOP] = TypeNarrowOop::BOTTOM; | |
348 _const_basic_type[T_BOOLEAN] = TypeInt::BOOL; | 355 _const_basic_type[T_BOOLEAN] = TypeInt::BOOL; |
349 _const_basic_type[T_CHAR] = TypeInt::CHAR; | 356 _const_basic_type[T_CHAR] = TypeInt::CHAR; |
350 _const_basic_type[T_BYTE] = TypeInt::BYTE; | 357 _const_basic_type[T_BYTE] = TypeInt::BYTE; |
351 _const_basic_type[T_SHORT] = TypeInt::SHORT; | 358 _const_basic_type[T_SHORT] = TypeInt::SHORT; |
352 _const_basic_type[T_INT] = TypeInt::INT; | 359 _const_basic_type[T_INT] = TypeInt::INT; |
357 _const_basic_type[T_ARRAY] = TypeInstPtr::BOTTOM; // there is no separate bottom for arrays | 364 _const_basic_type[T_ARRAY] = TypeInstPtr::BOTTOM; // there is no separate bottom for arrays |
358 _const_basic_type[T_VOID] = TypePtr::NULL_PTR; // reflection represents void this way | 365 _const_basic_type[T_VOID] = TypePtr::NULL_PTR; // reflection represents void this way |
359 _const_basic_type[T_ADDRESS] = TypeRawPtr::BOTTOM; // both interpreter return addresses & random raw ptrs | 366 _const_basic_type[T_ADDRESS] = TypeRawPtr::BOTTOM; // both interpreter return addresses & random raw ptrs |
360 _const_basic_type[T_CONFLICT]= Type::BOTTOM; // why not? | 367 _const_basic_type[T_CONFLICT]= Type::BOTTOM; // why not? |
361 | 368 |
369 _zero_type[T_NARROWOOP] = TypeNarrowOop::NULL_PTR; | |
362 _zero_type[T_BOOLEAN] = TypeInt::ZERO; // false == 0 | 370 _zero_type[T_BOOLEAN] = TypeInt::ZERO; // false == 0 |
363 _zero_type[T_CHAR] = TypeInt::ZERO; // '\0' == 0 | 371 _zero_type[T_CHAR] = TypeInt::ZERO; // '\0' == 0 |
364 _zero_type[T_BYTE] = TypeInt::ZERO; // 0x00 == 0 | 372 _zero_type[T_BYTE] = TypeInt::ZERO; // 0x00 == 0 |
365 _zero_type[T_SHORT] = TypeInt::ZERO; // 0x0000 == 0 | 373 _zero_type[T_SHORT] = TypeInt::ZERO; // 0x0000 == 0 |
366 _zero_type[T_INT] = TypeInt::ZERO; | 374 _zero_type[T_INT] = TypeInt::ZERO; |
398 DictI i(_shared_type_dict); | 406 DictI i(_shared_type_dict); |
399 for( ; i.test(); ++i ) { | 407 for( ; i.test(); ++i ) { |
400 Type* t = (Type*)i._value; | 408 Type* t = (Type*)i._value; |
401 tdic->Insert(t,t); // New Type, insert into Type table | 409 tdic->Insert(t,t); // New Type, insert into Type table |
402 } | 410 } |
411 | |
412 #ifdef ASSERT | |
413 verify_lastype(); | |
414 #endif | |
403 } | 415 } |
404 | 416 |
405 //------------------------------hashcons--------------------------------------- | 417 //------------------------------hashcons--------------------------------------- |
406 // Do the hash-cons trick. If the Type already exists in the type table, | 418 // Do the hash-cons trick. If the Type already exists in the type table, |
407 // delete the current Type and return the existing Type. Otherwise stick the | 419 // delete the current Type and return the existing Type. Otherwise stick the |
465 | 477 |
466 //------------------------------meet------------------------------------------- | 478 //------------------------------meet------------------------------------------- |
467 // Compute the MEET of two types. NOT virtual. It enforces that meet is | 479 // Compute the MEET of two types. NOT virtual. It enforces that meet is |
468 // commutative and the lattice is symmetric. | 480 // commutative and the lattice is symmetric. |
469 const Type *Type::meet( const Type *t ) const { | 481 const Type *Type::meet( const Type *t ) const { |
482 if (isa_narrowoop() && t->isa_narrowoop()) { | |
483 const Type* result = is_narrowoop()->make_oopptr()->meet(t->is_narrowoop()->make_oopptr()); | |
484 if (result->isa_oopptr()) { | |
485 return result->isa_oopptr()->make_narrowoop(); | |
486 } else if (result == TypePtr::NULL_PTR) { | |
487 return TypeNarrowOop::NULL_PTR; | |
488 } else { | |
489 return result; | |
490 } | |
491 } | |
492 | |
470 const Type *mt = xmeet(t); | 493 const Type *mt = xmeet(t); |
494 if (isa_narrowoop() || t->isa_narrowoop()) return mt; | |
471 #ifdef ASSERT | 495 #ifdef ASSERT |
472 assert( mt == t->xmeet(this), "meet not commutative" ); | 496 assert( mt == t->xmeet(this), "meet not commutative" ); |
473 const Type* dual_join = mt->_dual; | 497 const Type* dual_join = mt->_dual; |
474 const Type *t2t = dual_join->xmeet(t->_dual); | 498 const Type *t2t = dual_join->xmeet(t->_dual); |
475 const Type *t2this = dual_join->xmeet( _dual); | 499 const Type *t2this = dual_join->xmeet( _dual); |
554 return t->xmeet(this); | 578 return t->xmeet(this); |
555 | 579 |
556 case AryPtr: | 580 case AryPtr: |
557 return t->xmeet(this); | 581 return t->xmeet(this); |
558 | 582 |
583 case NarrowOop: | |
584 return t->xmeet(this); | |
585 | |
559 case Bad: // Type check | 586 case Bad: // Type check |
560 default: // Bogus type not in lattice | 587 default: // Bogus type not in lattice |
561 typerr(t); | 588 typerr(t); |
562 return Type::BOTTOM; | 589 return Type::BOTTOM; |
563 | 590 |
611 Control, // Control | 638 Control, // Control |
612 Bottom, // Top | 639 Bottom, // Top |
613 Bad, // Int - handled in v-call | 640 Bad, // Int - handled in v-call |
614 Bad, // Long - handled in v-call | 641 Bad, // Long - handled in v-call |
615 Half, // Half | 642 Half, // Half |
643 Bad, // NarrowOop - handled in v-call | |
616 | 644 |
617 Bad, // Tuple - handled in v-call | 645 Bad, // Tuple - handled in v-call |
618 Bad, // Array - handled in v-call | 646 Bad, // Array - handled in v-call |
619 | 647 |
620 Bad, // AnyPtr - handled in v-call | 648 Bad, // AnyPtr - handled in v-call |
666 //------------------------------dump------------------------------------------- | 694 //------------------------------dump------------------------------------------- |
667 void Type::dump_on(outputStream *st) const { | 695 void Type::dump_on(outputStream *st) const { |
668 ResourceMark rm; | 696 ResourceMark rm; |
669 Dict d(cmpkey,hashkey); // Stop recursive type dumping | 697 Dict d(cmpkey,hashkey); // Stop recursive type dumping |
670 dump2(d,1, st); | 698 dump2(d,1, st); |
699 if (isa_ptr() && is_ptr()->is_narrow()) { | |
700 st->print(" [narrow]"); | |
701 } | |
671 } | 702 } |
672 | 703 |
673 //------------------------------data------------------------------------------- | 704 //------------------------------data------------------------------------------- |
674 const char * const Type::msg[Type::lastype] = { | 705 const char * const Type::msg[Type::lastype] = { |
675 "bad","control","top","int:","long:","half", | 706 "bad","control","top","int:","long:","half", "narrowoop:", |
676 "tuple:", "aryptr", | 707 "tuple:", "aryptr", |
677 "anyptr:", "rawptr:", "java:", "inst:", "ary:", "klass:", | 708 "anyptr:", "rawptr:", "java:", "inst:", "ary:", "klass:", |
678 "func", "abIO", "return_address", "memory", | 709 "func", "abIO", "return_address", "memory", |
679 "float_top", "ftcon:", "float", | 710 "float_top", "ftcon:", "float", |
680 "double_top", "dblcon:", "double", | 711 "double_top", "dblcon:", "double", |
733 } | 764 } |
734 | 765 |
735 //------------------------------isa_oop_ptr------------------------------------ | 766 //------------------------------isa_oop_ptr------------------------------------ |
736 // Return true if type is an oop pointer type. False for raw pointers. | 767 // Return true if type is an oop pointer type. False for raw pointers. |
737 static char isa_oop_ptr_tbl[Type::lastype] = { | 768 static char isa_oop_ptr_tbl[Type::lastype] = { |
738 0,0,0,0,0,0,0/*tuple*/, 0/*ary*/, | 769 0,0,0,0,0,0,0/*narrowoop*/,0/*tuple*/, 0/*ary*/, |
739 0/*anyptr*/,0/*rawptr*/,1/*OopPtr*/,1/*InstPtr*/,1/*AryPtr*/,1/*KlassPtr*/, | 770 0/*anyptr*/,0/*rawptr*/,1/*OopPtr*/,1/*InstPtr*/,1/*AryPtr*/,1/*KlassPtr*/, |
740 0/*func*/,0,0/*return_address*/,0, | 771 0/*func*/,0,0/*return_address*/,0, |
741 /*floats*/0,0,0, /*doubles*/0,0,0, | 772 /*floats*/0,0,0, /*doubles*/0,0,0, |
742 0 | 773 0 |
743 }; | 774 }; |
1049 case FloatCon: | 1080 case FloatCon: |
1050 case FloatBot: | 1081 case FloatBot: |
1051 case DoubleTop: | 1082 case DoubleTop: |
1052 case DoubleCon: | 1083 case DoubleCon: |
1053 case DoubleBot: | 1084 case DoubleBot: |
1085 case NarrowOop: | |
1054 case Bottom: // Ye Olde Default | 1086 case Bottom: // Ye Olde Default |
1055 return Type::BOTTOM; | 1087 return Type::BOTTOM; |
1056 default: // All else is a mistake | 1088 default: // All else is a mistake |
1057 typerr(t); | 1089 typerr(t); |
1058 case Top: // No change | 1090 case Top: // No change |
1716 return size; | 1748 return size; |
1717 } | 1749 } |
1718 | 1750 |
1719 //------------------------------make------------------------------------------- | 1751 //------------------------------make------------------------------------------- |
1720 const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) { | 1752 const TypeAry *TypeAry::make( const Type *elem, const TypeInt *size) { |
1753 if (UseCompressedOops && elem->isa_oopptr()) { | |
1754 elem = elem->is_oopptr()->make_narrowoop(); | |
1755 } | |
1721 size = normalize_array_size(size); | 1756 size = normalize_array_size(size); |
1722 return (TypeAry*)(new TypeAry(elem,size))->hashcons(); | 1757 return (TypeAry*)(new TypeAry(elem,size))->hashcons(); |
1723 } | 1758 } |
1724 | 1759 |
1725 //------------------------------meet------------------------------------------- | 1760 //------------------------------meet------------------------------------------- |
1798 // This logic looks at the element type of an array, and returns true | 1833 // This logic looks at the element type of an array, and returns true |
1799 // if the element type is either a primitive or a final instance class. | 1834 // if the element type is either a primitive or a final instance class. |
1800 // In such cases, an array built on this ary must have no subclasses. | 1835 // In such cases, an array built on this ary must have no subclasses. |
1801 if (_elem == BOTTOM) return false; // general array not exact | 1836 if (_elem == BOTTOM) return false; // general array not exact |
1802 if (_elem == TOP ) return false; // inverted general array not exact | 1837 if (_elem == TOP ) return false; // inverted general array not exact |
1803 const TypeOopPtr* toop = _elem->isa_oopptr(); | 1838 const TypeOopPtr* toop = NULL; |
1839 if (UseCompressedOops) { | |
1840 const TypeNarrowOop* noop = _elem->isa_narrowoop(); | |
1841 if (noop) toop = noop->make_oopptr()->isa_oopptr(); | |
1842 } else { | |
1843 toop = _elem->isa_oopptr(); | |
1844 } | |
1804 if (!toop) return true; // a primitive type, like int | 1845 if (!toop) return true; // a primitive type, like int |
1805 ciKlass* tklass = toop->klass(); | 1846 ciKlass* tklass = toop->klass(); |
1806 if (tklass == NULL) return false; // unloaded class | 1847 if (tklass == NULL) return false; // unloaded class |
1807 if (!tklass->is_loaded()) return false; // unloaded class | 1848 if (!tklass->is_loaded()) return false; // unloaded class |
1808 const TypeInstPtr* tinst = _elem->isa_instptr(); | 1849 const TypeInstPtr* tinst; |
1850 if (_elem->isa_narrowoop()) | |
1851 tinst = _elem->is_narrowoop()->make_oopptr()->isa_instptr(); | |
1852 else | |
1853 tinst = _elem->isa_instptr(); | |
1809 if (tinst) return tklass->as_instance_klass()->is_final(); | 1854 if (tinst) return tklass->as_instance_klass()->is_final(); |
1810 const TypeAryPtr* tap = _elem->isa_aryptr(); | 1855 const TypeAryPtr* tap; |
1856 if (_elem->isa_narrowoop()) | |
1857 tap = _elem->is_narrowoop()->make_oopptr()->isa_aryptr(); | |
1858 else | |
1859 tap = _elem->isa_aryptr(); | |
1811 if (tap) return tap->ary()->ary_must_be_exact(); | 1860 if (tap) return tap->ary()->ary_must_be_exact(); |
1812 return false; | 1861 return false; |
1813 } | 1862 } |
1814 | 1863 |
1815 //============================================================================= | 1864 //============================================================================= |
1862 case FloatCon: | 1911 case FloatCon: |
1863 case FloatBot: | 1912 case FloatBot: |
1864 case DoubleTop: | 1913 case DoubleTop: |
1865 case DoubleCon: | 1914 case DoubleCon: |
1866 case DoubleBot: | 1915 case DoubleBot: |
1916 case NarrowOop: | |
1867 case Bottom: // Ye Olde Default | 1917 case Bottom: // Ye Olde Default |
1868 return Type::BOTTOM; | 1918 return Type::BOTTOM; |
1869 case Top: | 1919 case Top: |
1870 return this; | 1920 return this; |
1871 | 1921 |
2453 //------------------------------add_offset------------------------------------- | 2503 //------------------------------add_offset------------------------------------- |
2454 const TypePtr *TypeOopPtr::add_offset( int offset ) const { | 2504 const TypePtr *TypeOopPtr::add_offset( int offset ) const { |
2455 return make( _ptr, xadd_offset(offset) ); | 2505 return make( _ptr, xadd_offset(offset) ); |
2456 } | 2506 } |
2457 | 2507 |
2508 const TypeNarrowOop* TypeOopPtr::make_narrowoop() const { | |
2509 return TypeNarrowOop::make(this); | |
2510 } | |
2511 | |
2458 int TypeOopPtr::meet_instance(int iid) const { | 2512 int TypeOopPtr::meet_instance(int iid) const { |
2459 if (iid == 0) { | 2513 if (iid == 0) { |
2460 return (_instance_id < 0) ? _instance_id : UNKNOWN_INSTANCE; | 2514 return (_instance_id < 0) ? _instance_id : UNKNOWN_INSTANCE; |
2461 } else if (_instance_id == UNKNOWN_INSTANCE) { | 2515 } else if (_instance_id == UNKNOWN_INSTANCE) { |
2462 return (iid < 0) ? iid : UNKNOWN_INSTANCE; | 2516 return (iid < 0) ? iid : UNKNOWN_INSTANCE; |
2605 case FloatCon: | 2659 case FloatCon: |
2606 case FloatBot: | 2660 case FloatBot: |
2607 case DoubleTop: | 2661 case DoubleTop: |
2608 case DoubleCon: | 2662 case DoubleCon: |
2609 case DoubleBot: | 2663 case DoubleBot: |
2664 case NarrowOop: | |
2610 case Bottom: // Ye Olde Default | 2665 case Bottom: // Ye Olde Default |
2611 return Type::BOTTOM; | 2666 return Type::BOTTOM; |
2612 case Top: | 2667 case Top: |
2613 return this; | 2668 return this; |
2614 | 2669 |
3019 static jint max_array_length(BasicType etype) { | 3074 static jint max_array_length(BasicType etype) { |
3020 jint& cache = max_array_length_cache[etype]; | 3075 jint& cache = max_array_length_cache[etype]; |
3021 jint res = cache; | 3076 jint res = cache; |
3022 if (res == 0) { | 3077 if (res == 0) { |
3023 switch (etype) { | 3078 switch (etype) { |
3079 case T_NARROWOOP: | |
3080 etype = T_OBJECT; | |
3081 break; | |
3024 case T_CONFLICT: | 3082 case T_CONFLICT: |
3025 case T_ILLEGAL: | 3083 case T_ILLEGAL: |
3026 case T_VOID: | 3084 case T_VOID: |
3027 etype = T_BYTE; // will produce conservatively high value | 3085 etype = T_BYTE; // will produce conservatively high value |
3028 } | 3086 } |
3091 case FloatCon: | 3149 case FloatCon: |
3092 case FloatBot: | 3150 case FloatBot: |
3093 case DoubleTop: | 3151 case DoubleTop: |
3094 case DoubleCon: | 3152 case DoubleCon: |
3095 case DoubleBot: | 3153 case DoubleBot: |
3154 case NarrowOop: | |
3096 case Bottom: // Ye Olde Default | 3155 case Bottom: // Ye Olde Default |
3097 return Type::BOTTOM; | 3156 return Type::BOTTOM; |
3098 case Top: | 3157 case Top: |
3099 return this; | 3158 return this; |
3100 | 3159 |
3291 return make( _ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id ); | 3350 return make( _ptr, _const_oop, _ary, _klass, _klass_is_exact, xadd_offset(offset), _instance_id ); |
3292 } | 3351 } |
3293 | 3352 |
3294 | 3353 |
3295 //============================================================================= | 3354 //============================================================================= |
3355 const TypeNarrowOop *TypeNarrowOop::BOTTOM; | |
3356 const TypeNarrowOop *TypeNarrowOop::NULL_PTR; | |
3357 | |
3358 | |
3359 const TypeNarrowOop* TypeNarrowOop::make(const TypePtr* type) { | |
3360 return (const TypeNarrowOop*)(new TypeNarrowOop(type))->hashcons(); | |
3361 } | |
3362 | |
3363 //------------------------------hash------------------------------------------- | |
3364 // Type-specific hashing function. | |
3365 int TypeNarrowOop::hash(void) const { | |
3366 return _ooptype->hash() + 7; | |
3367 } | |
3368 | |
3369 | |
3370 bool TypeNarrowOop::eq( const Type *t ) const { | |
3371 const TypeNarrowOop* tc = t->isa_narrowoop(); | |
3372 if (tc != NULL) { | |
3373 if (_ooptype->base() != tc->_ooptype->base()) { | |
3374 return false; | |
3375 } | |
3376 return tc->_ooptype->eq(_ooptype); | |
3377 } | |
3378 return false; | |
3379 } | |
3380 | |
3381 bool TypeNarrowOop::singleton(void) const { // TRUE if type is a singleton | |
3382 return _ooptype->singleton(); | |
3383 } | |
3384 | |
3385 bool TypeNarrowOop::empty(void) const { | |
3386 return _ooptype->empty(); | |
3387 } | |
3388 | |
3389 //------------------------------meet------------------------------------------- | |
3390 // Compute the MEET of two types. It returns a new Type object. | |
3391 const Type *TypeNarrowOop::xmeet( const Type *t ) const { | |
3392 // Perform a fast test for common case; meeting the same types together. | |
3393 if( this == t ) return this; // Meeting same type-rep? | |
3394 | |
3395 | |
3396 // Current "this->_base" is OopPtr | |
3397 switch (t->base()) { // switch on original type | |
3398 | |
3399 case Int: // Mixing ints & oops happens when javac | |
3400 case Long: // reuses local variables | |
3401 case FloatTop: | |
3402 case FloatCon: | |
3403 case FloatBot: | |
3404 case DoubleTop: | |
3405 case DoubleCon: | |
3406 case DoubleBot: | |
3407 case Bottom: // Ye Olde Default | |
3408 return Type::BOTTOM; | |
3409 case Top: | |
3410 return this; | |
3411 | |
3412 case NarrowOop: { | |
3413 const Type* result = _ooptype->xmeet(t->is_narrowoop()->make_oopptr()); | |
3414 if (result->isa_ptr()) { | |
3415 return TypeNarrowOop::make(result->is_ptr()); | |
3416 } | |
3417 return result; | |
3418 } | |
3419 | |
3420 default: // All else is a mistake | |
3421 typerr(t); | |
3422 | |
3423 case RawPtr: | |
3424 case AnyPtr: | |
3425 case OopPtr: | |
3426 case InstPtr: | |
3427 case KlassPtr: | |
3428 case AryPtr: | |
3429 typerr(t); | |
3430 return Type::BOTTOM; | |
3431 | |
3432 } // End of switch | |
3433 } | |
3434 | |
3435 const Type *TypeNarrowOop::xdual() const { // Compute dual right now. | |
3436 const TypePtr* odual = _ooptype->dual()->is_ptr(); | |
3437 return new TypeNarrowOop(odual); | |
3438 } | |
3439 | |
3440 const Type *TypeNarrowOop::filter( const Type *kills ) const { | |
3441 if (kills->isa_narrowoop()) { | |
3442 const Type* ft =_ooptype->filter(kills->is_narrowoop()->_ooptype); | |
3443 if (ft->empty()) | |
3444 return Type::TOP; // Canonical empty value | |
3445 if (ft->isa_ptr()) { | |
3446 return make(ft->isa_ptr()); | |
3447 } | |
3448 return ft; | |
3449 } else if (kills->isa_ptr()) { | |
3450 const Type* ft = _ooptype->join(kills); | |
3451 if (ft->empty()) | |
3452 return Type::TOP; // Canonical empty value | |
3453 return ft; | |
3454 } else { | |
3455 return Type::TOP; | |
3456 } | |
3457 } | |
3458 | |
3459 | |
3460 intptr_t TypeNarrowOop::get_con() const { | |
3461 return _ooptype->get_con(); | |
3462 } | |
3463 | |
3464 #ifndef PRODUCT | |
3465 void TypeNarrowOop::dump2( Dict & d, uint depth, outputStream *st ) const { | |
3466 tty->print("narrowoop: "); | |
3467 _ooptype->dump2(d, depth, st); | |
3468 } | |
3469 #endif | |
3470 | |
3471 | |
3472 //============================================================================= | |
3296 // Convenience common pre-built types. | 3473 // Convenience common pre-built types. |
3297 | 3474 |
3298 // Not-null object klass or below | 3475 // Not-null object klass or below |
3299 const TypeKlassPtr *TypeKlassPtr::OBJECT; | 3476 const TypeKlassPtr *TypeKlassPtr::OBJECT; |
3300 const TypeKlassPtr *TypeKlassPtr::OBJECT_OR_NULL; | 3477 const TypeKlassPtr *TypeKlassPtr::OBJECT_OR_NULL; |
3339 | 3516 |
3340 // Oops, need to compute _klass and cache it | 3517 // Oops, need to compute _klass and cache it |
3341 ciKlass* k_ary = NULL; | 3518 ciKlass* k_ary = NULL; |
3342 const TypeInstPtr *tinst; | 3519 const TypeInstPtr *tinst; |
3343 const TypeAryPtr *tary; | 3520 const TypeAryPtr *tary; |
3521 const Type* el = elem(); | |
3522 if (el->isa_narrowoop()) { | |
3523 el = el->is_narrowoop()->make_oopptr(); | |
3524 } | |
3525 | |
3344 // Get element klass | 3526 // Get element klass |
3345 if ((tinst = elem()->isa_instptr()) != NULL) { | 3527 if ((tinst = el->isa_instptr()) != NULL) { |
3346 // Compute array klass from element klass | 3528 // Compute array klass from element klass |
3347 k_ary = ciObjArrayKlass::make(tinst->klass()); | 3529 k_ary = ciObjArrayKlass::make(tinst->klass()); |
3348 } else if ((tary = elem()->isa_aryptr()) != NULL) { | 3530 } else if ((tary = el->isa_aryptr()) != NULL) { |
3349 // Compute array klass from element klass | 3531 // Compute array klass from element klass |
3350 ciKlass* k_elem = tary->klass(); | 3532 ciKlass* k_elem = tary->klass(); |
3351 // If element type is something like bottom[], k_elem will be null. | 3533 // If element type is something like bottom[], k_elem will be null. |
3352 if (k_elem != NULL) | 3534 if (k_elem != NULL) |
3353 k_ary = ciObjArrayKlass::make(k_elem); | 3535 k_ary = ciObjArrayKlass::make(k_elem); |
3354 } else if ((elem()->base() == Type::Top) || | 3536 } else if ((el->base() == Type::Top) || |
3355 (elem()->base() == Type::Bottom)) { | 3537 (el->base() == Type::Bottom)) { |
3356 // element type of Bottom occurs from meet of basic type | 3538 // element type of Bottom occurs from meet of basic type |
3357 // and object; Top occurs when doing join on Bottom. | 3539 // and object; Top occurs when doing join on Bottom. |
3358 // Leave k_ary at NULL. | 3540 // Leave k_ary at NULL. |
3359 } else { | 3541 } else { |
3360 // Cannot compute array klass directly from basic type, | 3542 // Cannot compute array klass directly from basic type, |
3361 // since subtypes of TypeInt all have basic type T_INT. | 3543 // since subtypes of TypeInt all have basic type T_INT. |
3362 assert(!elem()->isa_int(), | 3544 assert(!el->isa_int(), |
3363 "integral arrays must be pre-equipped with a class"); | 3545 "integral arrays must be pre-equipped with a class"); |
3364 // Compute array klass directly from basic type | 3546 // Compute array klass directly from basic type |
3365 k_ary = ciTypeArrayKlass::make(elem()->basic_type()); | 3547 k_ary = ciTypeArrayKlass::make(el->basic_type()); |
3366 } | 3548 } |
3367 | 3549 |
3368 if( this != TypeAryPtr::OOPS ) | 3550 if( this != TypeAryPtr::OOPS ) |
3369 // The _klass field acts as a cache of the underlying | 3551 // The _klass field acts as a cache of the underlying |
3370 // ciKlass for this array type. In order to set the field, | 3552 // ciKlass for this array type. In order to set the field, |
3708 } | 3890 } |
3709 | 3891 |
3710 //------------------------------print_flattened-------------------------------- | 3892 //------------------------------print_flattened-------------------------------- |
3711 // Print a 'flattened' signature | 3893 // Print a 'flattened' signature |
3712 static const char * const flat_type_msg[Type::lastype] = { | 3894 static const char * const flat_type_msg[Type::lastype] = { |
3713 "bad","control","top","int","long","_", | 3895 "bad","control","top","int","long","_", "narrowoop", |
3714 "tuple:", "array:", | 3896 "tuple:", "array:", |
3715 "ptr", "rawptr", "ptr", "ptr", "ptr", "ptr", | 3897 "ptr", "rawptr", "ptr", "ptr", "ptr", "ptr", |
3716 "func", "abIO", "return_address", "mem", | 3898 "func", "abIO", "return_address", "mem", |
3717 "float_top", "ftcon:", "flt", | 3899 "float_top", "ftcon:", "flt", |
3718 "double_top", "dblcon:", "dbl", | 3900 "double_top", "dblcon:", "dbl", |