src/share/vm/opto/graphKit.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File 7118863 Sdiff src/share/vm/opto

src/share/vm/opto/graphKit.cpp

Print this page




2287       {
2288         // Just do a direct pointer compare and be done.
2289         Node* cmp = _gvn.transform( new(C, 3) CmpPNode(subklass, superklass) );
2290         Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) );
2291         IfNode* iff = create_and_xform_if(control(), bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
2292         set_control( _gvn.transform( new(C, 1) IfTrueNode (iff) ) );
2293         return       _gvn.transform( new(C, 1) IfFalseNode(iff) );
2294       }
2295     case SSC_full_test:
2296       break;
2297     default:
2298       ShouldNotReachHere();
2299     }
2300   }
2301 
2302   // %%% Possible further optimization:  Even if the superklass is not exact,
2303   // if the subklass is the unique subtype of the superklass, the check
2304   // will always succeed.  We could leave a dependency behind to ensure this.
2305 
2306   // First load the super-klass's check-offset
2307   Node *p1 = basic_plus_adr( superklass, superklass, sizeof(oopDesc) + Klass::super_check_offset_offset_in_bytes() );
2308   Node *chk_off = _gvn.transform( new (C, 3) LoadINode( NULL, memory(p1), p1, _gvn.type(p1)->is_ptr() ) );
2309   int cacheoff_con = sizeof(oopDesc) + Klass::secondary_super_cache_offset_in_bytes();
2310   bool might_be_cache = (find_int_con(chk_off, cacheoff_con) == cacheoff_con);
2311 
2312   // Load from the sub-klass's super-class display list, or a 1-word cache of
2313   // the secondary superclass list, or a failing value with a sentinel offset
2314   // if the super-klass is an interface or exceptionally deep in the Java
2315   // hierarchy and we have to scan the secondary superclass list the hard way.
2316   // Worst-case type is a little odd: NULL is allowed as a result (usually
2317   // klass loads can never produce a NULL).
2318   Node *chk_off_X = ConvI2X(chk_off);
2319   Node *p2 = _gvn.transform( new (C, 4) AddPNode(subklass,subklass,chk_off_X) );
2320   // For some types like interfaces the following loadKlass is from a 1-word
2321   // cache which is mutable so can't use immutable memory.  Other
2322   // types load from the super-class display table which is immutable.
2323   Node *kmem = might_be_cache ? memory(p2) : immutable_memory();
2324   Node *nkls = _gvn.transform( LoadKlassNode::make( _gvn, kmem, p2, _gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL ) );
2325 
2326   // Compile speed common case: ARE a subtype and we canNOT fail
2327   if( superklass == nkls )
2328     return top();             // false path is dead; no test needed.
2329 


