< prev index next >
src/hotspot/share/opto/macro.cpp
Print this page
@@ -2416,10 +2416,52 @@
// Optimize test; set region slot 2
slow_path = opt_bits_test(ctrl, region, 2, flock, 0, 0);
mem_phi->init_req(2, mem);
}
+ const TypeOopPtr* objptr = _igvn.type(obj)->make_oopptr();
+ if (objptr->can_be_value_type()) {
+ // Deoptimize and re-execute if a value
+ assert(EnableValhalla, "should only be used if value types are enabled");
+ Node* mark = make_load(slow_path, mem, obj, oopDesc::mark_offset_in_bytes(), TypeX_X, TypeX_X->basic_type());
+ Node* value_mask = _igvn.MakeConX(markOopDesc::always_locked_pattern);
+ Node* is_value = _igvn.transform(new AndXNode(mark, value_mask));
+ Node* cmp = _igvn.transform(new CmpXNode(is_value, value_mask));
+ Node* bol = _igvn.transform(new BoolNode(cmp, BoolTest::eq));
+ Node* unc_ctrl = generate_slow_guard(&slow_path, bol, NULL);
+
+ int trap_request = Deoptimization::make_trap_request(Deoptimization::Reason_class_check, Deoptimization::Action_none);
+ address call_addr = SharedRuntime::uncommon_trap_blob()->entry_point();
+ const TypePtr* no_memory_effects = NULL;
+ JVMState* jvms = lock->jvms();
+ CallNode* unc = new CallStaticJavaNode(OptoRuntime::uncommon_trap_Type(), call_addr, "uncommon_trap",
+ jvms->bci(), no_memory_effects);
+
+ unc->init_req(TypeFunc::Control, unc_ctrl);
+ unc->init_req(TypeFunc::I_O, lock->i_o());
+ unc->init_req(TypeFunc::Memory, mem); // may gc ptrs
+ unc->init_req(TypeFunc::FramePtr, lock->in(TypeFunc::FramePtr));
+ unc->init_req(TypeFunc::ReturnAdr, lock->in(TypeFunc::ReturnAdr));
+ unc->init_req(TypeFunc::Parms+0, _igvn.intcon(trap_request));
+ unc->set_cnt(PROB_UNLIKELY_MAG(4));
+ copy_call_debug_info(lock, unc);
+
+ assert(unc->peek_monitor_box() == box, "wrong monitor");
+ assert(unc->peek_monitor_obj() == obj, "wrong monitor");
+
+ // pop monitor and push obj back on stack: we trap before the monitorenter
+ unc->pop_monitor();
+ unc->grow_stack(unc->jvms(), 1);
+ unc->set_stack(unc->jvms(), unc->jvms()->stk_size()-1, obj);
+
+ _igvn.register_new_node_with_optimizer(unc);
+
+ Node* ctrl = _igvn.transform(new ProjNode(unc, TypeFunc::Control));
+ Node* halt = _igvn.transform(new HaltNode(ctrl, lock->in(TypeFunc::FramePtr)));
+ C->root()->add_req(halt);
+ }
+
// Make slow path call
CallNode *call = make_slow_call((CallNode *) lock, OptoRuntime::complete_monitor_enter_Type(),
OptoRuntime::complete_monitor_locking_Java(), NULL, slow_path,
obj, box, NULL);
< prev index next >