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