< prev index next >

src/hotspot/share/runtime/vframeArray.cpp

Print this page

        

@@ -56,13 +56,12 @@
      delete chunk;
   }
 }
 
 void vframeArrayElement::fill_in(compiledVFrame* vf, bool realloc_failures) {
-
-// Copy the information from the compiled vframe to the
-// interpreter frame we will be creating to replace vf
+  // Copy the information from the compiled vframe to the
+  // interpreter frame we will be creating to replace vf
 
   _method = vf->method();
   _bci    = vf->raw_bci();
   _reexecute = vf->should_reexecute();
 #ifdef ASSERT

@@ -88,11 +87,11 @@
       assert(!monitor->owner_is_scalar_replaced() || realloc_failures, "object should be reallocated already");
       BasicObjectLock* dest = _monitors->at(index);
       if (monitor->owner_is_scalar_replaced()) {
         dest->set_obj(NULL);
       } else {
-        assert(monitor->owner() == NULL || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
+        assert(monitor->owner() == NULL || monitor->owner()->is_value() || (!monitor->owner()->is_unlocked() && !monitor->owner()->has_bias_pattern()), "object must be null or locked, and unbiased");
         dest->set_obj(monitor->owner());
         monitor->lock()->move_to(monitor->owner(), dest->lock());
       }
     }
   }

@@ -190,18 +189,28 @@
     assert(is_top_frame, "reexecute allowed only for the top frame");
     bcp = method()->bcp_from(bci());
     pc  = Interpreter::deopt_reexecute_entry(method(), bcp);
   } else {
     bcp = method()->bcp_from(bci());
+    if (EnableValhalla && thread->deopt_compiled_method()->is_compiled_by_c2() &&
+        *bcp == Bytecodes::_monitorenter && exec_mode == Deoptimization::Unpack_exception) {
+      // For monitorenter, the slow path of C2 compiled code will call SharedRuntime::complete_monitor_locking_C
+      // which installs an exception and deoptimize the compiled caller if the object is a value type.
+      // Increment bci to place it in the proper exception handler range (right after monitorenter).
+      int len = Bytecodes::length_for(Bytecodes::_monitorenter);
+      int next_bci = bci() + len;
+      bcp = method()->bcp_from(next_bci);
+    }
     pc  = Interpreter::deopt_continue_after_entry(method(), bcp, callee_parameters, is_top_frame);
     use_next_mdp = true;
   }
   assert(Bytecodes::is_defined(*bcp), "must be a valid bytecode");
 
   // Monitorenter and pending exceptions:
   //
-  // For Compiler2, there should be no pending exception when deoptimizing at monitorenter
+  // Monitorenter on a value type will throw an exception in the runtime and deoptimize (handled above).
+  // Otherwise, for Compiler2, there should be no pending exception when deoptimizing at monitorenter
   // because there is no safepoint at the null pointer check (it is either handled explicitly
   // or prior to the monitorenter) and asynchronous exceptions are not made "pending" by the
   // runtime interface for the slow case (see JRT_ENTRY_FOR_MONITORENTER).  If an asynchronous
   // exception was processed, the bytecode pointer would have to be extended one bytecode beyond
   // the monitorenter to place it in the proper exception range.
< prev index next >