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;
|