< prev index next >

src/hotspot/share/compiler/compileBroker.cpp

Print this page
rev 60137 : 8227745: Enable Escape Analysis for Better Performance in the Presence of JVMTI Agents
Reviewed-by: mdoerr, goetz
rev 60138 : 8227745: delta webrev.5 -> webrev.6

@@ -802,44 +802,96 @@
                        string,
                        CHECK_NH);
 }
 
 #if defined(ASSERT) && COMPILER2_OR_JVMCI
-// See Deoptimization::deoptimize_objects_alot_loop()
+// Stress testing. Revert optimizations based on escape analysis.
 class DeoptimizeObjectsALotThread : public JavaThread {
- public:
-  DeoptimizeObjectsALotThread();
+
+  static void deopt_objs_alot_thread_entry(JavaThread* thread, TRAPS);
+  void deoptimize_objects_alot_loop_single();
+  void deoptimize_objects_alot_loop_all();
+
+public:
+  DeoptimizeObjectsALotThread() : JavaThread(&deopt_objs_alot_thread_entry) { }
+
   bool is_hidden_from_external_view() const      { return true; }
 };
 
-static void deopt_objs_alot_thread_entry(JavaThread* thread, TRAPS) {
-  Deoptimization::deoptimize_objects_alot_loop();
+void DeoptimizeObjectsALotThread::deopt_objs_alot_thread_entry(JavaThread* thread, TRAPS) {
+    DeoptimizeObjectsALotThread* dt = ((DeoptimizeObjectsALotThread*) thread);
+    bool enter_single_loop;
+    {
+      MonitorLocker ml(dt, EscapeBarrier_lock, Mutex::_no_safepoint_check_flag);
+      static int single_thread_count = 0;
+      enter_single_loop = single_thread_count++ < DeoptimizeObjectsALotThreadCountSingle;
+    }
+    if (enter_single_loop) {
+      dt->deoptimize_objects_alot_loop_single();
+    } else {
+      dt->deoptimize_objects_alot_loop_all();
+    }
+  }
+
+// Revert optimizations for a single deoptee_thread which gets selected round robin
+void DeoptimizeObjectsALotThread::deoptimize_objects_alot_loop_single() {
+  HandleMark hm(this);
+  while (!this->is_terminated()) {
+    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *deoptee_thread = jtiwh.next(); ) {
+      { // Begin new scope for escape barrier
+        HandleMarkCleaner hmc(this);
+        ResourceMark rm(this);
+        EscapeBarrier eb(this, deoptee_thread, true);
+        eb.deoptimize_objects(100);
+      }
+      // Now sleep after the escape barriers destructor resumed deoptee_thread.
+      sleep(DeoptimizeObjectsALotInterval);
+    }
+  }
 }
 
-DeoptimizeObjectsALotThread::DeoptimizeObjectsALotThread()
-: JavaThread(&deopt_objs_alot_thread_entry) {
+// Revert optimizations for all threads at once
+void DeoptimizeObjectsALotThread::deoptimize_objects_alot_loop_all() {
+  HandleMark hm(this);
+  while (!is_terminated()) {
+    { // Begin new scope for escape barrier
+      HandleMarkCleaner hmc(this);
+      ResourceMark rm(this);
+      EscapeBarrier eb(this, true);
+      eb.deoptimize_objects_all_threads();
+    }
+    // Now sleep after the escape barriers destructor resumed the java threads.
+    sleep(DeoptimizeObjectsALotInterval);
+  }
 }
 #endif // defined(ASSERT) && COMPILER2_OR_JVMCI
 
 
 JavaThread* CompileBroker::make_thread(ThreadType type, jobject thread_handle, CompileQueue* queue, AbstractCompiler* comp, Thread* THREAD) {
   JavaThread* new_thread = NULL;
   {
     MutexLocker mu(THREAD, Threads_lock);
-    if (type == compiler_t) {
+    switch (type) {
+      case compiler_t:
+        assert(comp != NULL, "Compiler instance missing.");
       if (!InjectCompilerCreationFailure || comp->num_compiler_threads() == 0) {
         CompilerCounters* counters = new CompilerCounters();
         new_thread = new CompilerThread(queue, counters);
       }
-    } else if (type == sweeper_t) {
+        break;
+      case sweeper_t:
       new_thread = new CodeCacheSweeperThread();
-    }
+        break;
 #if defined(ASSERT) && COMPILER2_OR_JVMCI
-    else {
+      case deoptimizer_t:
       new_thread = new DeoptimizeObjectsALotThread();
-    }
+        break;
 #endif // ASSERT
+      default:
+        ShouldNotReachHere();
+    }
+
     // At this point the new CompilerThread data-races with this startup
     // thread (which I believe is the primoridal thread and NOT the VM
     // thread).  This means Java bytecodes being executed at startup can
     // queue compile jobs which will run at whatever default priority the
     // newly created CompilerThread runs at.

@@ -985,14 +1037,15 @@
     jobject thread_handle = JNIHandles::make_local(THREAD, thread_oop());
     make_thread(sweeper_t, thread_handle, NULL, NULL, THREAD);
   }
 
 #if defined(ASSERT) && COMPILER2_OR_JVMCI
-  if (DeoptimizeObjectsALot == 2) {
+  if (DeoptimizeObjectsALot) {
     // Initialize and start the object deoptimizer threads
-    for (int thread_count = 0; thread_count < DeoptimizeObjectsALotThreadCount; thread_count++) {
-      Handle thread_oop = create_thread_oop("Deoptimize objects a lot thread", CHECK);
+    const int total_count = DeoptimizeObjectsALotThreadCountSingle + DeoptimizeObjectsALotThreadCountAll;
+    for (int count = 0; count < total_count; count++) {
+      Handle thread_oop = create_thread_oop("Deoptimize objects a lot single mode", CHECK);
       jobject thread_handle = JNIHandles::make_local(THREAD, thread_oop());
       make_thread(deoptimizer_t, thread_handle, NULL, NULL, THREAD);
     }
   }
 #endif // defined(ASSERT) && COMPILER2_OR_JVMCI
< prev index next >