< prev index next >

src/hotspot/share/compiler/compileTask.cpp

Print this page
*** 20,10 ***
--- 20,11 ---
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   *
   */
  
+ #include "code/SCCache.hpp"
  #include "compiler/compilationPolicy.hpp"
  #include "compiler/compileBroker.hpp"
  #include "compiler/compileLog.hpp"
  #include "compiler/compilerDirectives.hpp"
  #include "compiler/compileTask.hpp"

*** 35,16 ***
  #include "runtime/handles.inline.hpp"
  #include "runtime/jniHandles.hpp"
  #include "runtime/mutexLocker.hpp"
  
  CompileTask*  CompileTask::_task_free_list = nullptr;
  
  /**
   * Allocate a CompileTask, from the free list if possible.
   */
  CompileTask* CompileTask::allocate() {
!   MutexLocker locker(CompileTaskAlloc_lock);
    CompileTask* task = nullptr;
  
    if (_task_free_list != nullptr) {
      task = _task_free_list;
      _task_free_list = task->next();
--- 36,17 ---
  #include "runtime/handles.inline.hpp"
  #include "runtime/jniHandles.hpp"
  #include "runtime/mutexLocker.hpp"
  
  CompileTask*  CompileTask::_task_free_list = nullptr;
+ int CompileTask::_active_tasks = 0;
  
  /**
   * Allocate a CompileTask, from the free list if possible.
   */
  CompileTask* CompileTask::allocate() {
!   MonitorLocker locker(CompileTaskAlloc_lock);
    CompileTask* task = nullptr;
  
    if (_task_free_list != nullptr) {
      task = _task_free_list;
      _task_free_list = task->next();

*** 54,18 ***
      task->set_next(nullptr);
      task->set_is_free(true);
    }
    assert(task->is_free(), "Task must be free.");
    task->set_is_free(false);
    return task;
  }
  
  /**
  * Add a task to the free list.
  */
  void CompileTask::free(CompileTask* task) {
!   MutexLocker locker(CompileTaskAlloc_lock);
    if (!task->is_free()) {
      assert(!task->lock()->is_locked(), "Should not be locked when freed");
      if ((task->_method_holder != nullptr && JNIHandles::is_weak_global_handle(task->_method_holder)) ||
          (task->_hot_method_holder != nullptr && JNIHandles::is_weak_global_handle(task->_hot_method_holder))) {
        JNIHandles::destroy_weak_global(task->_method_holder);
--- 56,19 ---
      task->set_next(nullptr);
      task->set_is_free(true);
    }
    assert(task->is_free(), "Task must be free.");
    task->set_is_free(false);
+   _active_tasks++;
    return task;
  }
  
  /**
  * Add a task to the free list.
  */
  void CompileTask::free(CompileTask* task) {
!   MonitorLocker locker(CompileTaskAlloc_lock);
    if (!task->is_free()) {
      assert(!task->lock()->is_locked(), "Should not be locked when freed");
      if ((task->_method_holder != nullptr && JNIHandles::is_weak_global_handle(task->_method_holder)) ||
          (task->_hot_method_holder != nullptr && JNIHandles::is_weak_global_handle(task->_hot_method_holder))) {
        JNIHandles::destroy_weak_global(task->_method_holder);

*** 81,52 ***
      task->_failure_reason_on_C_heap = false;
  
      task->set_is_free(true);
      task->set_next(_task_free_list);
      _task_free_list = task;
    }
  }
  
  void CompileTask::initialize(int compile_id,
                               const methodHandle& method,
                               int osr_bci,
                               int comp_level,
                               const methodHandle& hot_method,
                               int hot_count,
                               CompileTask::CompileReason compile_reason,
                               bool is_blocking) {
    assert(!_lock->is_locked(), "bad locking");
  
    Thread* thread = Thread::current();
    _compile_id = compile_id;
    _method = method();
    _method_holder = JNIHandles::make_weak_global(Handle(thread, method->method_holder()->klass_holder()));
    _osr_bci = osr_bci;
    _is_blocking = is_blocking;
-   JVMCI_ONLY(_has_waiter = CompileBroker::compiler(comp_level)->is_jvmci();)
-   JVMCI_ONLY(_blocking_jvmci_compile_state = nullptr;)
    _comp_level = comp_level;
    _num_inlined_bytecodes = 0;
  
    _waiting_count = 0;
  
    _is_complete = false;
    _is_success = false;
  
    _hot_method = nullptr;
    _hot_method_holder = nullptr;
    _hot_count = hot_count;
!   _time_queued = os::elapsed_counter();
    _time_started = 0;
    _compile_reason = compile_reason;
    _nm_content_size = 0;
-   AbstractCompiler* comp = compiler();
-   _directive = DirectivesStack::getMatchingDirective(method, comp);
    _nm_insts_size = 0;
    _nm_total_size = 0;
    _failure_reason = nullptr;
    _failure_reason_on_C_heap = false;
    _arena_bytes = 0;
  
    if (LogCompilation) {
      if (hot_method.not_null()) {
        if (hot_method == method) {
--- 84,88 ---
      task->_failure_reason_on_C_heap = false;
  
      task->set_is_free(true);
      task->set_next(_task_free_list);
      _task_free_list = task;
+     _active_tasks--;
+     if (_active_tasks == 0) {
+       locker.notify_all();
+     }
+   }
+ }
+ 
+ void CompileTask::wait_for_no_active_tasks() {
+   MonitorLocker locker(CompileTaskAlloc_lock);
+   while (_active_tasks > 0) {
+     locker.wait();
    }
  }
  
  void CompileTask::initialize(int compile_id,
                               const methodHandle& method,
                               int osr_bci,
                               int comp_level,
                               const methodHandle& hot_method,
                               int hot_count,
+                              SCCEntry* scc_entry,
                               CompileTask::CompileReason compile_reason,
+                              CompileQueue* compile_queue,
+                              bool requires_online_compilation,
                               bool is_blocking) {
    assert(!_lock->is_locked(), "bad locking");
  
    Thread* thread = Thread::current();
    _compile_id = compile_id;
    _method = method();
    _method_holder = JNIHandles::make_weak_global(Handle(thread, method->method_holder()->klass_holder()));
    _osr_bci = osr_bci;
+   _requires_online_compilation = requires_online_compilation;
    _is_blocking = is_blocking;
    _comp_level = comp_level;
    _num_inlined_bytecodes = 0;
  
    _waiting_count = 0;
  
    _is_complete = false;
    _is_success = false;
  
+   _next = nullptr;
+   _prev = nullptr;
+ 
    _hot_method = nullptr;
    _hot_method_holder = nullptr;
    _hot_count = hot_count;
!   _time_created = os::elapsed_counter();
+   _time_queued = 0;
    _time_started = 0;
+   _time_finished = 0;
+   _aot_load_start = 0;
+   _aot_load_finish = 0;
    _compile_reason = compile_reason;
    _nm_content_size = 0;
    _nm_insts_size = 0;
    _nm_total_size = 0;
    _failure_reason = nullptr;
    _failure_reason_on_C_heap = false;
+   _training_data = nullptr;
+   _scc_entry = scc_entry;
+   _compile_queue = compile_queue;
+ 
+   AbstractCompiler* comp = CompileBroker::compiler(comp_level);
+ #if INCLUDE_JVMCI
+   if (comp->is_jvmci() && CompileBroker::compiler3() != nullptr) {
+     assert(_method != nullptr, "sanity");
+     if (((JVMCICompiler*)comp)->force_comp_at_level_simple(method)) {
+       comp = CompileBroker::compiler3();
+     }
+   }
+ #endif
+   _compiler = comp;
+   _directive = DirectivesStack::getMatchingDirective(method, comp);
+ 
+   JVMCI_ONLY(_has_waiter = comp->is_jvmci();)
+   JVMCI_ONLY(_blocking_jvmci_compile_state = nullptr;)
    _arena_bytes = 0;
  
    if (LogCompilation) {
      if (hot_method.not_null()) {
        if (hot_method == method) {

*** 144,15 ***
  
  /**
   * Returns the compiler for this task.
   */
  AbstractCompiler* CompileTask::compiler() const {
!   return CompileBroker::compiler(_comp_level);
  }
  
  // Replace weak handles by strong handles to avoid unloading during compilation.
  CompileTask* CompileTask::select_for_compilation() {
    if (is_unloaded()) {
      // Guard against concurrent class unloading
      return nullptr;
    }
    Thread* thread = Thread::current();
--- 183,19 ---
  
  /**
   * Returns the compiler for this task.
   */
  AbstractCompiler* CompileTask::compiler() const {
!   assert(_compiler != nullptr, "should be set");
+   return _compiler;
  }
  
  // Replace weak handles by strong handles to avoid unloading during compilation.
  CompileTask* CompileTask::select_for_compilation() {
+   if (_compile_reason == Reason_Preload) {
+     return this;
+   }
    if (is_unloaded()) {
      // Guard against concurrent class unloading
      return nullptr;
    }
    Thread* thread = Thread::current();

*** 177,10 ***
--- 220,11 ---
      _hot_method->set_on_stack(true);
    }
  }
  
  bool CompileTask::is_unloaded() const {
+   if (preload()) return false;
    return _method_holder != nullptr && JNIHandles::is_weak_global_handle(_method_holder) && JNIHandles::is_weak_global_cleared(_method_holder);
  }
  
  // RedefineClasses support
  void CompileTask::metadata_do(MetadataClosure* f) {

*** 203,11 ***
  //
  // Otherwise it's the same as CompileTask::print_line()
  //
  void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) {
    // print compiler name
!   st->print("%s:", CompileBroker::compiler_name(comp_level()));
    print(st);
  }
  
  // ------------------------------------------------------------------
  // CompileTask::print_tty
--- 247,11 ---
  //
  // Otherwise it's the same as CompileTask::print_line()
  //
  void CompileTask::print_line_on_error(outputStream* st, char* buf, int buflen) {
    // print compiler name
!   st->print("%s:", compiler()->name());
    print(st);
  }
  
  // ------------------------------------------------------------------
  // CompileTask::print_tty

*** 217,28 ***
  }
  
  // ------------------------------------------------------------------
  // CompileTask::print_impl
  void CompileTask::print_impl(outputStream* st, Method* method, int compile_id, int comp_level,
!                              bool is_osr_method, int osr_bci, bool is_blocking,
                               const char* msg, bool short_form, bool cr,
!                              jlong time_queued, jlong time_started) {
    if (!short_form) {
!     // Print current time
!     st->print(UINT64_FORMAT " ", (uint64_t) tty->time_stamp().milliseconds());
!     if (Verbose && time_queued != 0) {
!       // Print time in queue and time being processed by compiler thread
!       jlong now = os::elapsed_counter();
!       st->print("%.0f ", TimeHelper::counter_to_millis(now-time_queued));
!       if (time_started != 0) {
!         st->print("%.0f ", TimeHelper::counter_to_millis(now-time_started));
        }
      }
    }
    // print compiler name if requested
    if (CIPrintCompilerName) {
!     st->print("%s:", CompileBroker::compiler_name(comp_level));
    }
    st->print("%4d ", compile_id);    // print compilation number
  
    bool is_synchronized = false;
    bool has_exception_handler = false;
--- 261,55 ---
  }
  
  // ------------------------------------------------------------------
  // CompileTask::print_impl
  void CompileTask::print_impl(outputStream* st, Method* method, int compile_id, int comp_level,
!                              bool is_osr_method, int osr_bci, bool is_blocking, bool is_scc, bool is_preload,
+                              const char* compiler_name,
                               const char* msg, bool short_form, bool cr,
!                              jlong time_created, jlong time_queued, jlong time_started, jlong time_finished,
+                              jlong aot_load_start, jlong aot_load_finish) {
    if (!short_form) {
!     {
!       stringStream ss;
!       ss.print(UINT64_FORMAT, (uint64_t) tty->time_stamp().milliseconds());
!       st->print("%7s ", ss.freeze());
!     }
!     { // Time waiting to be put on queue
!       stringStream ss;
!       if (time_created != 0 && time_queued != 0) {
+         ss.print("W%.1f", TimeHelper::counter_to_millis(time_queued - time_created));
+       }
+       st->print("%7s ", ss.freeze());
+     }
+     { // Time in queue
+       stringStream ss;
+       if (time_queued != 0 && time_started != 0) {
+         ss.print("Q%.1f", TimeHelper::counter_to_millis(time_started - time_queued));
+       }
+       st->print("%7s ", ss.freeze());
+     }
+     { // Time in compilation
+       stringStream ss;
+       if (time_started != 0 && time_finished != 0) {
+         ss.print("C%.1f", TimeHelper::counter_to_millis(time_finished - time_started));
        }
+       st->print("%7s ", ss.freeze());
      }
+     { // Time to load from AOT code cache
+       stringStream ss;
+       if (aot_load_start != 0 && aot_load_finish != 0) {
+         ss.print("A%.1f", TimeHelper::counter_to_millis(aot_load_finish - aot_load_start));
+       }
+       st->print("%7s ", ss.freeze());
+     }
+     st->print("  ");
    }
+ 
    // print compiler name if requested
    if (CIPrintCompilerName) {
!     st->print("%s:", compiler_name);
    }
    st->print("%4d ", compile_id);    // print compilation number
  
    bool is_synchronized = false;
    bool has_exception_handler = false;

*** 252,13 ***
    const char compile_type   = is_osr_method                   ? '%' : ' ';
    const char sync_char      = is_synchronized                 ? 's' : ' ';
    const char exception_char = has_exception_handler           ? '!' : ' ';
    const char blocking_char  = is_blocking                     ? 'b' : ' ';
    const char native_char    = is_native                       ? 'n' : ' ';
  
    // print method attributes
!   st->print("%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, native_char);
  
    if (TieredCompilation) {
      if (comp_level != -1)  st->print("%d ", comp_level);
      else                   st->print("- ");
    }
--- 323,15 ---
    const char compile_type   = is_osr_method                   ? '%' : ' ';
    const char sync_char      = is_synchronized                 ? 's' : ' ';
    const char exception_char = has_exception_handler           ? '!' : ' ';
    const char blocking_char  = is_blocking                     ? 'b' : ' ';
    const char native_char    = is_native                       ? 'n' : ' ';
+   const char scc_char       = is_scc                          ? 'A' : ' ';
+   const char preload_char   = is_preload                      ? 'P' : ' ';
  
    // print method attributes
!   st->print("%c%c%c%c%c%c%c ", compile_type, sync_char, exception_char, blocking_char, native_char, scc_char, preload_char);
  
    if (TieredCompilation) {
      if (comp_level != -1)  st->print("%d ", comp_level);
      else                   st->print("- ");
    }

*** 287,11 ***
  
  // ------------------------------------------------------------------
  // CompileTask::print_compilation
  void CompileTask::print(outputStream* st, const char* msg, bool short_form, bool cr) {
    bool is_osr_method = osr_bci() != InvocationEntryBci;
!   print_impl(st, is_unloaded() ? nullptr : method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), msg, short_form, cr, _time_queued, _time_started);
  }
  
  // ------------------------------------------------------------------
  // CompileTask::log_task
  void CompileTask::log_task(xmlStream* log) {
--- 360,12 ---
  
  // ------------------------------------------------------------------
  // CompileTask::print_compilation
  void CompileTask::print(outputStream* st, const char* msg, bool short_form, bool cr) {
    bool is_osr_method = osr_bci() != InvocationEntryBci;
!   print_impl(st, is_unloaded() ? nullptr : method(), compile_id(), comp_level(), is_osr_method, osr_bci(), is_blocking(), is_scc(), preload(),
+              compiler()->name(), msg, short_form, cr, _time_created, _time_queued, _time_started, _time_finished, _aot_load_start, _aot_load_finish);
  }
  
  // ------------------------------------------------------------------
  // CompileTask::log_task
  void CompileTask::log_task(xmlStream* log) {

*** 312,11 ***
      log->print(" level='%d'", _comp_level);
    }
    if (_is_blocking) {
      log->print(" blocking='1'");
    }
-   log->stamp();
  }
  
  // ------------------------------------------------------------------
  // CompileTask::log_task_queued
  void CompileTask::log_task_queued() {
--- 386,10 ---

*** 328,24 ***
    log_task(xtty);
    assert(_compile_reason > CompileTask::Reason_None && _compile_reason < CompileTask::Reason_Count, "Valid values");
    xtty->print(" comment='%s'", reason_name(_compile_reason));
  
    if (_hot_method != nullptr && _hot_method != _method) {
!     xtty->method(_hot_method);
    }
    if (_hot_count != 0) {
      xtty->print(" hot_count='%d'", _hot_count);
    }
    xtty->end_elem();
  }
  
  
  // ------------------------------------------------------------------
  // CompileTask::log_task_start
! void CompileTask::log_task_start(CompileLog* log)   {
    log->begin_head("task");
    log_task(log);
    log->end_head();
  }
  
  
  // ------------------------------------------------------------------
--- 401,26 ---
    log_task(xtty);
    assert(_compile_reason > CompileTask::Reason_None && _compile_reason < CompileTask::Reason_Count, "Valid values");
    xtty->print(" comment='%s'", reason_name(_compile_reason));
  
    if (_hot_method != nullptr && _hot_method != _method) {
!     xtty->method(_hot_method, "hot_");
    }
    if (_hot_count != 0) {
      xtty->print(" hot_count='%d'", _hot_count);
    }
+   xtty->stamp();
    xtty->end_elem();
  }
  
  
  // ------------------------------------------------------------------
  // CompileTask::log_task_start
! void CompileTask::log_task_start(CompileLog* log) {
    log->begin_head("task");
    log_task(log);
+   log->stamp();
    log->end_head();
  }
  
  
  // ------------------------------------------------------------------

*** 483,11 ***
    if (lt.is_enabled()) {
      LogStream ls(lt);
      print_impl(&ls, nm->method(), nm->compile_id(),
                 nm->comp_level(), nm->is_osr_method(),
                 nm->is_osr_method() ? nm->osr_entry_bci() : -1,
!                /*is_blocking*/ false,
                 msg, /* short form */ true, /* cr */ true);
    }
  }
  
  void CompileTask::print_inlining_ul(ciMethod* method, int inline_level, int bci, InliningResult result, const char* msg) {
--- 558,12 ---
    if (lt.is_enabled()) {
      LogStream ls(lt);
      print_impl(&ls, nm->method(), nm->compile_id(),
                 nm->comp_level(), nm->is_osr_method(),
                 nm->is_osr_method() ? nm->osr_entry_bci() : -1,
!                /*is_blocking*/ false, nm->scc_entry() != nullptr,
+                nm->preloaded(), nm->compiler_name(),
                 msg, /* short form */ true, /* cr */ true);
    }
  }
  
  void CompileTask::print_inlining_ul(ciMethod* method, int inline_level, int bci, InliningResult result, const char* msg) {
< prev index next >