2917 // If the given klass is a constant or known to be an array,
2918 // fetch the constant layout helper value into constant_value
2919 // and return (Node*)NULL.  Otherwise, load the non-constant
2920 // layout helper value, and return the node which represents it.
2921 // This two-faced routine is useful because allocation sites
2922 // almost always feature constant types.
2923 Node* GraphKit::get_layout_helper(Node* klass_node, jint& constant_value) {
2924   const TypeKlassPtr* inst_klass = _gvn.type(klass_node)->isa_klassptr();
2925   if (!StressReflectiveCode && inst_klass != NULL) {
2926     ciKlass* klass = inst_klass->klass();
2927     bool    xklass = inst_klass->klass_is_exact();
2928     if (xklass || klass->is_array_klass()) {
2929       jint lhelper = klass->layout_helper();
2930       if (lhelper != Klass::_lh_neutral_value) {
2931         constant_value = lhelper;
2932         return (Node*) NULL;
2933       }
2934     }
2935   }
2936   constant_value = Klass::_lh_neutral_value;  // put in a known value
2937   Node* lhp = basic_plus_adr(klass_node, klass_node, Klass::layout_helper_offset_in_bytes() + sizeof(oopDesc));
2938   return make_load(NULL, lhp, TypeInt::INT, T_INT);
2939 }
2940 
2941 // We just put in an allocate/initialize with a big raw-memory effect.
2942 // Hook selected additional alias categories on the initialization.
2943 static void hook_memory_on_init(GraphKit& kit, int alias_idx,
2944                                 MergeMemNode* init_in_merge,
2945                                 Node* init_out_raw) {
2946   DEBUG_ONLY(Node* init_in_raw = init_in_merge->base_memory());
2947   assert(init_in_merge->memory_at(alias_idx) == init_in_raw, "");
2948 
2949   Node* prevmem = kit.memory(alias_idx);
2950   init_in_merge->set_memory_at(alias_idx, prevmem);
2951   kit.set_memory(init_out_raw, alias_idx);
2952 }
2953 
2954 //---------------------------set_output_for_allocation-------------------------
2955 Node* GraphKit::set_output_for_allocation(AllocateNode* alloc,
2956                                           const TypeOopPtr* oop_type) {
2957   int rawidx = Compile::AliasIdxRaw;




2287       {
2288         // Just do a direct pointer compare and be done.
2289         Node* cmp = _gvn.transform( new(C, 3) CmpPNode(subklass, superklass) );
2290         Node* bol = _gvn.transform( new(C, 2) BoolNode(cmp, BoolTest::eq) );
2291         IfNode* iff = create_and_xform_if(control(), bol, PROB_STATIC_FREQUENT, COUNT_UNKNOWN);
2292         set_control( _gvn.transform( new(C, 1) IfTrueNode (iff) ) );
2293         return       _gvn.transform( new(C, 1) IfFalseNode(iff) );
2294       }
2295     case SSC_full_test:
2296       break;
2297     default:
2298       ShouldNotReachHere();
2299     }
2300   }
2301 
2302   // %%% Possible further optimization:  Even if the superklass is not exact,
2303   // if the subklass is the unique subtype of the superklass, the check
2304   // will always succeed.  We could leave a dependency behind to ensure this.
2305 
2306   // First load the super-klass's check-offset
2307   Node *p1 = basic_plus_adr( superklass, superklass, Klass::super_check_offset_offset_in_bytes() );
2308   Node *chk_off = _gvn.transform( new (C, 3) LoadINode( NULL, memory(p1), p1, _gvn.type(p1)->is_ptr() ) );
2309   int cacheoff_con = Klass::secondary_super_cache_offset_in_bytes();
2310   bool might_be_cache = (find_int_con(chk_off, cacheoff_con) == cacheoff_con);
2311 
2312   // Load from the sub-klass's super-class display list, or a 1-word cache of
2313   // the secondary superclass list, or a failing value with a sentinel offset
2314   // if the super-klass is an interface or exceptionally deep in the Java
2315   // hierarchy and we have to scan the secondary superclass list the hard way.
2316   // Worst-case type is a little odd: NULL is allowed as a result (usually
2317   // klass loads can never produce a NULL).
2318   Node *chk_off_X = ConvI2X(chk_off);
2319   Node *p2 = _gvn.transform( new (C, 4) AddPNode(subklass,subklass,chk_off_X) );
2320   // For some types like interfaces the following loadKlass is from a 1-word
2321   // cache which is mutable so can't use immutable memory.  Other
2322   // types load from the super-class display table which is immutable.
2323   Node *kmem = might_be_cache ? memory(p2) : immutable_memory();
2324   Node *nkls = _gvn.transform( LoadKlassNode::make( _gvn, kmem, p2, _gvn.type(p2)->is_ptr(), TypeKlassPtr::OBJECT_OR_NULL ) );
2325 
2326   // Compile speed common case: ARE a subtype and we canNOT fail
2327   if( superklass == nkls )
2328     return top();             // false path is dead; no test needed.
2329 


2917 // If the given klass is a constant or known to be an array,
2918 // fetch the constant layout helper value into constant_value
2919 // and return (Node*)NULL.  Otherwise, load the non-constant
2920 // layout helper value, and return the node which represents it.
2921 // This two-faced routine is useful because allocation sites
2922 // almost always feature constant types.
2923 Node* GraphKit::get_layout_helper(Node* klass_node, jint& constant_value) {
2924   const TypeKlassPtr* inst_klass = _gvn.type(klass_node)->isa_klassptr();
2925   if (!StressReflectiveCode && inst_klass != NULL) {
2926     ciKlass* klass = inst_klass->klass();
2927     bool    xklass = inst_klass->klass_is_exact();
2928     if (xklass || klass->is_array_klass()) {
2929       jint lhelper = klass->layout_helper();
2930       if (lhelper != Klass::_lh_neutral_value) {
2931         constant_value = lhelper;
2932         return (Node*) NULL;
2933       }
2934     }
2935   }
2936   constant_value = Klass::_lh_neutral_value;  // put in a known value
2937   Node* lhp = basic_plus_adr(klass_node, klass_node, Klass::layout_helper_offset_in_bytes());
2938   return make_load(NULL, lhp, TypeInt::INT, T_INT);
2939 }
2940 
2941 // We just put in an allocate/initialize with a big raw-memory effect.
2942 // Hook selected additional alias categories on the initialization.
2943 static void hook_memory_on_init(GraphKit& kit, int alias_idx,
2944                                 MergeMemNode* init_in_merge,
2945                                 Node* init_out_raw) {
2946   DEBUG_ONLY(Node* init_in_raw = init_in_merge->base_memory());
2947   assert(init_in_merge->memory_at(alias_idx) == init_in_raw, "");
2948 
2949   Node* prevmem = kit.memory(alias_idx);
2950   init_in_merge->set_memory_at(alias_idx, prevmem);
2951   kit.set_memory(init_out_raw, alias_idx);
2952 }
2953 
2954 //---------------------------set_output_for_allocation-------------------------
2955 Node* GraphKit::set_output_for_allocation(AllocateNode* alloc,
2956                                           const TypeOopPtr* oop_type) {
2957   int rawidx = Compile::AliasIdxRaw;


src/share/vm/opto/graphKit.cpp
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File