Mercurial > hg > truffle
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 |