comparison src/share/vm/opto/memnode.cpp @ 6725:da91efe96a93

6964458: Reimplement class meta-data storage to use native memory Summary: Remove PermGen, allocate meta-data in metaspace linked to class loaders, rewrite GC walking, rewrite and rename metadata to be C++ classes Reviewed-by: jmasa, stefank, never, coleenp, kvn, brutisso, mgerdin, dholmes, jrose, twisti, roland Contributed-by: jmasa <jon.masamitsu@oracle.com>, stefank <stefan.karlsson@oracle.com>, mgerdin <mikael.gerdin@oracle.com>, never <tom.rodriguez@oracle.com>
author coleenp
date Sat, 01 Sep 2012 13:25:18 -0400
parents 8c92982cbbc4
children 7eca5de9e0b6
comparison
equal deleted inserted replaced
6724:36d1d483d5d6 6725:da91efe96a93
839 uint LoadNode::size_of() const { return sizeof(*this); } 839 uint LoadNode::size_of() const { return sizeof(*this); }
840 uint LoadNode::cmp( const Node &n ) const 840 uint LoadNode::cmp( const Node &n ) const
841 { return !Type::cmp( _type, ((LoadNode&)n)._type ); } 841 { return !Type::cmp( _type, ((LoadNode&)n)._type ); }
842 const Type *LoadNode::bottom_type() const { return _type; } 842 const Type *LoadNode::bottom_type() const { return _type; }
843 uint LoadNode::ideal_reg() const { 843 uint LoadNode::ideal_reg() const {
844 return Matcher::base2reg[_type->base()]; 844 return _type->ideal_reg();
845 } 845 }
846 846
847 #ifndef PRODUCT 847 #ifndef PRODUCT
848 void LoadNode::dump_spec(outputStream *st) const { 848 void LoadNode::dump_spec(outputStream *st) const {
849 MemNode::dump_spec(st); 849 MemNode::dump_spec(st);
1658 // (Folds up type checking code.) 1658 // (Folds up type checking code.)
1659 assert(Opcode() == Op_LoadI, "must load an int from _super_check_offset"); 1659 assert(Opcode() == Op_LoadI, "must load an int from _super_check_offset");
1660 return TypeInt::make(klass->super_check_offset()); 1660 return TypeInt::make(klass->super_check_offset());
1661 } 1661 }
1662 // Compute index into primary_supers array 1662 // Compute index into primary_supers array
1663 juint depth = (tkls->offset() - in_bytes(Klass::primary_supers_offset())) / sizeof(klassOop); 1663 juint depth = (tkls->offset() - in_bytes(Klass::primary_supers_offset())) / sizeof(Klass*);
1664 // Check for overflowing; use unsigned compare to handle the negative case. 1664 // Check for overflowing; use unsigned compare to handle the negative case.
1665 if( depth < ciKlass::primary_super_limit() ) { 1665 if( depth < ciKlass::primary_super_limit() ) {
1666 // The field is an element of Klass::_primary_supers. Return its (constant) value. 1666 // The field is an element of Klass::_primary_supers. Return its (constant) value.
1667 // (Folds up type checking code.) 1667 // (Folds up type checking code.)
1668 assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers"); 1668 assert(Opcode() == Op_LoadKlass, "must load a klass from _primary_supers");
1688 1688
1689 // We can still check if we are loading from the primary_supers array at a 1689 // We can still check if we are loading from the primary_supers array at a
1690 // shallow enough depth. Even though the klass is not exact, entries less 1690 // shallow enough depth. Even though the klass is not exact, entries less
1691 // than or equal to its super depth are correct. 1691 // than or equal to its super depth are correct.
1692 if (klass->is_loaded() ) { 1692 if (klass->is_loaded() ) {
1693 ciType *inner = klass->klass(); 1693 ciType *inner = klass;
1694 while( inner->is_obj_array_klass() ) 1694 while( inner->is_obj_array_klass() )
1695 inner = inner->as_obj_array_klass()->base_element_type(); 1695 inner = inner->as_obj_array_klass()->base_element_type();
1696 if( inner->is_instance_klass() && 1696 if( inner->is_instance_klass() &&
1697 !inner->as_instance_klass()->flags().is_interface() ) { 1697 !inner->as_instance_klass()->flags().is_interface() ) {
1698 // Compute index into primary_supers array 1698 // Compute index into primary_supers array
1699 juint depth = (tkls->offset() - in_bytes(Klass::primary_supers_offset())) / sizeof(klassOop); 1699 juint depth = (tkls->offset() - in_bytes(Klass::primary_supers_offset())) / sizeof(Klass*);
1700 // Check for overflowing; use unsigned compare to handle the negative case. 1700 // Check for overflowing; use unsigned compare to handle the negative case.
1701 if( depth < ciKlass::primary_super_limit() && 1701 if( depth < ciKlass::primary_super_limit() &&
1702 depth <= klass->super_depth() ) { // allow self-depth checks to handle self-check case 1702 depth <= klass->super_depth() ) { // allow self-depth checks to handle self-check case
1703 // The field is an element of Klass::_primary_supers. Return its (constant) value. 1703 // The field is an element of Klass::_primary_supers. Return its (constant) value.
1704 // (Folds up type checking code.) 1704 // (Folds up type checking code.)
1889 // Polymorphic factory method: 1889 // Polymorphic factory method:
1890 Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) { 1890 Node *LoadKlassNode::make( PhaseGVN& gvn, Node *mem, Node *adr, const TypePtr* at, const TypeKlassPtr *tk ) {
1891 Compile* C = gvn.C; 1891 Compile* C = gvn.C;
1892 Node *ctl = NULL; 1892 Node *ctl = NULL;
1893 // sanity check the alias category against the created node type 1893 // sanity check the alias category against the created node type
1894 const TypeOopPtr *adr_type = adr->bottom_type()->isa_oopptr(); 1894 const TypePtr *adr_type = adr->bottom_type()->isa_ptr();
1895 assert(adr_type != NULL, "expecting TypeOopPtr"); 1895 assert(adr_type != NULL, "expecting TypeKlassPtr");
1896 #ifdef _LP64 1896 #ifdef _LP64
1897 if (adr_type->is_ptr_to_narrowoop()) { 1897 if (adr_type->is_ptr_to_narrowoop()) {
1898 assert(UseCompressedKlassPointers, "no compressed klasses");
1898 Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop())); 1899 Node* load_klass = gvn.transform(new (C, 3) LoadNKlassNode(ctl, mem, adr, at, tk->make_narrowoop()));
1899 return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr()); 1900 return new (C, 2) DecodeNNode(load_klass, load_klass->bottom_type()->make_ptr());
1900 } 1901 }
1901 #endif 1902 #endif
1902 assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop"); 1903 assert(!adr_type->is_ptr_to_narrowoop(), "should have got back a narrow oop");
2063 if (allocated_klass != NULL) { 2064 if (allocated_klass != NULL) {
2064 return allocated_klass; 2065 return allocated_klass;
2065 } 2066 }
2066 } 2067 }
2067 2068
2068 // Simplify k.java_mirror.as_klass to plain k, where k is a klassOop. 2069 // Simplify k.java_mirror.as_klass to plain k, where k is a Klass*.
2069 // Simplify ak.component_mirror.array_klass to plain ak, ak an arrayKlass. 2070 // Simplify ak.component_mirror.array_klass to plain ak, ak an arrayKlass.
2070 // See inline_native_Class_query for occurrences of these patterns. 2071 // See inline_native_Class_query for occurrences of these patterns.
2071 // Java Example: x.getClass().isAssignableFrom(y) 2072 // Java Example: x.getClass().isAssignableFrom(y)
2072 // Java Example: Array.newInstance(x.getClass().getComponentType(), n) 2073 // Java Example: Array.newInstance(x.getClass().getComponentType(), n)
2073 // 2074 //
2074 // This improves reflective code, often making the Class 2075 // This improves reflective code, often making the Class
2075 // mirror go completely dead. (Current exception: Class 2076 // mirror go completely dead. (Current exception: Class
2076 // mirrors may appear in debug info, but we could clean them out by 2077 // mirrors may appear in debug info, but we could clean them out by
2077 // introducing a new debug info operator for klassOop.java_mirror). 2078 // introducing a new debug info operator for Klass*.java_mirror).
2078 if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass() 2079 if (toop->isa_instptr() && toop->klass() == phase->C->env()->Class_klass()
2079 && (offset == java_lang_Class::klass_offset_in_bytes() || 2080 && (offset == java_lang_Class::klass_offset_in_bytes() ||
2080 offset == java_lang_Class::array_klass_offset_in_bytes())) { 2081 offset == java_lang_Class::array_klass_offset_in_bytes())) {
2081 // We are loading a special hidden field from a Class mirror, 2082 // We are loading a special hidden field from a Class mirror,
2082 // the field which points to its Klass or arrayKlass metaobject. 2083 // the field which points to its Klass or arrayKlass metaobject.
2221 case T_CHAR: 2222 case T_CHAR:
2222 case T_SHORT: return new (C, 4) StoreCNode(ctl, mem, adr, adr_type, val); 2223 case T_SHORT: return new (C, 4) StoreCNode(ctl, mem, adr, adr_type, val);
2223 case T_LONG: return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val); 2224 case T_LONG: return new (C, 4) StoreLNode(ctl, mem, adr, adr_type, val);
2224 case T_FLOAT: return new (C, 4) StoreFNode(ctl, mem, adr, adr_type, val); 2225 case T_FLOAT: return new (C, 4) StoreFNode(ctl, mem, adr, adr_type, val);
2225 case T_DOUBLE: return new (C, 4) StoreDNode(ctl, mem, adr, adr_type, val); 2226 case T_DOUBLE: return new (C, 4) StoreDNode(ctl, mem, adr, adr_type, val);
2227 case T_METADATA:
2226 case T_ADDRESS: 2228 case T_ADDRESS:
2227 case T_OBJECT: 2229 case T_OBJECT:
2228 #ifdef _LP64 2230 #ifdef _LP64
2229 if (adr->bottom_type()->is_ptr_to_narrowoop() || 2231 if (adr->bottom_type()->is_ptr_to_narrowoop() ||
2230 (UseCompressedOops && val->bottom_type()->isa_klassptr() && 2232 (UseCompressedKlassPointers && val->bottom_type()->isa_klassptr() &&
2231 adr->bottom_type()->isa_rawptr())) { 2233 adr->bottom_type()->isa_rawptr())) {
2232 val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop())); 2234 val = gvn.transform(new (C, 2) EncodePNode(val, val->bottom_type()->make_narrowoop()));
2233 return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val); 2235 return new (C, 4) StoreNNode(ctl, mem, adr, adr_type, val);
2234 } else 2236 } else
2235 #endif 2237 #endif