< prev index next >
src/hotspot/share/c1/c1_GraphBuilder.cpp
Print this page
*** 1239,1251 ****
void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* state_before) {
BlockBegin* tsux = block_at(stream()->get_dest());
BlockBegin* fsux = block_at(stream()->next_bci());
bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
// In case of loop invariant code motion or predicate insertion
// before the body of a loop the state is needed
! Instruction *i = append(new If(x, cond, false, y, tsux, fsux, (is_bb || compilation()->is_optimistic()) ? state_before : NULL, is_bb));
assert(i->as_Goto() == NULL ||
(i->as_Goto()->sux_at(0) == tsux && i->as_Goto()->is_safepoint() == tsux->bci() < stream()->cur_bci()) ||
(i->as_Goto()->sux_at(0) == fsux && i->as_Goto()->is_safepoint() == fsux->bci() < stream()->cur_bci()),
"safepoint state of Goto returned by canonicalizer incorrect");
--- 1239,1281 ----
void GraphBuilder::if_node(Value x, If::Condition cond, Value y, ValueStack* state_before) {
BlockBegin* tsux = block_at(stream()->get_dest());
BlockBegin* fsux = block_at(stream()->next_bci());
bool is_bb = tsux->bci() < stream()->cur_bci() || fsux->bci() < stream()->cur_bci();
+
+ bool subst_check = false;
+ if (EnableValhalla && ACmpOnValues == 3 &&
+ (stream()->cur_bc() == Bytecodes::_if_acmpeq || stream()->cur_bc() == Bytecodes::_if_acmpne) &&
+ 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
+ ValueType* left_vt = x->type();
+ ValueType* right_vt = y->type();
+ if (left_vt->is_object()) {
+ assert(right_vt->is_object(), "must be");
+ ciKlass* left_klass = x->as_loaded_klass_or_null();
+ ciKlass* right_klass = y->as_loaded_klass_or_null();
+
+ if (left_klass == NULL || right_klass == NULL) {
+ // The klass is still unloaded, or came from a Phi node. Go slow case;
+ subst_check = true;
+ } else if (left_klass->is_java_lang_Object() || left_klass->is_interface() ||
+ right_klass->is_java_lang_Object() || right_klass->is_interface()) {
+ // Either operand may be a value object, but we're not sure. Go slow case;
+ subst_check = true;
+ } else if (left_klass->is_valuetype() || right_klass->is_valuetype()) {
+ subst_check = true;
+ } else {
+ // No need to do substituability check
+ }
+ }
+ }
+
// In case of loop invariant code motion or predicate insertion
// before the body of a loop the state is needed
! Instruction *i = append(new If(x, cond, false, y, tsux, fsux, (is_bb || compilation()->is_optimistic() || subst_check) ? state_before : NULL, is_bb, subst_check));
assert(i->as_Goto() == NULL ||
(i->as_Goto()->sux_at(0) == tsux && i->as_Goto()->is_safepoint() == tsux->bci() < stream()->cur_bci()) ||
(i->as_Goto()->sux_at(0) == fsux && i->as_Goto()->is_safepoint() == fsux->bci() < stream()->cur_bci()),
"safepoint state of Goto returned by canonicalizer incorrect");
< prev index next >