diff src/share/vm/compiler/compileBroker.cpp @ 1930:2d26b0046e0d

Merge.
author Thomas Wuerthinger <wuerthinger@ssw.jku.at>
date Tue, 30 Nov 2010 14:53:30 +0100
parents 5571b97fc1ec d5d065957597
children 48bbaead8b6c
line wrap: on
line diff
--- a/src/share/vm/compiler/compileBroker.cpp	Mon Nov 29 18:32:30 2010 +0100
+++ b/src/share/vm/compiler/compileBroker.cpp	Tue Nov 30 14:53:30 2010 +0100
@@ -1,5 +1,5 @@
 /*
- * Copyright 1999-2010 Sun Microsystems, Inc.  All Rights Reserved.
+ * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -16,9 +16,9 @@
  * 2 along with this work; if not, write to the Free Software Foundation,
  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
  *
  */
 
@@ -123,20 +123,12 @@
 int CompileBroker::_sum_nmethod_size             = 0;
 int CompileBroker::_sum_nmethod_code_size        = 0;
 
-CompileQueue* CompileBroker::_method_queue   = NULL;
+CompileQueue* CompileBroker::_c2_method_queue   = NULL;
+CompileQueue* CompileBroker::_c1_method_queue   = NULL;
 CompileTask*  CompileBroker::_task_free_list = NULL;
 
 GrowableArray<CompilerThread*>* CompileBroker::_method_threads = NULL;
 
-// CompileTaskWrapper
-//
-// Assign this task to the current thread.  Deallocate the task
-// when the compilation is complete.
-class CompileTaskWrapper : StackObj {
-public:
-  CompileTaskWrapper(CompileTask* task);
-  ~CompileTaskWrapper();
-};
 
 CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) {
   CompilerThread* thread = CompilerThread::current();
@@ -246,6 +238,12 @@
              bool_to_str(_is_complete), bool_to_str(_is_success));
 }
 
+
+void CompileTask::print_compilation(outputStream *st, methodOop method, char* method_name) {
+  nmethod::print_compilation(st, method_name,/*title*/ NULL, method,
+                             is_blocking(), compile_id(), osr_bci(), comp_level());
+}
+
 // ------------------------------------------------------------------
 // CompileTask::print_line_on_error
 //
@@ -258,32 +256,13 @@
 //
 void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) {
   methodOop method = (methodOop)JNIHandles::resolve(_method);
-
   // print compiler name
   st->print("%s:", CompileBroker::compiler(comp_level())->name());
-
-  // print compilation number
-  st->print("%3d", compile_id());
-
-  // print method attributes
-  const bool is_osr = osr_bci() != CompileBroker::standard_entry_bci;
-  { const char blocking_char  = is_blocking()                      ? 'b' : ' ';
-    const char compile_type   = is_osr                             ? '%' : ' ';
-    const char sync_char      = method->is_synchronized()          ? 's' : ' ';
-    const char exception_char = method->has_exception_handler()    ? '!' : ' ';
-    const char tier_char      =
-      is_highest_tier_compile(comp_level())                        ? ' ' : ('0' + comp_level());
-    st->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, tier_char);
+  char* method_name = NULL;
+  if (method != NULL) {
+    method_name = method->name_and_sig_as_C_string(buf, buflen);
   }
-
-  // Use buf to get method name and signature
-  if (method != NULL) st->print("%s", method->name_and_sig_as_C_string(buf, buflen));
-
-  // print osr_bci if any
-  if (is_osr) st->print(" @ %d", osr_bci());
-
-  // print method size
-  st->print_cr(" (%d bytes)", method->code_size());
+  print_compilation(st, method, method_name);
 }
 
 // ------------------------------------------------------------------
@@ -298,32 +277,7 @@
 
   // print compiler name if requested
   if (CIPrintCompilerName) tty->print("%s:", CompileBroker::compiler(comp_level())->name());
-
-  // print compilation number
-  tty->print("%3d", compile_id());
-
-  // print method attributes
-  const bool is_osr = osr_bci() != CompileBroker::standard_entry_bci;
-  { const char blocking_char  = is_blocking()                      ? 'b' : ' ';
-    const char compile_type   = is_osr                             ? '%' : ' ';
-    const char sync_char      = method->is_synchronized()          ? 's' : ' ';
-    const char exception_char = method->has_exception_handler()    ? '!' : ' ';
-    const char tier_char      =
-      is_highest_tier_compile(comp_level())                        ? ' ' : ('0' + comp_level());
-    tty->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, tier_char);
-  }
-
-  // print method name
-  method->print_short_name(tty);
-
-  // print osr_bci if any
-  if (is_osr) tty->print(" @ %d", osr_bci());
-
-  // print method size
-  tty->print(" (%d bytes)", method->code_size());
-
-  // invocation count
-  tty->print_cr(" %d invocations", _hot_count);
+  print_compilation(tty, method(), NULL);
 }
 
 
