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