< 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,845 ****
string,
CHECK_NH);
}
#if defined(ASSERT) && COMPILER2_OR_JVMCI
! // See Deoptimization::deoptimize_objects_alot_loop()
class DeoptimizeObjectsALotThread : public JavaThread {
! public:
! DeoptimizeObjectsALotThread();
bool is_hidden_from_external_view() const { return true; }
};
! static void deopt_objs_alot_thread_entry(JavaThread* thread, TRAPS) {
! Deoptimization::deoptimize_objects_alot_loop();
}
! DeoptimizeObjectsALotThread::DeoptimizeObjectsALotThread()
! : JavaThread(&deopt_objs_alot_thread_entry) {
}
#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) {
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();
! }
#if defined(ASSERT) && COMPILER2_OR_JVMCI
! else {
new_thread = new DeoptimizeObjectsALotThread();
! }
#endif // ASSERT
// 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.
--- 802,897 ----
string,
CHECK_NH);
}
#if defined(ASSERT) && COMPILER2_OR_JVMCI
! // Stress testing. Revert optimizations based on escape analysis.
class DeoptimizeObjectsALotThread : public JavaThread {
!
! 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; }
};
! 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);
! }
! }
}
! // 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);
! 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
! 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,998 ****
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) {
// 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);
jobject thread_handle = JNIHandles::make_local(THREAD, thread_oop());
make_thread(deoptimizer_t, thread_handle, NULL, NULL, THREAD);
}
}
#endif // defined(ASSERT) && COMPILER2_OR_JVMCI
--- 1037,1051 ----
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) {
// Initialize and start the object deoptimizer threads
! 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 >