< prev index next >
src/hotspot/share/opto/parse2.cpp
Print this page
@@ -1923,11 +1923,11 @@
cmp = optimize_cmp_with_klass(cmp);
do_if(btest, cmp);
return;
}
- // Substitutability test
+ // Allocate value type operands
if (a->is_ValueType()) {
inc_sp(2);
a = a->as_ValueType()->allocate(this, true)->get_oop();
dec_sp(2);
}
@@ -1935,23 +1935,21 @@
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();
-
- 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);
+ 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* 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;
@@ -1972,11 +1970,12 @@
set_control(_gvn.transform(eq_region));
return;
}
set_control(is_not_equal);
}
- // Pointers not equal, check for values
+
+ // 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,21 +1993,18 @@
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);
- 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)));
+ 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)));
- // One of the 2 pointers refers to a value, check if both are of
- // the same class
+ // 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,12 +2020,15 @@
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);
+
+ // 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,14 +2046,13 @@
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().
+ // 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 >