src/share/vm/compiler/compileBroker.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/compiler/compileBroker.cpp Thu Oct 23 13:40:55 2014
--- new/src/share/vm/compiler/compileBroker.cpp Thu Oct 23 13:40:53 2014
*** 154,165 ****
--- 154,163 ----
long CompileBroker::_peak_compilation_time = 0;
CompileQueue* CompileBroker::_c2_compile_queue = NULL;
CompileQueue* CompileBroker::_c1_compile_queue = NULL;
GrowableArray<CompilerThread*>* CompileBroker::_compiler_threads = NULL;
class CompilationLog : public StringEventLog {
public:
CompilationLog() : StringEventLog("Compilation events") {
}
*** 647,663 ****
--- 645,658 ----
// Wake up all threads that block on the queue.
lock()->notify_all();
}
// ------------------------------------------------------------------
// CompileQueue::get
! //
// Get the next CompileTask from a CompileQueue
+ /**
+ * Get the next CompileTask from a CompileQueue
! */
CompileTask* CompileQueue::get() {
NMethodSweeper::possibly_sweep();
MutexLocker locker(lock());
// If _first is NULL we have no more compile jobs. There are two reasons for
// having no compile jobs: First, we compiled everything we wanted. Second,
// we ran out of code cache so compilation has been disabled. In the latter
// case we perform code cache sweeps to free memory such that we can re-enable
*** 666,693 ****
--- 661,670 ----
// Exit loop if compilation is disabled forever
if (CompileBroker::is_compilation_disabled_forever()) {
return NULL;
}
if (UseCodeCacheFlushing && !CompileBroker::should_compile_new_jobs()) {
// Wait a certain amount of time to possibly do another sweep.
// We must wait until stack scanning has happened so that we can
// transition a method's state from 'not_entrant' to 'zombie'.
long wait_time = NmethodSweepCheckInterval * 1000;
if (FLAG_IS_DEFAULT(NmethodSweepCheckInterval)) {
// Only one thread at a time can do sweeping. Scale the
// wait time according to the number of compiler threads.
// As a result, the next sweep is likely to happen every 100ms
// with an arbitrary number of threads that do sweeping.
wait_time = 100 * CICompilerCount;
}
bool timeout = lock()->wait(!Mutex::_no_safepoint_check_flag, wait_time);
if (timeout) {
MutexUnlocker ul(lock());
NMethodSweeper::possibly_sweep();
}
} else {
// If there are no compilation tasks and we can compile new jobs
// (i.e., there is enough free space in the code cache) there is
// no need to invoke the sweeper. As a result, the hotness of methods
// remains unchanged. This behavior is desired, since we want to keep
// the stable state, i.e., we do not want to evict methods from the
*** 695,705 ****
--- 672,681 ----
// We need a timed wait here, since compiler threads can exit if compilation
// is disabled forever. We use 5 seconds wait time; the exiting of compiler threads
// is not critical and we do not want idle compiler threads to wake up too often.
lock()->wait(!Mutex::_no_safepoint_check_flag, 5*1000);
}
}
if (CompileBroker::is_compilation_disabled_forever()) {
return NULL;
}
*** 884,895 ****
--- 860,871 ----
int c2_count = 1;
_compilers[1] = new SharkCompiler();
#endif // SHARK
! // Start the CompilerThreads
! init_compiler_threads(c1_count, c2_count);
! // Start the compiler thread(s) and the sweeper thread
! init_compiler_sweeper_threads(c1_count, c2_count);
// totalTime performance counter is always created as it is required
// by the implementation of java.lang.management.CompilationMBean.
{
EXCEPTION_MARK;
_perf_total_compilation =
*** 989,1005 ****
--- 965,978 ----
_initialized = true;
}
! CompilerThread* CompileBroker::make_compiler_thread(const char* name, CompileQueue* queue, CompilerCounters* counters,
! AbstractCompiler* comp, TRAPS) {
! CompilerThread* compiler_thread = NULL;
Klass* k =
SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(),
true, CHECK_0);
! JavaThread* CompileBroker::make_thread(const char* name, CompileQueue* queue, CompilerCounters* counters,
! AbstractCompiler* comp, bool compiler_thread, TRAPS) {
! JavaThread* thread = NULL;
+ Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::java_lang_Thread(), true, CHECK_0);
instanceKlassHandle klass (THREAD, k);
instanceHandle thread_oop = klass->allocate_instance_handle(CHECK_0);
Handle string = java_lang_String::create_from_str(name, CHECK_0);
// Initialize thread_oop to put it into the system threadGroup
*** 1013,1023 ****
--- 986,1000 ----
string,
CHECK_0);
{
MutexLocker mu(Threads_lock, THREAD);
compiler_thread = new CompilerThread(queue, counters);
+ if (compiler_thread) {
+ thread = new CompilerThread(queue, counters);
+ } else {
+ thread = new CodeCacheSweeperThread();
+ }
// 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.
*** 1026,1041 ****
--- 1003,1018 ----
// At this point it may be possible that no osthread was created for the
// JavaThread due to lack of memory. We would have to throw an exception
// in that case. However, since this must work and we do not allow
// exceptions anyway, check and abort if this fails.
! if (compiler_thread == NULL || compiler_thread->osthread() == NULL){
! if (thread == NULL || thread->osthread() == NULL) {
vm_exit_during_initialization("java.lang.OutOfMemoryError",
os::native_thread_creation_failed_msg());
}
- java_lang_Thread::set_thread(thread_oop(), compiler_thread);
// Note that this only sets the JavaThread _priority field, which by
// definition is limited to Java priorities and not OS priorities.
// The os-priority is set in the CompilerThread startup code itself
*** 1052,1079 ****
--- 1029,1058 ----
native_prio = os::java_to_os_priority[CriticalPriority];
} else {
native_prio = os::java_to_os_priority[NearMaxPriority];
}
}
- os::set_native_priority(compiler_thread, native_prio);
java_lang_Thread::set_daemon(thread_oop());
- compiler_thread->set_threadObj(thread_oop());
compiler_thread->set_compiler(comp);
! Threads::add(compiler_thread);
Thread::start(compiler_thread);
+ if (compiler_thread) {
! thread->as_CompilerThread()->set_compiler(comp);
+ }
+ Threads::add(thread);
+ Thread::start(thread);
}
// Let go of Threads_lock before yielding
os::naked_yield(); // make sure that the compiler thread is started early (especially helpful on SOLARIS)
- return compiler_thread;
}
! void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) {
! void CompileBroker::init_compiler_sweeper_threads(int c1_compiler_count, int c2_compiler_count) {
EXCEPTION_MARK;
#if !defined(ZERO) && !defined(SHARK)
assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?");
#endif // !ZERO && !SHARK
// Initialize the compilation queue
*** 1086,1120 ****
--- 1065,1100 ----
_compilers[0]->set_num_compiler_threads(c1_compiler_count);
}
int compiler_count = c1_compiler_count + c2_compiler_count;
_compiler_threads =
new (ResourceObj::C_HEAP, mtCompiler) GrowableArray<CompilerThread*>(compiler_count, true);
char name_buffer[256];
+ const bool compiler_thread = true;
for (int i = 0; i < c2_compiler_count; i++) {
// Create a name for our thread.
sprintf(name_buffer, "C2 CompilerThread%d", i);
CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
// Shark and C2
! CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], CHECK);
_compiler_threads->append(new_thread);
! make_thread(name_buffer, _c2_compile_queue, counters, _compilers[1], compiler_thread, CHECK);
}
for (int i = c2_compiler_count; i < compiler_count; i++) {
// Create a name for our thread.
sprintf(name_buffer, "C1 CompilerThread%d", i);
CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
// C1
! CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_compile_queue, counters, _compilers[0], CHECK);
_compiler_threads->append(new_thread);
! make_thread(name_buffer, _c1_compile_queue, counters, _compilers[0], compiler_thread, CHECK);
}
if (UsePerfData) {
PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, compiler_count, CHECK);
}
+
+ if (MethodFlushing) {
+ // Initialize the sweeper thread
+ make_thread("Sweeper thread", NULL, NULL, NULL, false, CHECK);
+ }
}
/**
* Set the methods on the stack as on_stack so that redefine classes doesn't
*** 1757,1782 ****
--- 1737,1756 ----
// space in the code cache to generate the necessary stubs, etc.
while (!is_compilation_disabled_forever()) {
// We need this HandleMark to avoid leaking VM handles.
HandleMark hm(thread);
// Check if the CodeCache is full
int code_blob_type = 0;
if (CodeCache::is_full(&code_blob_type)) {
// The CodeHeap for code_blob_type is really full
handle_full_code_cache(code_blob_type);
}
CompileTask* task = queue->get();
if (task == NULL) {
continue;
}
// Give compiler threads an extra quanta. They tend to be bursty and
// this helps the compiler to finish up the job.
! if( CompilerThreadHintNoPreempt )
! if (CompilerThreadHintNoPreempt) {
os::hint_no_preempt();
+ }
// trace per thread time and compile statistics
CompilerCounters* counters = ((CompilerThread*)thread)->counters();
PerfTraceTimedEvent(counters->time_counter(), counters->compile_counter());
*** 2072,2083 ****
--- 2046,2059 ----
}
#endif
}
/**
! * The CodeCache is full. Print out warning and disable compilation
! * or try code cache cleaning so compilation can continue later.
! * The CodeCache is full. Print warning and disable compilation.
! * Schedule code cache cleaning so compilation can continue later.
+ * This function needs to be called only from CodeCache::allocate(),
+ * since we currently handle a full code cache uniformly.
*/
void CompileBroker::handle_full_code_cache(int code_blob_type) {
UseInterpreter = true;
if (UseCompiler || AlwaysCompileLoopMethods ) {
if (xtty != NULL) {
*** 2105,2118 ****
--- 2081,2090 ----
if (UseCodeCacheFlushing) {
// Since code cache is full, immediately stop new compiles
if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
NMethodSweeper::log_sweep("disable_compiler");
}
// Switch to 'vm_state'. This ensures that possibly_sweep() can be called
// without having to consider the state in which the current thread is.
ThreadInVMfromUnknown in_vm;
NMethodSweeper::possibly_sweep();
} else {
disable_compilation_forever();
}
CodeCache::report_codemem_full(code_blob_type, should_print_compiler_warning());
src/share/vm/compiler/compileBroker.cpp
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File