# HG changeset patch # User Thomas Wuerthinger # Date 1289591828 -3600 # Node ID 7cf1952ec5fb930f58951a397bce77e794bf8b68 # Parent d603bdbec024ef1b4d784cabeda3774450b44ff4 Added flag -XX:BootstrapC1X that precompiles Object:: and then every method in the compilation queue until it is empty. diff -r d603bdbec024 -r 7cf1952ec5fb src/share/vm/c1/c1_globals.hpp --- a/src/share/vm/c1/c1_globals.hpp Fri Nov 12 18:34:07 2010 +0100 +++ b/src/share/vm/c1/c1_globals.hpp Fri Nov 12 20:57:08 2010 +0100 @@ -35,6 +35,8 @@ \ product(bool, UseC1X, false, \ "Use C1X instead of C1") \ + product(bool, BootstrapC1X, false, \ + "Bootstrap C1X before running Java main method") \ product(intx, TraceC1X, 0, \ "Trace level for C1X") \ /* Printing */ \ diff -r d603bdbec024 -r 7cf1952ec5fb src/share/vm/compiler/compileBroker.cpp --- a/src/share/vm/compiler/compileBroker.cpp Fri Nov 12 18:34:07 2010 +0100 +++ b/src/share/vm/compiler/compileBroker.cpp Fri Nov 12 20:57:08 2010 +0100 @@ -320,7 +320,10 @@ if (is_osr) tty->print(" @ %d", osr_bci()); // print method size - tty->print_cr(" (%d bytes)", method->code_size()); + tty->print(" (%d bytes)", method->code_size()); + + // invocation count + tty->print_cr(" %d invocations", _hot_count); } @@ -477,6 +480,9 @@ _last = NULL; } + // (tw) Immediately set compiling flag. + JavaThread::current()->as_CompilerThread()->set_compiling(true); + return task; } @@ -532,6 +538,69 @@ } } +// Bootstrap the C1X compiler. Compiles all methods until compile queue is empty and no compilation is active. +void CompileBroker::bootstrap_c1x() { + Thread* THREAD = Thread::current(); + tty->print_cr("Bootstrapping C1X..."); + + C1XCompiler* compiler = C1XCompiler::instance(); + if (compiler == NULL) fatal("must use flag -XX:+UseC1X"); + + jlong start = os::javaTimeMillis(); + { + HandleMark hm; + instanceKlass* klass = (instanceKlass*)SystemDictionary::Object_klass()->klass_part(); + methodOop method = klass->find_method(vmSymbols::object_initializer_name(), vmSymbols::void_method_signature()); + CompileBroker::compile_method(method, -1, method, 0, "initial compile of object initializer", THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + fatal("error inserting object initializer into compile queue"); + } + } + int z = 0; + while (true) { + { + HandleMark hm; + ResourceMark rm; + MutexLocker locker(_method_queue->lock(), Thread::current()); + if (_method_queue->is_empty()) { + MutexLocker mu(Threads_lock); // grab Threads_lock + JavaThread* current = Threads::first(); + bool compiling = false; + while (current != NULL) { + if (current->is_Compiler_thread()) { + CompilerThread* comp_thread = current->as_CompilerThread(); + if (comp_thread->is_compiling()) { + if (TraceC1X >= 4) { + tty->print_cr("Compile queue empty, but following thread is still compiling:"); + comp_thread->print(); + } + compiling = true; + } + } + current = current->next(); + } + if (!compiling) { + break; + } + } + if (TraceC1X >= 4) { + _method_queue->print(); + } + } + + { + ThreadToNativeFromVM trans(JavaThread::current()); + usleep(1000); + } + ++z; + } + jlong diff = os::javaTimeMillis() - start; + tty->print_cr("Finished bootstrap in %d ms", diff); + if (CITime) CompileBroker::print_times(); + tty->print_cr("==========================================================================="); +} + // ------------------------------------------------------------------ // CompileBroker::compilation_init @@ -863,14 +932,14 @@ // Acquire our lock. { MutexLocker locker(_method_queue->lock(), THREAD); -/* - if (Thread::current()->is_Compiler_thread() && CompilerThread::current()->is_compiling()) { - - TRACE_C1X_1("Recursive compile %s!", method->name_and_sig_as_C_string()); - //method->set_not_compilable(); - return; - } -*/ + + if (Thread::current()->is_Compiler_thread() && CompilerThread::current()->is_compiling() && !BackgroundCompilation) { + + TRACE_C1X_1("Recursive compile %s!", method->name_and_sig_as_C_string()); + method->set_not_compilable(); + return; + } + // Make sure the method has not slipped into the queues since // last we checked; note that those checks were "fast bail-outs". // Here we need to be more careful, see 14012000 below. @@ -1352,6 +1421,9 @@ while (true) { { + // Unset compiling flag. + thread->set_compiling(false); + // We need this HandleMark to avoid leaking VM handles. HandleMark hm(thread); diff -r d603bdbec024 -r 7cf1952ec5fb src/share/vm/compiler/compileBroker.hpp --- a/src/share/vm/compiler/compileBroker.hpp Fri Nov 12 18:34:07 2010 +0100 +++ b/src/share/vm/compiler/compileBroker.hpp Fri Nov 12 20:57:08 2010 +0100 @@ -358,4 +358,6 @@ static void print_last_compile(); static void print_compiler_threads_on(outputStream* st); + + static void bootstrap_c1x(); }; diff -r d603bdbec024 -r 7cf1952ec5fb src/share/vm/prims/jni.cpp --- a/src/share/vm/prims/jni.cpp Fri Nov 12 18:34:07 2010 +0100 +++ b/src/share/vm/prims/jni.cpp Fri Nov 12 20:57:08 2010 +0100 @@ -3295,6 +3295,11 @@ } // Check if we should compile all classes on bootclasspath NOT_PRODUCT(if (CompileTheWorld) ClassLoader::compile_the_world();) + + if (BootstrapC1X) { + CompileBroker::bootstrap_c1x(); + } + // Since this is not a JVM_ENTRY we have to set the thread state manually before leaving. ThreadStateTransition::transition_and_fence(thread, _thread_in_vm, _thread_in_native); } else { diff -r d603bdbec024 -r 7cf1952ec5fb src/share/vm/runtime/thread.cpp --- a/src/share/vm/runtime/thread.cpp Fri Nov 12 18:34:07 2010 +0100 +++ b/src/share/vm/runtime/thread.cpp Fri Nov 12 20:57:08 2010 +0100 @@ -2799,6 +2799,7 @@ _task = NULL; _queue = queue; _counters = counters; + _is_compiling = false; #ifndef PRODUCT _ideal_graph_printer = NULL;