@@ -402,7 +356,7 @@
   // <task_done ... stamp='1.234'>  </task>
   nmethod* nm = code();
   log->begin_elem("task_done success='%d' nmsize='%d' count='%d'",
-                  _is_success, nm == NULL ? 0 : nm->instructions_size(),
+                  _is_success, nm == NULL ? 0 : nm->content_size(),
                   method->invocation_count());
   int bec = method->backedge_count();
   if (bec != 0)  log->print(" backedge_count='%d'", bec);
@@ -430,6 +384,7 @@
   assert(lock()->owned_by_self(), "must own lock");
 
   task->set_next(NULL);
+  task->set_prev(NULL);
 
   if (_last == NULL) {
     // The compile queue is empty.
@@ -440,8 +395,10 @@
     // Append the task to the queue.
     assert(_last->next() == NULL, "not last");
     _last->set_next(task);
+    task->set_prev(_last);
     _last = task;
   }
+  ++_size;
 
   // Mark the method as being in the compile queue.
   ((methodOop)JNIHandles::resolve(task->method_handle()))->set_queued_for_compilation();
@@ -455,39 +412,62 @@
   }
 
   // Notify CompilerThreads that a task is available.
-  lock()->notify();
+  lock()->notify_all();
 }
 
-
 // ------------------------------------------------------------------
 // CompileQueue::get
 //
 // Get the next CompileTask from a CompileQueue
 CompileTask* CompileQueue::get() {
+  NMethodSweeper::possibly_sweep();
+
   MutexLocker locker(lock());
-
   // Wait for an available CompileTask.
   while (_first == NULL) {
     // There is no work to be done right now.  Wait.
-    lock()->wait();
+    if (UseCodeCacheFlushing && (!CompileBroker::should_compile_new_jobs() || CodeCache::needs_flushing())) {
+      // During the emergency sweeping periods, wake up and sweep occasionally
+      bool timedout = lock()->wait(!Mutex::_no_safepoint_check_flag, NmethodSweepCheckInterval*1000);
+      if (timedout) {
+        MutexUnlocker ul(lock());
+        // When otherwise not busy, run nmethod sweeping
+        NMethodSweeper::possibly_sweep();
+      }
+    } else {
+      // During normal operation no need to wake up on timer
+      lock()->wait();
+    }
+  }
+  CompileTask* task = CompilationPolicy::policy()->select_task(this);
+  remove(task);
+  return task;
+}
+
+void CompileQueue::remove(CompileTask* task)
+{
+   assert(lock()->owned_by_self(), "must own lock");
+  if (task->prev() != NULL) {
+    task->prev()->set_next(task->next());
+  } else {
+    // max is the first element
+    assert(task == _first, "Sanity");
+    _first = task->next();
   }
 
-  CompileTask* task = _first;
-
-  // Update queue first and last
-  _first =_first->next();
-  if (_first == NULL) {
-    _last = NULL;
+  if (task->next() != NULL) {
+    task->next()->set_prev(task->prev());
+  } else {
+    // max is the last element
+    assert(task == _last, "Sanity");
+    _last = task->prev();
   }
 
   // (tw) Immediately set compiling flag.
   JavaThread::current()->as_CompilerThread()->set_compiling(true);
-
-  return task;
-
+  --_size;
 }
 
-
 // ------------------------------------------------------------------
 // CompileQueue::print
 void CompileQueue::print() {
@@ -614,10 +594,12 @@
   _last_method_compiled[0] = '\0';
 
   // Set the interface to the current compiler(s).
+  int c1_count = CompilationPolicy::policy()->compiler_count(CompLevel_simple);
+  int c2_count = CompilationPolicy::policy()->compiler_count(CompLevel_full_optimization);
 #ifdef COMPILER1
   if (UseC1X) {
 	  _compilers[0] = new C1XCompiler();
-  } else {
+  } else if (c1_count > 0) {
 	  _compilers[0] = new Compiler();
   }
 #ifndef COMPILER2
@@ -626,19 +608,24 @@
 #endif // COMPILER1
 
 #ifdef COMPILER2
-  _compilers[1] = new C2Compiler();
-#ifndef COMPILER1
-  _compilers[0] = _compilers[1];
+  if (c2_count > 0) {
+    _compilers[1] = new C2Compiler();
+  }
+#endif // COMPILER2
+
+#ifdef SHARK
+#if defined(COMPILER1) || defined(COMPILER2)
+#error "Can't use COMPILER1 or COMPILER2 with shark"
 #endif
-#endif // COMPILER2
+  _compilers[0] = new SharkCompiler();
+  _compilers[1] = _compilers[0];
+#endif
 
   // Initialize the CompileTask free list
   _task_free_list = NULL;
 
   // Start the CompilerThreads
-  init_compiler_threads(compiler_count());
-
-
+  init_compiler_threads(c1_count, c2_count);
   // totalTime performance counter is always created as it is required
   // by the implementation of java.lang.management.CompilationMBean.
   {
@@ -826,23 +813,38 @@
 // CompileBroker::init_compiler_threads
 //
 // Initialize the compilation queue
-void CompileBroker::init_compiler_threads(int compiler_count) {
+void CompileBroker::init_compiler_threads(int c1_compiler_count, int c2_compiler_count) {
   EXCEPTION_MARK;
+  assert(c2_compiler_count > 0 || c1_compiler_count > 0, "No compilers?");
+  if (c2_compiler_count > 0) {
+    _c2_method_queue  = new CompileQueue("C2MethodQueue",  MethodCompileQueue_lock);
+  }
+  if (c1_compiler_count > 0) {
+    _c1_method_queue  = new CompileQueue("C1MethodQueue",  MethodCompileQueue_lock);
+  }
 
-  _method_queue  = new CompileQueue("MethodQueue",  MethodCompileQueue_lock);
+  int compiler_count = c1_compiler_count + c2_compiler_count;
+
   _method_threads =
     new (ResourceObj::C_HEAP) GrowableArray<CompilerThread*>(compiler_count, true);
 
   char name_buffer[256];
-  int i;
-  for (i = 0; i < compiler_count; i++) {
+  for (int i = 0; i < c2_compiler_count; i++) {
     // Create a name for our thread.
-    sprintf(name_buffer, "CompilerThread%d", i);
+    sprintf(name_buffer, "C2 CompilerThread%d", i);
     CompilerCounters* counters = new CompilerCounters("compilerThread", i, CHECK);
-
-    CompilerThread* new_thread = make_compiler_thread(name_buffer, _method_queue, counters, CHECK);
+    CompilerThread* new_thread = make_compiler_thread(name_buffer, _c2_method_queue, counters, CHECK);
     _method_threads->append(new_thread);
   }
+
+  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);
+    CompilerThread* new_thread = make_compiler_thread(name_buffer, _c1_method_queue, counters, CHECK);
+    _method_threads->append(new_thread);
+  }
+
   if (UsePerfData) {
     PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes,
                                      compiler_count, CHECK);
@@ -852,7 +854,9 @@
 // ------------------------------------------------------------------
 // CompileBroker::is_idle
 bool CompileBroker::is_idle() {
-  if (!_method_queue->is_empty()) {
+  if (_c2_method_queue != NULL && !_c2_method_queue->is_empty()) {
+    return false;
+  } else if (_c1_method_queue != NULL && !_c1_method_queue->is_empty()) {
     return false;
   } else {
     int num_threads = _method_threads->length();
@@ -915,6 +919,7 @@
     return;
   }
 
+
   // If this method is already in the compile queue, then
   // we do not block the current thread.
   if (compilation_is_in_queue(method, osr_bci)) {
@@ -932,10 +937,11 @@
   // Outputs from the following MutexLocker block:
   CompileTask* task     = NULL;
   bool         blocking = false;
+  CompileQueue* queue  = compile_queue(comp_level);
 
   // Acquire our lock.
   {
-    MutexLocker locker(_method_queue->lock(), THREAD);
+    MutexLocker locker(queue->lock(), THREAD);
 
     if (Thread::current()->is_Compiler_thread() && CompilerThread::current()->is_compiling() && !BackgroundCompilation) {
 
@@ -1008,7 +1014,7 @@
     // and in that case it's best to protect both the testing (here) of
     // these bits, and their updating (here and elsewhere) under a
     // common lock.
-    task = create_compile_task(_method_queue,
+    task = create_compile_task(queue,
                                compile_id, method,
                                osr_bci, comp_level,
                                hot_method, hot_count, comment,
@@ -1022,6 +1028,7 @@
 
 
 nmethod* CompileBroker::compile_method(methodHandle method, int osr_bci,
+                                       int comp_level,
                                        methodHandle hot_method, int hot_count,
                                        const char* comment, TRAPS) {
   // make sure arguments make sense
@@ -1030,26 +1037,9 @@
   assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods");
   assert(!instanceKlass::cast(method->method_holder())->is_not_initialized(), "method holder must be initialized");
 
-  int comp_level = CompilationPolicy::policy()->compilation_level(method, osr_bci);
-
-#ifdef TIERED
-  if (TieredCompilation && StressTieredRuntime) {
-    static int flipper = 0;
-    if (is_even(flipper++)) {
-      comp_level = CompLevel_fast_compile;
-    } else {
-      comp_level = CompLevel_full_optimization;
-    }
+  if (!TieredCompilation) {
+    comp_level = CompLevel_highest_tier;
   }
-#ifdef SPARC
-  // QQQ FIX ME
-  // C2 only returns long results in G1 and c1 doesn't understand so disallow c2
-  // compiles of long results
-  if (TieredCompilation && method()->result_type() == T_LONG) {
-    comp_level = CompLevel_fast_compile;
-  }
-#endif // SPARC
-#endif // TIERED
 
   // return quickly if possible
 
@@ -1063,12 +1053,10 @@
   if (osr_bci == InvocationEntryBci) {
     // standard compilation
     nmethod* method_code = method->code();
-    if (method_code != NULL
-#ifdef TIERED
-       && ( method_code->is_compiled_by_c2() || comp_level == CompLevel_fast_compile )
-#endif // TIERED
-      ) {
-      return method_code;
+    if (method_code != NULL) {
+      if (compilation_is_complete(method, osr_bci, comp_level)) {
+        return method_code;
+      }
     }
     if (method->is_not_compilable(comp_level)) return NULL;
 
@@ -1084,10 +1072,11 @@
     // osr compilation
 #ifndef TIERED
     // seems like an assert of dubious value
-    assert(comp_level == CompLevel_full_optimization,
+    assert(comp_level == CompLevel_highest_tier,
            "all OSR compiles are assumed to be at a single compilation lavel");
 #endif // TIERED
-    nmethod* nm = method->lookup_osr_nmethod_for(osr_bci);
+    // We accept a higher level osr method
+    nmethod* nm = method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
     if (nm != NULL) return nm;
     if (method->is_not_osr_compilable()) return NULL;
   }
@@ -1134,8 +1123,7 @@
   // If the compiler is shut off due to code cache flushing or otherwise,
   // fail out now so blocking compiles dont hang the java thread
   if (!should_compile_new_jobs() || (UseCodeCacheFlushing && CodeCache::needs_flushing())) {
-    method->invocation_counter()->decay();
-    method->backedge_counter()->decay();
+    CompilationPolicy::policy()->delay_compilation(method());
     return NULL;
   }
 
@@ -1151,7 +1139,8 @@
   }
 
   // return requested nmethod
-  return osr_bci  == InvocationEntryBci ? method->code() : method->lookup_osr_nmethod_for(osr_bci);
+  // We accept a higher level osr method
+  return osr_bci  == InvocationEntryBci ? method->code() : method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
 }
 
 
@@ -1167,7 +1156,7 @@
     if (method->is_not_osr_compilable()) {
       return true;
     } else {
-      nmethod* result = method->lookup_osr_nmethod_for(osr_bci);
+      nmethod* result = method->lookup_osr_nmethod_for(osr_bci, comp_level, true);
       return (result != NULL);
     }
   } else {
@@ -1176,15 +1165,7 @@
     } else {
       nmethod* result = method->code();
       if (result == NULL) return false;
-#ifdef TIERED
-      if (comp_level == CompLevel_fast_compile) {
-        // At worst the code is from c1
-        return true;
-      }
-      // comp level must be full opt
-      return result->is_compiled_by_c2();
-#endif // TIERED
-      return true;
+      return comp_level == result->comp_level();
     }
   }
 }
@@ -1202,11 +1183,10 @@
 // versa).  This can be remedied by a full queue search to disambiguate
 // cases.  If it is deemed profitible, this may be done.
 bool CompileBroker::compilation_is_in_queue(methodHandle method,
-                                          int          osr_bci) {
+                                            int          osr_bci) {
   return method->queued_for_compilation();
 }
 
-
 // ------------------------------------------------------------------
 // CompileBroker::compilation_is_prohibited
 //
@@ -1214,11 +1194,9 @@
 bool CompileBroker::compilation_is_prohibited(methodHandle method, int osr_bci, int comp_level) {
   bool is_native = method->is_native();
   // Some compilers may not support the compilation of natives.
-  // QQQ this needs some work ought to only record not compilable at
-  // the specified level
   if (is_native &&
       (!CICompileNatives || !compiler(comp_level)->supports_native())) {
-    method->set_not_compilable_quietly();
+    method->set_not_compilable_quietly(comp_level);
     return true;
   }
 
@@ -1257,7 +1235,7 @@
 // compilations may be numbered separately from regular compilations
 // if certain debugging flags are used.
 uint CompileBroker::assign_compile_id(methodHandle method, int osr_bci) {
-  assert(_method_queue->lock()->owner() == JavaThread::current(),
+  assert(MethodCompileQueue_lock->owner() == Thread::current(),
          "must hold the compilation queue lock");
   bool is_osr = (osr_bci != standard_entry_bci);
   assert(!method->is_native(), "no longer compile natives");
@@ -1711,7 +1689,6 @@
 #endif
 }
 
-
 // ------------------------------------------------------------------
 // CompileBroker::handle_full_code_cache
 //
@@ -1720,21 +1697,20 @@
 void CompileBroker::handle_full_code_cache() {
   UseInterpreter = true;
   if (UseCompiler || AlwaysCompileLoopMethods ) {
-    CompilerThread* thread = CompilerThread::current();
-    CompileLog* log = thread->log();
-    if (log != NULL) {
-      log->begin_elem("code_cache_full");
-      log->stamp();
-      log->end_elem();
+    if (xtty != NULL) {
+      xtty->begin_elem("code_cache_full");
+      xtty->stamp();
+      xtty->end_elem();
     }
-  #ifndef PRODUCT
-    warning("CodeCache is full. Compiler has been disabled");
+    warning("CodeCache is full. Compiler has been disabled.");
+    warning("Try increasing the code cache size using -XX:ReservedCodeCacheSize=");
+#ifndef PRODUCT
     if (CompileTheWorld || ExitOnFullCodeCache) {
       before_exit(JavaThread::current());
       exit_globals(); // will delete tty
       vm_direct_exit(CompileTheWorld ? 0 : 1);
     }
-  #endif
+#endif
     if (UseCodeCacheFlushing) {
       NMethodSweeper::handle_full_code_cache(true);
     } else {
@@ -1916,13 +1892,13 @@
     }
 
     // Collect counts of successful compilations
-    _sum_nmethod_size += code->total_size();
-    _sum_nmethod_code_size += code->code_size();
+    _sum_nmethod_size      += code->total_size();
+    _sum_nmethod_code_size += code->insts_size();
     _total_compile_count++;
 
     if (UsePerfData) {
-      _perf_sum_nmethod_size->inc(code->total_size());
-      _perf_sum_nmethod_code_size->inc(code->code_size());
+      _perf_sum_nmethod_size->inc(     code->total_size());
+      _perf_sum_nmethod_code_size->inc(code->insts_size());
       _perf_total_compile_count->inc();
     }
 
@@ -1952,12 +1928,12 @@
                 CompileBroker::_t_standard_compilation.seconds() / CompileBroker::_total_standard_compile_count);
   tty->print_cr("    On stack replacement   : %6.3f s, Average : %2.3f", CompileBroker::_t_osr_compilation.seconds(), CompileBroker::_t_osr_compilation.seconds() / CompileBroker::_total_osr_compile_count);
 
-  if (compiler(CompLevel_fast_compile)) {
-    compiler(CompLevel_fast_compile)->print_timers();
-    if (compiler(CompLevel_fast_compile) != compiler(CompLevel_highest_tier))
-      compiler(CompLevel_highest_tier)->print_timers();
+  if (compiler(CompLevel_simple) != NULL) {
+    compiler(CompLevel_simple)->print_timers();
   }
-
+  if (compiler(CompLevel_full_optimization) != NULL) {
+    compiler(CompLevel_full_optimization)->print_timers();
+  }
   tty->cr();
   int tcb = CompileBroker::_sum_osr_bytes_compiled + CompileBroker::_sum_standard_bytes_compiled;
   tty->print_cr("  Total compiled bytecodes : %6d bytes", tcb);