changeset 1454:7cf1952ec5fb

Added flag -XX:BootstrapC1X that precompiles Object::<init> and then every method in the compilation queue until it is empty.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Fri, 12 Nov 2010 20:57:08 +0100
parents d603bdbec024
children dc114f680d9c a8f9f091c219
files src/share/vm/c1/c1_globals.hpp src/share/vm/compiler/compileBroker.cpp src/share/vm/compiler/compileBroker.hpp src/share/vm/prims/jni.cpp src/share/vm/runtime/thread.cpp
diffstat 5 files changed, 91 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- 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 */                                                            \
--- 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);
 
--- 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();
 };
--- 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 {
--- 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;