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