< prev index next >

src/hotspot/share/opto/parse2.cpp

Print this page

        

*** 1923,1933 **** cmp = optimize_cmp_with_klass(cmp); do_if(btest, cmp); return; } ! // Substitutability test if (a->is_ValueType()) { inc_sp(2); a = a->as_ValueType()->allocate(this, true)->get_oop(); dec_sp(2); } --- 1923,1933 ---- cmp = optimize_cmp_with_klass(cmp); do_if(btest, cmp); return; } ! // Allocate value type operands if (a->is_ValueType()) { inc_sp(2); a = a->as_ValueType()->allocate(this, true)->get_oop(); dec_sp(2); }
*** 1935,1957 **** inc_sp(2); b = b->as_ValueType()->allocate(this, true)->get_oop(); dec_sp(2); } const TypeOopPtr* ta = _gvn.type(a)->isa_oopptr(); const TypeOopPtr* tb = _gvn.type(b)->isa_oopptr(); - - if (ta == NULL || !ta->can_be_value_type_raw() || - tb == NULL || !tb->can_be_value_type_raw()) { Node* cmp = CmpP(a, b); cmp = optimize_cmp_with_klass(cmp); do_if(btest, cmp); return; } - - Node* cmp = CmpP(a, b); - cmp = optimize_cmp_with_klass(cmp); Node* eq_region = NULL; if (btest == BoolTest::eq) { do_if(btest, cmp, true); if (stopped()) { return; --- 1935,1955 ---- inc_sp(2); b = b->as_ValueType()->allocate(this, true)->get_oop(); dec_sp(2); } + // First, do a normal pointer comparison const TypeOopPtr* ta = _gvn.type(a)->isa_oopptr(); const TypeOopPtr* tb = _gvn.type(b)->isa_oopptr(); Node* cmp = CmpP(a, b); cmp = optimize_cmp_with_klass(cmp); + if (ta == NULL || !ta->can_be_value_type_raw() || + tb == NULL || !tb->can_be_value_type_raw()) { + // This is sufficient, if one of the operands can't be a value type do_if(btest, cmp); return; } Node* eq_region = NULL; if (btest == BoolTest::eq) { do_if(btest, cmp, true); if (stopped()) { return;
*** 1972,1982 **** set_control(_gvn.transform(eq_region)); return; } set_control(is_not_equal); } ! // Pointers not equal, check for values Node* ne_region = new RegionNode(6); inc_sp(2); Node* null_ctl = top(); Node* not_null_a = null_check_oop(a, &null_ctl, !too_many_traps(Deoptimization::Reason_null_check), false, false); dec_sp(2); --- 1970,1981 ---- set_control(_gvn.transform(eq_region)); return; } set_control(is_not_equal); } ! ! // Pointers are not equal, check if first operand is non-null Node* ne_region = new RegionNode(6); inc_sp(2); Node* null_ctl = top(); Node* not_null_a = null_check_oop(a, &null_ctl, !too_many_traps(Deoptimization::Reason_null_check), false, false); dec_sp(2);
*** 1994,2014 **** set_control(_gvn.transform(eq_region)); } return; } Node* is_value = is_always_locked(not_null_a); ! Node* value_mask = _gvn.MakeConX(markWord::always_locked_pattern); ! Node* is_value_cmp = _gvn.transform(new CmpXNode(is_value, value_mask)); ! Node* is_value_bol = _gvn.transform(new BoolNode(is_value_cmp, BoolTest::ne)); ! IfNode* is_value_iff = create_and_map_if(control(), is_value_bol, PROB_FAIR, COUNT_UNKNOWN); ! Node* not_value = _gvn.transform(new IfTrueNode(is_value_iff)); ! set_control(_gvn.transform(new IfFalseNode(is_value_iff))); ne_region->init_req(2, not_value); ! // One of the 2 pointers refers to a value, check if both are of ! // the same class inc_sp(2); null_ctl = top(); Node* not_null_b = null_check_oop(b, &null_ctl, !too_many_traps(Deoptimization::Reason_null_check), false, false); dec_sp(2); ne_region->init_req(3, null_ctl); --- 1993,2010 ---- set_control(_gvn.transform(eq_region)); } return; } + // First operand is non-null, check if it is a value type Node* is_value = is_always_locked(not_null_a); ! IfNode* is_value_iff = create_and_map_if(control(), is_value, PROB_FAIR, COUNT_UNKNOWN); ! Node* not_value = _gvn.transform(new IfFalseNode(is_value_iff)); ne_region->init_req(2, not_value); + set_control(_gvn.transform(new IfTrueNode(is_value_iff))); ! // The first operand is a value type, check if the second operand is non-null inc_sp(2); null_ctl = top(); Node* not_null_b = null_check_oop(b, &null_ctl, !too_many_traps(Deoptimization::Reason_null_check), false, false); dec_sp(2); ne_region->init_req(3, null_ctl);
*** 2024,2035 **** record_for_igvn(eq_region); set_control(_gvn.transform(eq_region)); } return; } ! Node* kls_a = load_object_klass(not_null_a); ! Node* kls_b = load_object_klass(not_null_b); Node* kls_cmp = CmpP(kls_a, kls_b); Node* kls_bol = _gvn.transform(new BoolNode(kls_cmp, BoolTest::ne)); IfNode* kls_iff = create_and_map_if(control(), kls_bol, PROB_FAIR, COUNT_UNKNOWN); Node* kls_ne = _gvn.transform(new IfTrueNode(kls_iff)); set_control(_gvn.transform(new IfFalseNode(kls_iff))); --- 2020,2034 ---- record_for_igvn(eq_region); set_control(_gvn.transform(eq_region)); } return; } ! ! // Check if both operands are of the same class. We don't need to clear the array property ! // bits in the klass pointer for the cmp because we know that the first operand is a value type. ! Node* kls_a = load_object_klass(not_null_a, /* clear_prop_bits = */ false); ! Node* kls_b = load_object_klass(not_null_b, /* clear_prop_bits = */ false); Node* kls_cmp = CmpP(kls_a, kls_b); Node* kls_bol = _gvn.transform(new BoolNode(kls_cmp, BoolTest::ne)); IfNode* kls_iff = create_and_map_if(control(), kls_bol, PROB_FAIR, COUNT_UNKNOWN); Node* kls_ne = _gvn.transform(new IfTrueNode(kls_iff)); set_control(_gvn.transform(new IfFalseNode(kls_iff)));
*** 2047,2060 **** record_for_igvn(eq_region); set_control(_gvn.transform(eq_region)); } return; } - // Both are values of the same class, we need to perform a - // substitutability test. Delegate to - // ValueBootstrapMethods::isSubstitutable(). Node* ne_io_phi = PhiNode::make(ne_region, i_o()); Node* mem = reset_memory(); Node* ne_mem_phi = PhiNode::make(ne_region, mem); Node* eq_io_phi = NULL; --- 2046,2058 ---- record_for_igvn(eq_region); set_control(_gvn.transform(eq_region)); } return; } + // Both operands are values types of the same class, we need to perform a + // substitutability test. Delegate to ValueBootstrapMethods::isSubstitutable(). Node* ne_io_phi = PhiNode::make(ne_region, i_o()); Node* mem = reset_memory(); Node* ne_mem_phi = PhiNode::make(ne_region, mem); Node* eq_io_phi = NULL;
< prev index next >