--- old/src/hotspot/share/compiler/compileBroker.cpp 2020-07-12 22:24:34.831372871 +0200 +++ new/src/hotspot/share/compiler/compileBroker.cpp 2020-07-12 22:24:34.431372108 +0200 @@ -804,19 +804,64 @@ } #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 @@ -825,19 +870,26 @@ JavaThread* new_thread = NULL; { MutexLocker mu(THREAD, Threads_lock); - if (type == compiler_t) { - if (!InjectCompilerCreationFailure || comp->num_compiler_threads() == 0) { - CompilerCounters* counters = new CompilerCounters(); - new_thread = new CompilerThread(queue, counters); - } - } else if (type == sweeper_t) { - new_thread = new CodeCacheSweeperThread(); - } + 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); + } + break; + case sweeper_t: + new_thread = new CodeCacheSweeperThread(); + break; #if defined(ASSERT) && COMPILER2_OR_JVMCI - else { - new_thread = new DeoptimizeObjectsALotThread(); - } + 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 @@ -987,10 +1039,11 @@ } #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); }