< prev index next >

src/hotspot/share/opto/parse2.cpp

Print this page

        

*** 1876,1893 **** void Parse::do_acmp(BoolTest::mask btest, Node* a, Node* b) { ciMethod* subst_method = ciEnv::current()->ValueBootstrapMethods_klass()->find_method(ciSymbol::isSubstitutable_name(), ciSymbol::object_object_boolean_signature()); // If current method is ValueBootstrapMethods::isSubstitutable(), // compile the acmp as a regular pointer comparison otherwise we // could call ValueBootstrapMethods::isSubstitutable() back ! if (ACmpOnValues == 0 || method() == subst_method) { Node* cmp = CmpP(a, b); cmp = optimize_cmp_with_klass(cmp); do_if(btest, cmp); return; } - if (ACmpOnValues == 3) { // Substitutability test if (a->is_ValueType()) { inc_sp(2); a = a->as_ValueType()->allocate(this, true)->get_oop(); dec_sp(2); --- 1876,1892 ---- void Parse::do_acmp(BoolTest::mask btest, Node* a, Node* b) { ciMethod* subst_method = ciEnv::current()->ValueBootstrapMethods_klass()->find_method(ciSymbol::isSubstitutable_name(), ciSymbol::object_object_boolean_signature()); // If current method is ValueBootstrapMethods::isSubstitutable(), // compile the acmp as a regular pointer comparison otherwise we // could call ValueBootstrapMethods::isSubstitutable() back ! if (!EnableValhalla || (method() == subst_method)) { Node* cmp = CmpP(a, b); 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);
*** 2075,2191 **** record_for_igvn(eq_region); set_control(_gvn.transform(eq_region)); set_i_o(_gvn.transform(eq_io_phi)); set_all_memory(_gvn.transform(eq_mem_phi)); } - - return; - } - // In the case were both operands might be value types, we need to - // use the new acmp implementation. Otherwise, i.e. if one operand - // is not a value type, we can use the old acmp implementation. - Node* cmp = C->optimize_acmp(&_gvn, a, b); - if (cmp != NULL) { - // Use optimized/old acmp - cmp = optimize_cmp_with_klass(_gvn.transform(cmp)); - do_if(btest, cmp); - return; - } - - Node* ctrl = NULL; - bool safe_for_replace = true; - if (ACmpOnValues != 1) { - // Emit old acmp before new acmp for quick a != b check - cmp = CmpP(a, b); - cmp = optimize_cmp_with_klass(_gvn.transform(cmp)); - if (btest == BoolTest::ne) { - do_if(btest, cmp, true); - if (stopped()) { - return; // Never equal - } - } else if (btest == BoolTest::eq) { - Node* is_equal = NULL; - { - PreserveJVMState pjvms(this); - do_if(btest, cmp, false, &is_equal); - if (!stopped()) { - // Not equal, skip valuetype check - ctrl = new RegionNode(3); - ctrl->init_req(1, control()); - _gvn.set_type(ctrl, Type::CONTROL); - record_for_igvn(ctrl); - safe_for_replace = false; - } - } - if (is_equal == NULL) { - assert(ctrl != NULL, "no control left"); - set_control(_gvn.transform(ctrl)); - return; // Never equal - } - set_control(is_equal); - } - } - - // Null check operand before loading the is_value bit - bool speculate = false; - if (!TypePtr::NULL_PTR->higher_equal(_gvn.type(b))) { - // Operand 'b' is never null, swap operands to avoid null check - swap(a, b); - } else if (!too_many_traps(Deoptimization::Reason_speculate_null_check)) { - // Speculate on non-nullness of one operand - if (!_gvn.type(a)->speculative_maybe_null()) { - speculate = true; - } else if (!_gvn.type(b)->speculative_maybe_null()) { - speculate = true; - swap(a, b); - } - } - inc_sp(2); - Node* null_ctl = top(); - Node* not_null_a = null_check_oop(a, &null_ctl, speculate, safe_for_replace, speculate); - assert(!stopped(), "operand is always null"); - dec_sp(2); - Node* region = new RegionNode(2); - Node* is_value = new PhiNode(region, TypeX_X); - if (null_ctl != top()) { - assert(!speculate, "should never be null"); - region->add_req(null_ctl); - is_value->add_req(_gvn.MakeConX(0)); - } - - Node* value_mask = _gvn.MakeConX(markOopDesc::always_locked_pattern); - if (ACmpOnValues == 1) { - Node* mark_addr = basic_plus_adr(not_null_a, oopDesc::mark_offset_in_bytes()); - Node* mark = make_load(NULL, mark_addr, TypeX_X, TypeX_X->basic_type(), MemNode::unordered); - Node* not_mark = _gvn.transform(new XorXNode(mark, _gvn.MakeConX(-1))); - Node* andn = _gvn.transform(new AndXNode(not_mark, value_mask)); - Node* neg_if_value = _gvn.transform(new SubXNode(andn, _gvn.MakeConX(1))); - is_value->init_req(1, _gvn.transform(new RShiftXNode(neg_if_value, _gvn.intcon(63)))); - } else { - is_value->init_req(1, is_always_locked(not_null_a)); - } - region->init_req(1, control()); - - set_control(_gvn.transform(region)); - is_value = _gvn.transform(is_value); - - if (ACmpOnValues == 1) { - // Perturbe oop if operand is a value type to make comparison fail - Node* pert = _gvn.transform(new AddPNode(a, a, is_value)); - cmp = _gvn.transform(new CmpPNode(pert, b)); - } else { - // Check for a value type because we already know that operands are equal - cmp = _gvn.transform(new CmpXNode(is_value, value_mask)); - btest = (btest == BoolTest::eq) ? BoolTest::ne : BoolTest::eq; - } - cmp = optimize_cmp_with_klass(cmp); - do_if(btest, cmp); - - if (ctrl != NULL) { - ctrl->init_req(2, control()); - set_control(_gvn.transform(ctrl)); - } } bool Parse::path_is_suitable_for_uncommon_trap(float prob) const { // Don't want to speculate on uncommon traps when running with -Xcomp if (!UseInterpreter) { --- 2074,2083 ----
< prev index next >