< prev index next >

src/hotspot/share/runtime/deoptimization.cpp

Print this page
rev 54697 : imported patch 8221734-v2-merge

@@ -772,14 +772,39 @@
 
 
   return bt;
 JRT_END
 
+class DeoptimizeMarkedTC : public ThreadClosure {
+ bool _in_handshake;
+ public:
+  DeoptimizeMarkedTC(bool in_handshake) : _in_handshake(in_handshake) {}
+  virtual void do_thread(Thread* thread) {
+    assert(thread->is_Java_thread(), "must be");
+    JavaThread* jt = (JavaThread*)thread;
+    jt->deoptimize_marked_methods(_in_handshake);
+  }
+};
+
+void Deoptimization::deoptimize_all_marked() {
+  ResourceMark rm;
+  DeoptimizationMarker dm;
 
-int Deoptimization::deoptimize_dependents() {
-  Threads::deoptimized_wrt_marked_nmethods();
-  return 0;
+  if (SafepointSynchronize::is_at_safepoint()) {
+    DeoptimizeMarkedTC deopt(false);
+    // Make the dependent methods not entrant
+    CodeCache::make_marked_nmethods_not_entrant();
+    Threads::java_threads_do(&deopt);
+  } else {
+    // Make the dependent methods not entrant
+    {
+      MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
+      CodeCache::make_marked_nmethods_not_entrant();
+    }
+    DeoptimizeMarkedTC deopt(true);
+    Handshake::execute(&deopt);
+  }
 }
 
 Deoptimization::DeoptAction Deoptimization::_unloaded_action
   = Deoptimization::Action_reinterpret;
 

@@ -1239,18 +1264,11 @@
       objects_to_revoke->append(Handle(thread, mon_info->owner()));
     }
   }
 }
 
-
-void Deoptimization::revoke_biases_of_monitors(JavaThread* thread, frame fr, RegisterMap* map) {
-  if (!UseBiasedLocking) {
-    return;
-  }
-
-  GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
-
+static void get_monitors_from_stack(GrowableArray<Handle>* objects_to_revoke, JavaThread* thread, frame fr, RegisterMap* map) {
   // Unfortunately we don't have a RegisterMap available in most of
   // the places we want to call this routine so we need to walk the
   // stack again to update the register map.
   if (map == NULL || !map->update_map()) {
     StackFrameStream sfs(thread, true);

@@ -1270,18 +1288,44 @@
   while (!cvf->is_top()) {
     collect_monitors(cvf, objects_to_revoke);
     cvf = compiledVFrame::cast(cvf->sender());
   }
   collect_monitors(cvf, objects_to_revoke);
+}
+
+void Deoptimization::inflate_monitors(JavaThread* thread, frame fr, RegisterMap* map) {
+  if (!UseBiasedLocking) {
+    return;
+  }
+  GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
+  get_monitors_from_stack(objects_to_revoke, thread, fr, map);
 
   if (SafepointSynchronize::is_at_safepoint()) {
     BiasedLocking::revoke_at_safepoint(objects_to_revoke);
   } else {
     BiasedLocking::revoke(objects_to_revoke);
   }
 }
 
+void Deoptimization::inflate_monitors_handshake(JavaThread* thread, frame fr, RegisterMap* map) {
+  if (!UseBiasedLocking) {
+    return;
+  }
+  GrowableArray<Handle>* objects_to_revoke = new GrowableArray<Handle>();
+  get_monitors_from_stack(objects_to_revoke, thread, fr, map);
+
+  int len = objects_to_revoke->length();
+  for (int i = 0; i < len; i++) {
+    oop obj = (objects_to_revoke->at(i))();
+    markOop mark = obj->mark();
+    assert(!mark->has_bias_pattern() || mark->biased_locker() == thread, "Can't revoke");
+    BiasedLocking::revoke_and_rebias_in_handshake(objects_to_revoke->at(i), thread);
+    assert(!obj->mark()->has_bias_pattern(), "biases should be revoked by now");
+    ObjectSynchronizer::inflate(thread, obj, ObjectSynchronizer::inflate_cause_vm_internal);
+  }
+}
+
 
 void Deoptimization::deoptimize_single_frame(JavaThread* thread, frame fr, Deoptimization::DeoptReason reason) {
   assert(fr.can_be_deoptimized(), "checking frame type");
 
   gather_statistics(reason, Action_none, Bytecodes::_illegal);

@@ -1306,25 +1350,34 @@
   // Patch the compiled method so that when execution returns to it we will
   // deopt the execution state and return to the interpreter.
   fr.deoptimize(thread);
 }
 
-void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map) {
-  deoptimize(thread, fr, map, Reason_constraint);
+void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, bool in_handshake) {
+  deopt_thread(in_handshake, thread, fr, map, Reason_constraint);
 }
 
 void Deoptimization::deoptimize(JavaThread* thread, frame fr, RegisterMap *map, DeoptReason reason) {
+  deopt_thread(false, thread, fr, map, reason);
+}
+
+void Deoptimization::deopt_thread(bool in_handshake, JavaThread* thread,
+                                  frame fr, RegisterMap *map, DeoptReason reason) {
   // Deoptimize only if the frame comes from compile code.
   // Do not deoptimize the frame which is already patched
   // during the execution of the loops below.
   if (!fr.is_compiled_frame() || fr.is_deoptimized_frame()) {
     return;
   }
   ResourceMark rm;
   DeoptimizationMarker dm;
   if (UseBiasedLocking) {
-    revoke_biases_of_monitors(thread, fr, map);
+    if (in_handshake) {
+      inflate_monitors_handshake(thread, fr, map);
+    } else {
+      inflate_monitors(thread, fr, map);
+    }
   }
   deoptimize_single_frame(thread, fr, reason);
 
 }
 

@@ -1485,11 +1538,11 @@
 
   {
     ResourceMark rm;
 
     // Revoke biases of any monitors in the frame to ensure we can migrate them
-    revoke_biases_of_monitors(thread, fr, &reg_map);
+    fix_monitors(thread, fr, &reg_map);
 
     DeoptReason reason = trap_request_reason(trap_request);
     DeoptAction action = trap_request_action(trap_request);
 #if INCLUDE_JVMCI
     int debug_id = trap_request_debug_id(trap_request);
< prev index next >