/*
 * Copyright (c) 1999, 2023, 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
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

#include "precompiled.hpp"
#include "classfile/javaClasses.inline.hpp"
#include "classfile/symbolTable.hpp"
#include "classfile/vmClasses.hpp"
#include "classfile/vmSymbols.hpp"
#include "code/codeCache.hpp"
#include "code/codeHeapState.hpp"
#include "code/dependencyContext.hpp"
#include "compiler/compilationLog.hpp"
#include "compiler/compilationPolicy.hpp"
#include "compiler/compileBroker.hpp"
#include "compiler/compileLog.hpp"
#include "compiler/compilerEvent.hpp"
#include "compiler/compilerOracle.hpp"
#include "compiler/directivesParser.hpp"
#include "interpreter/linkResolver.hpp"
#include "jvm.h"
#include "jfr/jfrEvents.hpp"
#include "logging/log.hpp"
#include "logging/logStream.hpp"
#include "memory/allocation.inline.hpp"
#include "memory/resourceArea.hpp"
#include "memory/universe.hpp"
#include "oops/methodData.hpp"
#include "oops/method.inline.hpp"
#include "oops/oop.inline.hpp"
#include "prims/jvmtiExport.hpp"
#include "prims/nativeLookup.hpp"
#include "prims/whitebox.hpp"
#include "runtime/atomic.hpp"
#include "runtime/escapeBarrier.hpp"
#include "runtime/globals_extension.hpp"
#include "runtime/handles.inline.hpp"
#include "runtime/init.hpp"
#include "runtime/interfaceSupport.inline.hpp"
#include "runtime/java.hpp"
#include "runtime/javaCalls.hpp"
#include "runtime/jniHandles.inline.hpp"
#include "runtime/os.hpp"
#include "runtime/perfData.hpp"
#include "runtime/safepointVerifiers.hpp"
#include "runtime/sharedRuntime.hpp"
#include "runtime/threads.hpp"
#include "runtime/threadSMR.hpp"
#include "runtime/timerTrace.hpp"
#include "runtime/vframe.inline.hpp"
#include "utilities/debug.hpp"
#include "utilities/dtrace.hpp"
#include "utilities/events.hpp"
#include "utilities/formatBuffer.hpp"
#include "utilities/macros.hpp"
#ifdef COMPILER1
#include "c1/c1_Compiler.hpp"
#endif
#ifdef COMPILER2
#include "opto/c2compiler.hpp"
#endif
#if INCLUDE_JVMCI
#include "jvmci/jvmciEnv.hpp"
#include "jvmci/jvmciRuntime.hpp"
#endif

#ifdef DTRACE_ENABLED

// Only bother with this argument setup if dtrace is available

#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(method, comp_name)             \
  {                                                                      \
    Symbol* klass_name = (method)->klass_name();                         \
    Symbol* name = (method)->name();                                     \
    Symbol* signature = (method)->signature();                           \
    HOTSPOT_METHOD_COMPILE_BEGIN(                                        \
      (char *) comp_name, strlen(comp_name),                             \
      (char *) klass_name->bytes(), klass_name->utf8_length(),           \
      (char *) name->bytes(), name->utf8_length(),                       \
      (char *) signature->bytes(), signature->utf8_length());            \
  }

#define DTRACE_METHOD_COMPILE_END_PROBE(method, comp_name, success)      \
  {                                                                      \
    Symbol* klass_name = (method)->klass_name();                         \
    Symbol* name = (method)->name();                                     \
    Symbol* signature = (method)->signature();                           \
    HOTSPOT_METHOD_COMPILE_END(                                          \
      (char *) comp_name, strlen(comp_name),                             \
      (char *) klass_name->bytes(), klass_name->utf8_length(),           \
      (char *) name->bytes(), name->utf8_length(),                       \
      (char *) signature->bytes(), signature->utf8_length(), (success)); \
  }

#else //  ndef DTRACE_ENABLED

#define DTRACE_METHOD_COMPILE_BEGIN_PROBE(method, comp_name)
#define DTRACE_METHOD_COMPILE_END_PROBE(method, comp_name, success)

#endif // ndef DTRACE_ENABLED

bool CompileBroker::_initialized = false;
volatile bool CompileBroker::_should_block = false;
volatile int  CompileBroker::_print_compilation_warning = 0;
volatile jint CompileBroker::_should_compile_new_jobs = run_compilation;

// The installed compiler(s)
AbstractCompiler* CompileBroker::_compilers[2];

// The maximum numbers of compiler threads to be determined during startup.
int CompileBroker::_c1_count = 0;
int CompileBroker::_c2_count = 0;

// An array of compiler names as Java String objects
jobject* CompileBroker::_compiler1_objects = nullptr;
jobject* CompileBroker::_compiler2_objects = nullptr;

CompileLog** CompileBroker::_compiler1_logs = nullptr;
CompileLog** CompileBroker::_compiler2_logs = nullptr;

// These counters are used to assign an unique ID to each compilation.
volatile jint CompileBroker::_compilation_id     = 0;
volatile jint CompileBroker::_osr_compilation_id = 0;
volatile jint CompileBroker::_native_compilation_id = 0;

// Performance counters
PerfCounter* CompileBroker::_perf_total_compilation = nullptr;
PerfCounter* CompileBroker::_perf_osr_compilation = nullptr;
PerfCounter* CompileBroker::_perf_standard_compilation = nullptr;

PerfCounter* CompileBroker::_perf_total_bailout_count = nullptr;
PerfCounter* CompileBroker::_perf_total_invalidated_count = nullptr;
PerfCounter* CompileBroker::_perf_total_compile_count = nullptr;
PerfCounter* CompileBroker::_perf_total_osr_compile_count = nullptr;
PerfCounter* CompileBroker::_perf_total_standard_compile_count = nullptr;

PerfCounter* CompileBroker::_perf_sum_osr_bytes_compiled = nullptr;
PerfCounter* CompileBroker::_perf_sum_standard_bytes_compiled = nullptr;
PerfCounter* CompileBroker::_perf_sum_nmethod_size = nullptr;
PerfCounter* CompileBroker::_perf_sum_nmethod_code_size = nullptr;

PerfStringVariable* CompileBroker::_perf_last_method = nullptr;
PerfStringVariable* CompileBroker::_perf_last_failed_method = nullptr;
PerfStringVariable* CompileBroker::_perf_last_invalidated_method = nullptr;
PerfVariable*       CompileBroker::_perf_last_compile_type = nullptr;
PerfVariable*       CompileBroker::_perf_last_compile_size = nullptr;
PerfVariable*       CompileBroker::_perf_last_failed_type = nullptr;
PerfVariable*       CompileBroker::_perf_last_invalidated_type = nullptr;

// Timers and counters for generating statistics
elapsedTimer CompileBroker::_t_total_compilation;
elapsedTimer CompileBroker::_t_osr_compilation;
elapsedTimer CompileBroker::_t_standard_compilation;
elapsedTimer CompileBroker::_t_invalidated_compilation;
elapsedTimer CompileBroker::_t_bailedout_compilation;

int CompileBroker::_total_bailout_count            = 0;
int CompileBroker::_total_invalidated_count        = 0;
int CompileBroker::_total_compile_count            = 0;
int CompileBroker::_total_osr_compile_count        = 0;
int CompileBroker::_total_standard_compile_count   = 0;
int CompileBroker::_total_compiler_stopped_count   = 0;
int CompileBroker::_total_compiler_restarted_count = 0;

int CompileBroker::_sum_osr_bytes_compiled         = 0;
int CompileBroker::_sum_standard_bytes_compiled    = 0;
int CompileBroker::_sum_nmethod_size               = 0;
int CompileBroker::_sum_nmethod_code_size          = 0;

jlong CompileBroker::_peak_compilation_time        = 0;

CompilerStatistics CompileBroker::_stats_per_level[CompLevel_full_optimization];

CompileQueue* CompileBroker::_c2_compile_queue     = nullptr;
CompileQueue* CompileBroker::_c1_compile_queue     = nullptr;

bool compileBroker_init() {
  if (LogEvents) {
    CompilationLog::init();
  }

  // init directives stack, adding default directive
  DirectivesStack::init();

  if (DirectivesParser::has_file()) {
    return DirectivesParser::parse_from_flag();
  } else if (CompilerDirectivesPrint) {
    // Print default directive even when no other was added
    DirectivesStack::print(tty);
  }

  return true;
}

CompileTaskWrapper::CompileTaskWrapper(CompileTask* task) {
  CompilerThread* thread = CompilerThread::current();
  thread->set_task(task);
  CompileLog*     log  = thread->log();
  if (log != nullptr && !task->is_unloaded())  task->log_task_start(log);
}

CompileTaskWrapper::~CompileTaskWrapper() {
  CompilerThread* thread = CompilerThread::current();
  CompileTask* task = thread->task();
  CompileLog*  log  = thread->log();
  if (log != nullptr && !task->is_unloaded())  task->log_task_done(log);
  thread->set_task(nullptr);
  thread->set_env(nullptr);
  if (task->is_blocking()) {
    bool free_task = false;
    {
      MutexLocker notifier(thread, task->lock());
      task->mark_complete();
#if INCLUDE_JVMCI
      if (CompileBroker::compiler(task->comp_level())->is_jvmci()) {
        if (!task->has_waiter()) {
          // The waiting thread timed out and thus did not free the task.
          free_task = true;
        }
        task->set_blocking_jvmci_compile_state(nullptr);
      }
#endif
      if (!free_task) {
        // Notify the waiting thread that the compilation has completed
        // so that it can free the task.
        task->lock()->notify_all();
      }
    }
    if (free_task) {
      // The task can only be freed once the task lock is released.
      CompileTask::free(task);
    }
  } else {
    task->mark_complete();

    // By convention, the compiling thread is responsible for
    // recycling a non-blocking CompileTask.
    CompileTask::free(task);
  }
}

/**
 * Check if a CompilerThread can be removed and update count if requested.
 */
bool CompileBroker::can_remove(CompilerThread *ct, bool do_it) {
  assert(UseDynamicNumberOfCompilerThreads, "or shouldn't be here");
  if (!ReduceNumberOfCompilerThreads) return false;

  AbstractCompiler *compiler = ct->compiler();
  int compiler_count = compiler->num_compiler_threads();
  bool c1 = compiler->is_c1();

  // Keep at least 1 compiler thread of each type.
  if (compiler_count < 2) return false;

  // Keep thread alive for at least some time.
  if (ct->idle_time_millis() < (c1 ? 500 : 100)) return false;

#if INCLUDE_JVMCI
  if (compiler->is_jvmci()) {
    // Handles for JVMCI thread objects may get released concurrently.
    if (do_it) {
      assert(CompileThread_lock->owner() == ct, "must be holding lock");
    } else {
      // Skip check if it's the last thread and let caller check again.
      return true;
    }
  }
#endif

  // We only allow the last compiler thread of each type to get removed.
  jobject last_compiler = c1 ? compiler1_object(compiler_count - 1)
                             : compiler2_object(compiler_count - 1);
  if (ct->threadObj() == JNIHandles::resolve_non_null(last_compiler)) {
    if (do_it) {
      assert_locked_or_safepoint(CompileThread_lock); // Update must be consistent.
      compiler->set_num_compiler_threads(compiler_count - 1);
#if INCLUDE_JVMCI
      if (compiler->is_jvmci()) {
        // Old j.l.Thread object can die when no longer referenced elsewhere.
        JNIHandles::destroy_global(compiler2_object(compiler_count - 1));
        _compiler2_objects[compiler_count - 1] = nullptr;
      }
#endif
    }
    return true;
  }
  return false;
}

/**
 * Add a CompileTask to a CompileQueue.
 */
void CompileQueue::add(CompileTask* task) {
  assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");

  task->set_next(nullptr);
  task->set_prev(nullptr);

  if (_last == nullptr) {
    // The compile queue is empty.
    assert(_first == nullptr, "queue is empty");
    _first = task;
    _last = task;
  } else {
    // Append the task to the queue.
    assert(_last->next() == nullptr, "not last");
    _last->set_next(task);
    task->set_prev(_last);
    _last = task;
  }
  ++_size;

  // Mark the method as being in the compile queue.
  task->method()->set_queued_for_compilation();

  if (CIPrintCompileQueue) {
    print_tty();
  }

  if (LogCompilation && xtty != nullptr) {
    task->log_task_queued();
  }

  // Notify CompilerThreads that a task is available.
  MethodCompileQueue_lock->notify_all();
}

/**
 * Empties compilation queue by putting all compilation tasks onto
 * a freelist. Furthermore, the method wakes up all threads that are
 * waiting on a compilation task to finish. This can happen if background
 * compilation is disabled.
 */
void CompileQueue::free_all() {
  MutexLocker mu(MethodCompileQueue_lock);
  CompileTask* next = _first;

  // Iterate over all tasks in the compile queue
  while (next != nullptr) {
    CompileTask* current = next;
    next = current->next();
    {
      // Wake up thread that blocks on the compile task.
      MutexLocker ct_lock(current->lock());
      current->lock()->notify();
    }
    // Put the task back on the freelist.
    CompileTask::free(current);
  }
  _first = nullptr;
  _last = nullptr;

  // Wake up all threads that block on the queue.
  MethodCompileQueue_lock->notify_all();
}

/**
 * Get the next CompileTask from a CompileQueue
 */
CompileTask* CompileQueue::get(CompilerThread* thread) {
  // save methods from RedefineClasses across safepoint
  // across MethodCompileQueue_lock below.
  methodHandle save_method;
  methodHandle save_hot_method;

  MonitorLocker locker(MethodCompileQueue_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
  // compilation.
  while (_first == nullptr) {
    // Exit loop if compilation is disabled forever
    if (CompileBroker::is_compilation_disabled_forever()) {
      return nullptr;
    }

    AbstractCompiler* compiler = thread->compiler();
    guarantee(compiler != nullptr, "Compiler object must exist");
    compiler->on_empty_queue(this, thread);
    if (_first != nullptr) {
      // The call to on_empty_queue may have temporarily unlocked the MCQ lock
      // so check again whether any tasks were added to the queue.
      break;
    }

    // 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 GC.
    // 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.
    locker.wait(5*1000);

    if (UseDynamicNumberOfCompilerThreads && _first == nullptr) {
      // Still nothing to compile. Give caller a chance to stop this thread.
      if (CompileBroker::can_remove(CompilerThread::current(), false)) return nullptr;
    }
  }

  if (CompileBroker::is_compilation_disabled_forever()) {
    return nullptr;
  }

  CompileTask* task;
  {
    NoSafepointVerifier nsv;
    task = CompilationPolicy::select_task(this);
    if (task != nullptr) {
      task = task->select_for_compilation();
    }
  }

  if (task != nullptr) {
    // Save method pointers across unlock safepoint.  The task is removed from
    // the compilation queue, which is walked during RedefineClasses.
    Thread* thread = Thread::current();
    save_method = methodHandle(thread, task->method());
    save_hot_method = methodHandle(thread, task->hot_method());

    remove(task);
  }
  purge_stale_tasks(); // may temporarily release MCQ lock
  return task;
}

// Clean & deallocate stale compile tasks.
// Temporarily releases MethodCompileQueue lock.
void CompileQueue::purge_stale_tasks() {
  assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");
  if (_first_stale != nullptr) {
    // Stale tasks are purged when MCQ lock is released,
    // but _first_stale updates are protected by MCQ lock.
    // Once task processing starts and MCQ lock is released,
    // other compiler threads can reuse _first_stale.
    CompileTask* head = _first_stale;
    _first_stale = nullptr;
    {
      MutexUnlocker ul(MethodCompileQueue_lock);
      for (CompileTask* task = head; task != nullptr; ) {
        CompileTask* next_task = task->next();
        CompileTaskWrapper ctw(task); // Frees the task
        task->set_failure_reason("stale task");
        task = next_task;
      }
    }
  }
}

void CompileQueue::remove(CompileTask* task) {
  assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");
  if (task->prev() != nullptr) {
    task->prev()->set_next(task->next());
  } else {
    // max is the first element
    assert(task == _first, "Sanity");
    _first = task->next();
  }

  if (task->next() != nullptr) {
    task->next()->set_prev(task->prev());
  } else {
    // max is the last element
    assert(task == _last, "Sanity");
    _last = task->prev();
  }
  --_size;
}

void CompileQueue::remove_and_mark_stale(CompileTask* task) {
  assert(MethodCompileQueue_lock->owned_by_self(), "must own lock");
  remove(task);

  // Enqueue the task for reclamation (should be done outside MCQ lock)
  task->set_next(_first_stale);
  task->set_prev(nullptr);
  _first_stale = task;
}

// methods in the compile queue need to be marked as used on the stack
// so that they don't get reclaimed by Redefine Classes
void CompileQueue::mark_on_stack() {
  CompileTask* task = _first;
  while (task != nullptr) {
    task->mark_on_stack();
    task = task->next();
  }
}


CompileQueue* CompileBroker::compile_queue(int comp_level) {
  if (is_c2_compile(comp_level)) return _c2_compile_queue;
  if (is_c1_compile(comp_level)) return _c1_compile_queue;
  return nullptr;
}

void CompileBroker::print_compile_queues(outputStream* st) {
  st->print_cr("Current compiles: ");

  char buf[2000];
  int buflen = sizeof(buf);
  Threads::print_threads_compiling(st, buf, buflen, /* short_form = */ true);

  st->cr();
  if (_c1_compile_queue != nullptr) {
    _c1_compile_queue->print(st);
  }
  if (_c2_compile_queue != nullptr) {
    _c2_compile_queue->print(st);
  }
}

void CompileQueue::print(outputStream* st) {
  assert_locked_or_safepoint(MethodCompileQueue_lock);
  st->print_cr("%s:", name());
  CompileTask* task = _first;
  if (task == nullptr) {
    st->print_cr("Empty");
  } else {
    while (task != nullptr) {
      task->print(st, nullptr, true, true);
      task = task->next();
    }
  }
  st->cr();
}

void CompileQueue::print_tty() {
  stringStream ss;
  // Dump the compile queue into a buffer before locking the tty
  print(&ss);
  {
    ttyLocker ttyl;
    tty->print("%s", ss.freeze());
  }
}

CompilerCounters::CompilerCounters() {
  _current_method[0] = '\0';
  _compile_type = CompileBroker::no_compile;
}

#if INCLUDE_JFR && COMPILER2_OR_JVMCI
// It appends new compiler phase names to growable array phase_names(a new CompilerPhaseType mapping
// in compiler/compilerEvent.cpp) and registers it with its serializer.
//
// c2 uses explicit CompilerPhaseType idToPhase mapping in opto/phasetype.hpp,
// so if c2 is used, it should be always registered first.
// This function is called during vm initialization.
void register_jfr_phasetype_serializer(CompilerType compiler_type) {
  ResourceMark rm;
  static bool first_registration = true;
  if (compiler_type == compiler_jvmci) {
    CompilerEvent::PhaseEvent::get_phase_id("NOT_A_PHASE_NAME", false, false, false);
    first_registration = false;
#ifdef COMPILER2
  } else if (compiler_type == compiler_c2) {
    assert(first_registration, "invariant"); // c2 must be registered first.
    for (int i = 0; i < PHASE_NUM_TYPES; i++) {
      const char* phase_name = CompilerPhaseTypeHelper::to_description((CompilerPhaseType) i);
      CompilerEvent::PhaseEvent::get_phase_id(phase_name, false, false, false);
    }
    first_registration = false;
#endif // COMPILER2
  }
}
#endif // INCLUDE_JFR && COMPILER2_OR_JVMCI

// ------------------------------------------------------------------
// CompileBroker::compilation_init
//
// Initialize the Compilation object
void CompileBroker::compilation_init_phase1(JavaThread* THREAD) {
  // No need to initialize compilation system if we do not use it.
  if (!UseCompiler) {
    return;
  }
  // Set the interface to the current compiler(s).
  _c1_count = CompilationPolicy::c1_count();
  _c2_count = CompilationPolicy::c2_count();

#if INCLUDE_JVMCI
  if (EnableJVMCI) {
    // This is creating a JVMCICompiler singleton.
    JVMCICompiler* jvmci = new JVMCICompiler();

    if (UseJVMCICompiler) {
      _compilers[1] = jvmci;
      if (FLAG_IS_DEFAULT(JVMCIThreads)) {
        if (BootstrapJVMCI) {
          // JVMCI will bootstrap so give it more threads
          _c2_count = MIN2(32, os::active_processor_count());
        }
      } else {
        _c2_count = JVMCIThreads;
      }
      if (FLAG_IS_DEFAULT(JVMCIHostThreads)) {
      } else {
#ifdef COMPILER1
        _c1_count = JVMCIHostThreads;
#endif // COMPILER1
      }
    }
  }
#endif // INCLUDE_JVMCI

#ifdef COMPILER1
  if (_c1_count > 0) {
    _compilers[0] = new Compiler();
  }
#endif // COMPILER1

#ifdef COMPILER2
  if (true JVMCI_ONLY( && !UseJVMCICompiler)) {
    if (_c2_count > 0) {
      _compilers[1] = new C2Compiler();
      // Register c2 first as c2 CompilerPhaseType idToPhase mapping is explicit.
      // idToPhase mapping for c2 is in opto/phasetype.hpp
      JFR_ONLY(register_jfr_phasetype_serializer(compiler_c2);)
    }
  }
#endif // COMPILER2

#if INCLUDE_JVMCI
   // Register after c2 registration.
   // JVMCI CompilerPhaseType idToPhase mapping is dynamic.
   if (EnableJVMCI) {
     JFR_ONLY(register_jfr_phasetype_serializer(compiler_jvmci);)
   }
#endif // INCLUDE_JVMCI

  // Start the compiler thread(s)
  init_compiler_threads();
  // totalTime performance counter is always created as it is required
  // by the implementation of java.lang.management.CompilationMXBean.
  {
    // Ensure OOM leads to vm_exit_during_initialization.
    EXCEPTION_MARK;
    _perf_total_compilation =
                 PerfDataManager::create_counter(JAVA_CI, "totalTime",
                                                 PerfData::U_Ticks, CHECK);
  }

  if (UsePerfData) {

    EXCEPTION_MARK;

    // create the jvmstat performance counters
    _perf_osr_compilation =
                 PerfDataManager::create_counter(SUN_CI, "osrTime",
                                                 PerfData::U_Ticks, CHECK);

    _perf_standard_compilation =
                 PerfDataManager::create_counter(SUN_CI, "standardTime",
                                                 PerfData::U_Ticks, CHECK);

    _perf_total_bailout_count =
                 PerfDataManager::create_counter(SUN_CI, "totalBailouts",
                                                 PerfData::U_Events, CHECK);

    _perf_total_invalidated_count =
                 PerfDataManager::create_counter(SUN_CI, "totalInvalidates",
                                                 PerfData::U_Events, CHECK);

    _perf_total_compile_count =
                 PerfDataManager::create_counter(SUN_CI, "totalCompiles",
                                                 PerfData::U_Events, CHECK);
    _perf_total_osr_compile_count =
                 PerfDataManager::create_counter(SUN_CI, "osrCompiles",
                                                 PerfData::U_Events, CHECK);

    _perf_total_standard_compile_count =
                 PerfDataManager::create_counter(SUN_CI, "standardCompiles",
                                                 PerfData::U_Events, CHECK);

    _perf_sum_osr_bytes_compiled =
                 PerfDataManager::create_counter(SUN_CI, "osrBytes",
                                                 PerfData::U_Bytes, CHECK);

    _perf_sum_standard_bytes_compiled =
                 PerfDataManager::create_counter(SUN_CI, "standardBytes",
                                                 PerfData::U_Bytes, CHECK);

    _perf_sum_nmethod_size =
                 PerfDataManager::create_counter(SUN_CI, "nmethodSize",
                                                 PerfData::U_Bytes, CHECK);

    _perf_sum_nmethod_code_size =
                 PerfDataManager::create_counter(SUN_CI, "nmethodCodeSize",
                                                 PerfData::U_Bytes, CHECK);

    _perf_last_method =
                 PerfDataManager::create_string_variable(SUN_CI, "lastMethod",
                                       CompilerCounters::cmname_buffer_length,
                                       "", CHECK);

    _perf_last_failed_method =
            PerfDataManager::create_string_variable(SUN_CI, "lastFailedMethod",
                                       CompilerCounters::cmname_buffer_length,
                                       "", CHECK);

    _perf_last_invalidated_method =
        PerfDataManager::create_string_variable(SUN_CI, "lastInvalidatedMethod",
                                     CompilerCounters::cmname_buffer_length,
                                     "", CHECK);

    _perf_last_compile_type =
             PerfDataManager::create_variable(SUN_CI, "lastType",
                                              PerfData::U_None,
                                              (jlong)CompileBroker::no_compile,
                                              CHECK);

    _perf_last_compile_size =
             PerfDataManager::create_variable(SUN_CI, "lastSize",
                                              PerfData::U_Bytes,
                                              (jlong)CompileBroker::no_compile,
                                              CHECK);


    _perf_last_failed_type =
             PerfDataManager::create_variable(SUN_CI, "lastFailedType",
                                              PerfData::U_None,
                                              (jlong)CompileBroker::no_compile,
                                              CHECK);

    _perf_last_invalidated_type =
         PerfDataManager::create_variable(SUN_CI, "lastInvalidatedType",
                                          PerfData::U_None,
                                          (jlong)CompileBroker::no_compile,
                                          CHECK);
  }
}

// Completes compiler initialization. Compilation requests submitted
// prior to this will be silently ignored.
void CompileBroker::compilation_init_phase2() {
  _initialized = true;
}

Handle CompileBroker::create_thread_oop(const char* name, TRAPS) {
  Handle thread_oop = JavaThread::create_system_thread_object(name, CHECK_NH);
  return thread_oop;
}

#if defined(ASSERT) && COMPILER2_OR_JVMCI
// Stress testing. Dedicated threads revert optimizations based on escape analysis concurrently to
// the running java application.  Configured with vm options DeoptimizeObjectsALot*.
class DeoptimizeObjectsALotThread : public JavaThread {

  static void deopt_objs_alot_thread_entry(JavaThread* thread, TRAPS);
  void deoptimize_objects_alot_loop_single();
  void deoptimize_objects_alot_loop_all();

public:
  DeoptimizeObjectsALotThread() : JavaThread(&deopt_objs_alot_thread_entry) { }

  bool is_hidden_from_external_view() const      { return true; }
};

// Entry for DeoptimizeObjectsALotThread. The threads are started in
// CompileBroker::init_compiler_threads() iff DeoptimizeObjectsALot is enabled
void DeoptimizeObjectsALotThread::deopt_objs_alot_thread_entry(JavaThread* thread, TRAPS) {
    DeoptimizeObjectsALotThread* dt = ((DeoptimizeObjectsALotThread*) thread);
    bool enter_single_loop;
    {
      MonitorLocker ml(dt, EscapeBarrier_lock, Mutex::_no_safepoint_check_flag);
      static int single_thread_count = 0;
      enter_single_loop = single_thread_count++ < DeoptimizeObjectsALotThreadCountSingle;
    }
    if (enter_single_loop) {
      dt->deoptimize_objects_alot_loop_single();
    } else {
      dt->deoptimize_objects_alot_loop_all();
    }
  }

// Execute EscapeBarriers in an endless loop to revert optimizations based on escape analysis. Each
// barrier targets a single thread which is selected round robin.
void DeoptimizeObjectsALotThread::deoptimize_objects_alot_loop_single() {
  HandleMark hm(this);
  while (true) {
    for (JavaThreadIteratorWithHandle jtiwh; JavaThread *deoptee_thread = jtiwh.next(); ) {
      { // Begin new scope for escape barrier
        HandleMarkCleaner hmc(this);
        ResourceMark rm(this);
        EscapeBarrier eb(true, this, deoptee_thread);
        eb.deoptimize_objects(100);
      }
      // Now sleep after the escape barriers destructor resumed deoptee_thread.
      sleep(DeoptimizeObjectsALotInterval);
    }
  }
}

// Execute EscapeBarriers in an endless loop to revert optimizations based on escape analysis. Each
// barrier targets all java threads in the vm at once.
void DeoptimizeObjectsALotThread::deoptimize_objects_alot_loop_all() {
  HandleMark hm(this);
  while (true) {
    { // Begin new scope for escape barrier
      HandleMarkCleaner hmc(this);
      ResourceMark rm(this);
      EscapeBarrier eb(true, this);
      eb.deoptimize_objects_all_threads();
    }
    // Now sleep after the escape barriers destructor resumed the java threads.
    sleep(DeoptimizeObjectsALotInterval);
  }
}
#endif // defined(ASSERT) && COMPILER2_OR_JVMCI


JavaThread* CompileBroker::make_thread(ThreadType type, jobject thread_handle, CompileQueue* queue, AbstractCompiler* comp, JavaThread* THREAD) {
  JavaThread* new_thread = nullptr;

  switch (type) {
    case compiler_t:
      assert(comp != nullptr, "Compiler instance missing.");
      if (!InjectCompilerCreationFailure || comp->num_compiler_threads() == 0) {
        CompilerCounters* counters = new CompilerCounters();
        new_thread = new CompilerThread(queue, counters);
      }
      break;
#if defined(ASSERT) && COMPILER2_OR_JVMCI
    case deoptimizer_t:
      new_thread = new DeoptimizeObjectsALotThread();
      break;
#endif // ASSERT
    default:
      ShouldNotReachHere();
  }

  // At this point the new CompilerThread data-races with this startup
  // thread (which is the main 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.


  // At this point it may be possible that no osthread was created for the
  // JavaThread due to lack of resources. We will handle that failure below.
  // Also check new_thread so that static analysis is happy.
  if (new_thread != nullptr && new_thread->osthread() != nullptr) {
    Handle thread_oop(THREAD, JNIHandles::resolve_non_null(thread_handle));

    if (type == compiler_t) {
      CompilerThread::cast(new_thread)->set_compiler(comp);
    }

    // Note that we cannot call os::set_priority because it expects Java
    // priorities and we are *explicitly* using OS priorities so that it's
    // possible to set the compiler thread priority higher than any Java
    // thread.

    int native_prio = CompilerThreadPriority;
    if (native_prio == -1) {
      if (UseCriticalCompilerThreadPriority) {
        native_prio = os::java_to_os_priority[CriticalPriority];
      } else {
        native_prio = os::java_to_os_priority[NearMaxPriority];
      }
    }
    os::set_native_priority(new_thread, native_prio);

    // Note that this only sets the JavaThread _priority field, which by
    // definition is limited to Java priorities and not OS priorities.
    JavaThread::start_internal_daemon(THREAD, new_thread, thread_oop, NearMaxPriority);

  } else { // osthread initialization failure
    if (UseDynamicNumberOfCompilerThreads && type == compiler_t
        && comp->num_compiler_threads() > 0) {
      // The new thread is not known to Thread-SMR yet so we can just delete.
      delete new_thread;
      return nullptr;
    } else {
      vm_exit_during_initialization("java.lang.OutOfMemoryError",
                                    os::native_thread_creation_failed_msg());
    }
  }

  os::naked_yield(); // make sure that the compiler thread is started early (especially helpful on SOLARIS)

  return new_thread;
}

static bool trace_compiler_threads() {
  LogTarget(Debug, jit, thread) lt;
  return TraceCompilerThreads || lt.is_enabled();
}

static void print_compiler_threads(stringStream& msg) {
  if (TraceCompilerThreads) {
    tty->print_cr("%7d %s", (int)tty->time_stamp().milliseconds(), msg.as_string());
  }
  LogTarget(Debug, jit, thread) lt;
  if (lt.is_enabled()) {
    LogStream ls(lt);
    ls.print_cr("%s", msg.as_string());
  }
}

void CompileBroker::init_compiler_threads() {
  // Ensure any exceptions lead to vm_exit_during_initialization.
  EXCEPTION_MARK;
#if !defined(ZERO)
  assert(_c2_count > 0 || _c1_count > 0, "No compilers?");
#endif // !ZERO
  // Initialize the compilation queue
  if (_c2_count > 0) {
    const char* name = JVMCI_ONLY(UseJVMCICompiler ? "JVMCI compile queue" :) "C2 compile queue";
    _c2_compile_queue  = new CompileQueue(name);
    _compiler2_objects = NEW_C_HEAP_ARRAY(jobject, _c2_count, mtCompiler);
    _compiler2_logs = NEW_C_HEAP_ARRAY(CompileLog*, _c2_count, mtCompiler);
  }
  if (_c1_count > 0) {
    _c1_compile_queue  = new CompileQueue("C1 compile queue");
    _compiler1_objects = NEW_C_HEAP_ARRAY(jobject, _c1_count, mtCompiler);
    _compiler1_logs = NEW_C_HEAP_ARRAY(CompileLog*, _c1_count, mtCompiler);
  }

  char name_buffer[256];

  for (int i = 0; i < _c2_count; i++) {
    jobject thread_handle = nullptr;
    // Create all j.l.Thread objects for C1 and C2 threads here, but only one
    // for JVMCI compiler which can create further ones on demand.
    JVMCI_ONLY(if (!UseJVMCICompiler || !UseDynamicNumberOfCompilerThreads || i == 0) {)
    // Create a name for our thread.
    os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", _compilers[1]->name(), i);
    Handle thread_oop = create_thread_oop(name_buffer, CHECK);
    thread_handle = JNIHandles::make_global(thread_oop);
    JVMCI_ONLY(})
    _compiler2_objects[i] = thread_handle;
    _compiler2_logs[i] = nullptr;

    if (!UseDynamicNumberOfCompilerThreads || i == 0) {
      JavaThread *ct = make_thread(compiler_t, thread_handle, _c2_compile_queue, _compilers[1], THREAD);
      assert(ct != nullptr, "should have been handled for initial thread");
      _compilers[1]->set_num_compiler_threads(i + 1);
      if (trace_compiler_threads()) {
        ResourceMark rm;
        ThreadsListHandle tlh;  // name() depends on the TLH.
        assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
        stringStream msg;
        msg.print("Added initial compiler thread %s", ct->name());
        print_compiler_threads(msg);
      }
    }
  }

  for (int i = 0; i < _c1_count; i++) {
    // Create a name for our thread.
    os::snprintf_checked(name_buffer, sizeof(name_buffer), "C1 CompilerThread%d", i);
    Handle thread_oop = create_thread_oop(name_buffer, CHECK);
    jobject thread_handle = JNIHandles::make_global(thread_oop);
    _compiler1_objects[i] = thread_handle;
    _compiler1_logs[i] = nullptr;

    if (!UseDynamicNumberOfCompilerThreads || i == 0) {
      JavaThread *ct = make_thread(compiler_t, thread_handle, _c1_compile_queue, _compilers[0], THREAD);
      assert(ct != nullptr, "should have been handled for initial thread");
      _compilers[0]->set_num_compiler_threads(i + 1);
      if (trace_compiler_threads()) {
        ResourceMark rm;
        ThreadsListHandle tlh;  // name() depends on the TLH.
        assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
        stringStream msg;
        msg.print("Added initial compiler thread %s", ct->name());
        print_compiler_threads(msg);
      }
    }
  }

  if (UsePerfData) {
    PerfDataManager::create_constant(SUN_CI, "threads", PerfData::U_Bytes, _c1_count + _c2_count, CHECK);
  }

#if defined(ASSERT) && COMPILER2_OR_JVMCI
  if (DeoptimizeObjectsALot) {
    // Initialize and start the object deoptimizer threads
    const int total_count = DeoptimizeObjectsALotThreadCountSingle + DeoptimizeObjectsALotThreadCountAll;
    for (int count = 0; count < total_count; count++) {
      Handle thread_oop = create_thread_oop("Deoptimize objects a lot single mode", CHECK);
      jobject thread_handle = JNIHandles::make_local(THREAD, thread_oop());
      make_thread(deoptimizer_t, thread_handle, nullptr, nullptr, THREAD);
    }
  }
#endif // defined(ASSERT) && COMPILER2_OR_JVMCI
}

void CompileBroker::possibly_add_compiler_threads(JavaThread* THREAD) {

  julong free_memory = os::free_memory();
  // If SegmentedCodeCache is off, both values refer to the single heap (with type CodeBlobType::All).
  size_t available_cc_np  = CodeCache::unallocated_capacity(CodeBlobType::MethodNonProfiled),
         available_cc_p   = CodeCache::unallocated_capacity(CodeBlobType::MethodProfiled);

  // Only do attempt to start additional threads if the lock is free.
  if (!CompileThread_lock->try_lock()) return;

  if (_c2_compile_queue != nullptr) {
    int old_c2_count = _compilers[1]->num_compiler_threads();
    int new_c2_count = MIN4(_c2_count,
        _c2_compile_queue->size() / 2,
        (int)(free_memory / (200*M)),
        (int)(available_cc_np / (128*K)));

    for (int i = old_c2_count; i < new_c2_count; i++) {
#if INCLUDE_JVMCI
      if (UseJVMCICompiler) {
        // Native compiler threads as used in C1/C2 can reuse the j.l.Thread
        // objects as their existence is completely hidden from the rest of
        // the VM (and those compiler threads can't call Java code to do the
        // creation anyway). For JVMCI we have to create new j.l.Thread objects
        // as they are visible and we can see unexpected thread lifecycle
        // transitions if we bind them to new JavaThreads.
        if (!THREAD->can_call_java()) break;
        char name_buffer[256];
        os::snprintf_checked(name_buffer, sizeof(name_buffer), "%s CompilerThread%d", _compilers[1]->name(), i);
        Handle thread_oop;
        {
          // We have to give up the lock temporarily for the Java calls.
          MutexUnlocker mu(CompileThread_lock);
          thread_oop = create_thread_oop(name_buffer, THREAD);
        }
        if (HAS_PENDING_EXCEPTION) {
          if (trace_compiler_threads()) {
            ResourceMark rm;
            stringStream msg;
            msg.print_cr("JVMCI compiler thread creation failed:");
            PENDING_EXCEPTION->print_on(&msg);
            print_compiler_threads(msg);
          }
          CLEAR_PENDING_EXCEPTION;
          break;
        }
        // Check if another thread has beaten us during the Java calls.
        if (_compilers[1]->num_compiler_threads() != i) break;
        jobject thread_handle = JNIHandles::make_global(thread_oop);
        assert(compiler2_object(i) == nullptr, "Old one must be released!");
        _compiler2_objects[i] = thread_handle;
      }
#endif
      JavaThread *ct = make_thread(compiler_t, compiler2_object(i), _c2_compile_queue, _compilers[1], THREAD);
      if (ct == nullptr) break;
      _compilers[1]->set_num_compiler_threads(i + 1);
      if (trace_compiler_threads()) {
        ResourceMark rm;
        ThreadsListHandle tlh;  // name() depends on the TLH.
        assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
        stringStream msg;
        msg.print("Added compiler thread %s (free memory: %dMB, available non-profiled code cache: %dMB)",
                  ct->name(), (int)(free_memory/M), (int)(available_cc_np/M));
        print_compiler_threads(msg);
      }
    }
  }

  if (_c1_compile_queue != nullptr) {
    int old_c1_count = _compilers[0]->num_compiler_threads();
    int new_c1_count = MIN4(_c1_count,
        _c1_compile_queue->size() / 4,
        (int)(free_memory / (100*M)),
        (int)(available_cc_p / (128*K)));

    for (int i = old_c1_count; i < new_c1_count; i++) {
      JavaThread *ct = make_thread(compiler_t, compiler1_object(i), _c1_compile_queue, _compilers[0], THREAD);
      if (ct == nullptr) break;
      _compilers[0]->set_num_compiler_threads(i + 1);
      if (trace_compiler_threads()) {
        ResourceMark rm;
        ThreadsListHandle tlh;  // name() depends on the TLH.
        assert(tlh.includes(ct), "ct=" INTPTR_FORMAT " exited unexpectedly.", p2i(ct));
        stringStream msg;
        msg.print("Added compiler thread %s (free memory: %dMB, available profiled code cache: %dMB)",
                  ct->name(), (int)(free_memory/M), (int)(available_cc_p/M));
        print_compiler_threads(msg);
      }
    }
  }

  CompileThread_lock->unlock();
}


/**
 * Set the methods on the stack as on_stack so that redefine classes doesn't
 * reclaim them. This method is executed at a safepoint.
 */
void CompileBroker::mark_on_stack() {
  assert(SafepointSynchronize::is_at_safepoint(), "sanity check");
  // Since we are at a safepoint, we do not need a lock to access
  // the compile queues.
  if (_c2_compile_queue != nullptr) {
    _c2_compile_queue->mark_on_stack();
  }
  if (_c1_compile_queue != nullptr) {
    _c1_compile_queue->mark_on_stack();
  }
}

// ------------------------------------------------------------------
// CompileBroker::compile_method
//
// Request compilation of a method.
void CompileBroker::compile_method_base(const methodHandle& method,
                                        int osr_bci,
                                        int comp_level,
                                        const methodHandle& hot_method,
                                        int hot_count,
                                        CompileTask::CompileReason compile_reason,
                                        bool blocking,
                                        Thread* thread) {
  guarantee(!method->is_abstract(), "cannot compile abstract methods");
  assert(method->method_holder()->is_instance_klass(),
         "sanity check");
  assert(!method->method_holder()->is_not_initialized(),
         "method holder must be initialized");
  assert(!method->is_method_handle_intrinsic(), "do not enqueue these guys");

  if (CIPrintRequests) {
    tty->print("request: ");
    method->print_short_name(tty);
    if (osr_bci != InvocationEntryBci) {
      tty->print(" osr_bci: %d", osr_bci);
    }
    tty->print(" level: %d comment: %s count: %d", comp_level, CompileTask::reason_name(compile_reason), hot_count);
    if (!hot_method.is_null()) {
      tty->print(" hot: ");
      if (hot_method() != method()) {
          hot_method->print_short_name(tty);
      } else {
        tty->print("yes");
      }
    }
    tty->cr();
  }

  // A request has been made for compilation.  Before we do any
  // real work, check to see if the method has been compiled
  // in the meantime with a definitive result.
  if (compilation_is_complete(method, osr_bci, comp_level)) {
    return;
  }

#ifndef PRODUCT
  if (osr_bci != -1 && !FLAG_IS_DEFAULT(OSROnlyBCI)) {
    if ((OSROnlyBCI > 0) ? (OSROnlyBCI != osr_bci) : (-OSROnlyBCI == osr_bci)) {
      // Positive OSROnlyBCI means only compile that bci.  Negative means don't compile that BCI.
      return;
    }
  }
#endif

  // If this method is already in the compile queue, then
  // we do not block the current thread.
  if (compilation_is_in_queue(method)) {
    // We may want to decay our counter a bit here to prevent
    // multiple denied requests for compilation.  This is an
    // open compilation policy issue. Note: The other possibility,
    // in the case that this is a blocking compile request, is to have
    // all subsequent blocking requesters wait for completion of
    // ongoing compiles. Note that in this case we'll need a protocol
    // for freeing the associated compile tasks. [Or we could have
    // a single static monitor on which all these waiters sleep.]
    return;
  }

  // Tiered policy requires MethodCounters to exist before adding a method to
  // the queue. Create if we don't have them yet.
  method->get_method_counters(thread);

  // Outputs from the following MutexLocker block:
  CompileTask* task     = nullptr;
  CompileQueue* queue  = compile_queue(comp_level);

  // Acquire our lock.
  {
    MutexLocker locker(thread, MethodCompileQueue_lock);

    // 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.
    if (compilation_is_in_queue(method)) {
      return;
    }

    // We need to check again to see if the compilation has
    // completed.  A previous compilation may have registered
    // some result.
    if (compilation_is_complete(method, osr_bci, comp_level)) {
      return;
    }

    // We now know that this compilation is not pending, complete,
    // or prohibited.  Assign a compile_id to this compilation
    // and check to see if it is in our [Start..Stop) range.
    int compile_id = assign_compile_id(method, osr_bci);
    if (compile_id == 0) {
      // The compilation falls outside the allowed range.
      return;
    }

#if INCLUDE_JVMCI
    if (UseJVMCICompiler && blocking) {
      // Don't allow blocking compiles for requests triggered by JVMCI.
      if (thread->is_Compiler_thread()) {
        blocking = false;
      }

      if (!UseJVMCINativeLibrary) {
        // Don't allow blocking compiles if inside a class initializer or while performing class loading
        vframeStream vfst(JavaThread::cast(thread));
        for (; !vfst.at_end(); vfst.next()) {
          if (vfst.method()->is_static_initializer() ||
              (vfst.method()->method_holder()->is_subclass_of(vmClasses::ClassLoader_klass()) &&
                  vfst.method()->name() == vmSymbols::loadClass_name())) {
            blocking = false;
            break;
          }
        }
      }

      // Don't allow blocking compilation requests to JVMCI
      // if JVMCI itself is not yet initialized
      if (!JVMCI::is_compiler_initialized() && compiler(comp_level)->is_jvmci()) {
        blocking = false;
      }

      // Don't allow blocking compilation requests if we are in JVMCIRuntime::shutdown
      // to avoid deadlock between compiler thread(s) and threads run at shutdown
      // such as the DestroyJavaVM thread.
      if (JVMCI::in_shutdown()) {
        blocking = false;
      }
    }
#endif // INCLUDE_JVMCI

    // We will enter the compilation in the queue.
    // 14012000: Note that this sets the queued_for_compile bits in
    // the target method. We can now reason that a method cannot be
    // queued for compilation more than once, as follows:
    // Before a thread queues a task for compilation, it first acquires
    // the compile queue lock, then checks if the method's queued bits
    // are set or it has already been compiled. Thus there can not be two
    // instances of a compilation task for the same method on the
    // compilation queue. Consider now the case where the compilation
    // thread has already removed a task for that method from the queue
    // and is in the midst of compiling it. In this case, the
    // queued_for_compile bits must be set in the method (and these
    // will be visible to the current thread, since the bits were set
    // under protection of the compile queue lock, which we hold now.
    // When the compilation completes, the compiler thread first sets
    // the compilation result and then clears the queued_for_compile
    // bits. Neither of these actions are protected by a barrier (or done
    // under the protection of a lock), so the only guarantee we have
    // (on machines with TSO (Total Store Order)) is that these values
    // will update in that order. As a result, the only combinations of
    // these bits that the current thread will see are, in temporal order:
    // <RESULT, QUEUE> :
    //     <0, 1> : in compile queue, but not yet compiled
    //     <1, 1> : compiled but queue bit not cleared
    //     <1, 0> : compiled and queue bit cleared
    // Because we first check the queue bits then check the result bits,
    // we are assured that we cannot introduce a duplicate task.
    // Note that if we did the tests in the reverse order (i.e. check
    // result then check queued bit), we could get the result bit before
    // the compilation completed, and the queue bit after the compilation
    // completed, and end up introducing a "duplicate" (redundant) task.
    // In that case, the compiler thread should first check if a method
    // has already been compiled before trying to compile it.
    // NOTE: in the event that there are multiple compiler threads and
    // there is de-optimization/recompilation, things will get hairy,
    // 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(queue,
                               compile_id, method,
                               osr_bci, comp_level,
                               hot_method, hot_count, compile_reason,
                               blocking);
  }

  if (blocking) {
    wait_for_completion(task);
  }
}

nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
                                       int comp_level,
                                       const methodHandle& hot_method, int hot_count,
                                       CompileTask::CompileReason compile_reason,
                                       TRAPS) {
  // Do nothing if compilebroker is not initialized or compiles are submitted on level none
  if (!_initialized || comp_level == CompLevel_none) {
    return nullptr;
  }

  AbstractCompiler *comp = CompileBroker::compiler(comp_level);
  assert(comp != nullptr, "Ensure we have a compiler");

  DirectiveSet* directive = DirectivesStack::getMatchingDirective(method, comp);
  // CompileBroker::compile_method can trap and can have pending async exception.
  nmethod* nm = CompileBroker::compile_method(method, osr_bci, comp_level, hot_method, hot_count, compile_reason, directive, THREAD);
  DirectivesStack::release(directive);
  return nm;
}

nmethod* CompileBroker::compile_method(const methodHandle& method, int osr_bci,
                                         int comp_level,
                                         const methodHandle& hot_method, int hot_count,
                                         CompileTask::CompileReason compile_reason,
                                         DirectiveSet* directive,
                                         TRAPS) {

  // make sure arguments make sense
  assert(method->method_holder()->is_instance_klass(), "not an instance method");
  assert(osr_bci == InvocationEntryBci || (0 <= osr_bci && osr_bci < method->code_size()), "bci out of range");
  assert(!method->is_abstract() && (osr_bci == InvocationEntryBci || !method->is_native()), "cannot compile abstract/native methods");
  assert(!method->method_holder()->is_not_initialized(), "method holder must be initialized");
  // return quickly if possible

  // lock, make sure that the compilation
  // isn't prohibited in a straightforward way.
  AbstractCompiler* comp = CompileBroker::compiler(comp_level);
  if (comp == nullptr || compilation_is_prohibited(method, osr_bci, comp_level, directive->ExcludeOption)) {
    return nullptr;
  }

#if INCLUDE_JVMCI
  if (comp->is_jvmci() && !JVMCI::can_initialize_JVMCI()) {
    return nullptr;
  }
#endif

  if (osr_bci == InvocationEntryBci) {
    // standard compilation
    CompiledMethod* method_code = method->code();
    if (method_code != nullptr && method_code->is_nmethod()) {
      if (compilation_is_complete(method, osr_bci, comp_level)) {
        return (nmethod*) method_code;
      }
    }
    if (method->is_not_compilable(comp_level)) {
      return nullptr;
    }
  } else {
    // osr compilation
    // We accept a higher level osr method
    nmethod* nm = method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
    if (nm != nullptr) return nm;
    if (method->is_not_osr_compilable(comp_level)) return nullptr;
  }

  assert(!HAS_PENDING_EXCEPTION, "No exception should be present");
  // some prerequisites that are compiler specific
  if (comp->is_c2() || comp->is_jvmci()) {
    method->constants()->resolve_string_constants(CHECK_AND_CLEAR_NONASYNC_NULL);
    // Resolve all classes seen in the signature of the method
    // we are compiling.
    Method::load_signature_classes(method, CHECK_AND_CLEAR_NONASYNC_NULL);
  }

  // If the method is native, do the lookup in the thread requesting
  // the compilation. Native lookups can load code, which is not
  // permitted during compilation.
  //
  // Note: A native method implies non-osr compilation which is
  //       checked with an assertion at the entry of this method.
  if (method->is_native() && !method->is_method_handle_intrinsic()) {
    address adr = NativeLookup::lookup(method, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      // In case of an exception looking up the method, we just forget
      // about it. The interpreter will kick-in and throw the exception.
      method->set_not_compilable("NativeLookup::lookup failed"); // implies is_not_osr_compilable()
      CLEAR_PENDING_EXCEPTION;
      return nullptr;
    }
    assert(method->has_native_function(), "must have native code by now");
  }

  // RedefineClasses() has replaced this method; just return
  if (method->is_old()) {
    return nullptr;
  }

  // JVMTI -- post_compile_event requires jmethod_id() that may require
  // a lock the compiling thread can not acquire. Prefetch it here.
  if (JvmtiExport::should_post_compiled_method_load()) {
    method->jmethod_id();
  }

  // do the compilation
  if (method->is_native()) {
    if (!PreferInterpreterNativeStubs || method->is_method_handle_intrinsic()) {
#if defined(X86) && !defined(ZERO)
      // The following native methods:
      //
      // java.lang.Float.intBitsToFloat
      // java.lang.Float.floatToRawIntBits
      // java.lang.Double.longBitsToDouble
      // java.lang.Double.doubleToRawLongBits
      //
      // are called through the interpreter even if interpreter native stubs
      // are not preferred (i.e., calling through adapter handlers is preferred).
      // The reason is that on x86_32 signaling NaNs (sNaNs) are not preserved
      // if the version of the methods from the native libraries is called.
      // As the interpreter and the C2-intrinsified version of the methods preserves
      // sNaNs, that would result in an inconsistent way of handling of sNaNs.
      if ((UseSSE >= 1 &&
          (method->intrinsic_id() == vmIntrinsics::_intBitsToFloat ||
           method->intrinsic_id() == vmIntrinsics::_floatToRawIntBits)) ||
          (UseSSE >= 2 &&
           (method->intrinsic_id() == vmIntrinsics::_longBitsToDouble ||
            method->intrinsic_id() == vmIntrinsics::_doubleToRawLongBits))) {
        return nullptr;
      }
#endif // X86 && !ZERO

      // To properly handle the appendix argument for out-of-line calls we are using a small trampoline that
      // pops off the appendix argument and jumps to the target (see gen_special_dispatch in SharedRuntime).
      //
      // Since normal compiled-to-compiled calls are not able to handle such a thing we MUST generate an adapter
      // in this case.  If we can't generate one and use it we can not execute the out-of-line method handle calls.
      AdapterHandlerLibrary::create_native_wrapper(method);
    } else {
      return nullptr;
    }
  } else {
    // If the compiler is shut off due to code cache getting full
    // fail out now so blocking compiles dont hang the java thread
    if (!should_compile_new_jobs()) {
      return nullptr;
    }
    bool is_blocking = !directive->BackgroundCompilationOption || ReplayCompiles;
    compile_method_base(method, osr_bci, comp_level, hot_method, hot_count, compile_reason, is_blocking, THREAD);
  }

  // return requested nmethod
  // We accept a higher level osr method
  if (osr_bci == InvocationEntryBci) {
    CompiledMethod* code = method->code();
    if (code == nullptr) {
      return (nmethod*) code;
    } else {
      return code->as_nmethod_or_null();
    }
  }
  return method->lookup_osr_nmethod_for(osr_bci, comp_level, false);
}


// ------------------------------------------------------------------
// CompileBroker::compilation_is_complete
//
// See if compilation of this method is already complete.
bool CompileBroker::compilation_is_complete(const methodHandle& method,
                                            int                 osr_bci,
                                            int                 comp_level) {
  bool is_osr = (osr_bci != standard_entry_bci);
  if (is_osr) {
    if (method->is_not_osr_compilable(comp_level)) {
      return true;
    } else {
      nmethod* result = method->lookup_osr_nmethod_for(osr_bci, comp_level, true);
      return (result != nullptr);
    }
  } else {
    if (method->is_not_compilable(comp_level)) {
      return true;
    } else {
      CompiledMethod* result = method->code();
      if (result == nullptr) return false;
      return comp_level == result->comp_level();
    }
  }
}


/**
 * See if this compilation is already requested.
 *
 * Implementation note: there is only a single "is in queue" bit
 * for each method.  This means that the check below is overly
 * conservative in the sense that an osr compilation in the queue
 * will block a normal compilation from entering the queue (and vice
 * versa).  This can be remedied by a full queue search to disambiguate
 * cases.  If it is deemed profitable, this may be done.
 */
bool CompileBroker::compilation_is_in_queue(const methodHandle& method) {
  return method->queued_for_compilation();
}

// ------------------------------------------------------------------
// CompileBroker::compilation_is_prohibited
//
// See if this compilation is not allowed.
bool CompileBroker::compilation_is_prohibited(const methodHandle& method, int osr_bci, int comp_level, bool excluded) {
  bool is_native = method->is_native();
  // Some compilers may not support the compilation of natives.
  AbstractCompiler *comp = compiler(comp_level);
  if (is_native && (!CICompileNatives || comp == nullptr)) {
    method->set_not_compilable_quietly("native methods not supported", comp_level);
    return true;
  }

  bool is_osr = (osr_bci != standard_entry_bci);
  // Some compilers may not support on stack replacement.
  if (is_osr && (!CICompileOSR || comp == nullptr)) {
    method->set_not_osr_compilable("OSR not supported", comp_level);
    return true;
  }

  // The method may be explicitly excluded by the user.
  double scale;
  if (excluded || (CompilerOracle::has_option_value(method, CompileCommand::CompileThresholdScaling, scale) && scale == 0)) {
    bool quietly = CompilerOracle::be_quiet();
    if (PrintCompilation && !quietly) {
      // This does not happen quietly...
      ResourceMark rm;
      tty->print("### Excluding %s:%s",
                 method->is_native() ? "generation of native wrapper" : "compile",
                 (method->is_static() ? " static" : ""));
      method->print_short_name(tty);
      tty->cr();
    }
    method->set_not_compilable("excluded by CompileCommand", comp_level, !quietly);
  }

  return false;
}

/**
 * Generate serialized IDs for compilation requests. If certain debugging flags are used
 * and the ID is not within the specified range, the method is not compiled and 0 is returned.
 * The function also allows to generate separate compilation IDs for OSR compilations.
 */
int CompileBroker::assign_compile_id(const methodHandle& method, int osr_bci) {
#ifdef ASSERT
  bool is_osr = (osr_bci != standard_entry_bci);
  int id;
  if (method->is_native()) {
    assert(!is_osr, "can't be osr");
    // Adapters, native wrappers and method handle intrinsics
    // should be generated always.
    return Atomic::add(CICountNative ? &_native_compilation_id : &_compilation_id, 1);
  } else if (CICountOSR && is_osr) {
    id = Atomic::add(&_osr_compilation_id, 1);
    if (CIStartOSR <= id && id < CIStopOSR) {
      return id;
    }
  } else {
    id = Atomic::add(&_compilation_id, 1);
    if (CIStart <= id && id < CIStop) {
      return id;
    }
  }

  // Method was not in the appropriate compilation range.
  method->set_not_compilable_quietly("Not in requested compile id range");
  return 0;
#else
  // CICountOSR is a develop flag and set to 'false' by default. In a product built,
  // only _compilation_id is incremented.
  return Atomic::add(&_compilation_id, 1);
#endif
}

// ------------------------------------------------------------------
// CompileBroker::assign_compile_id_unlocked
//
// Public wrapper for assign_compile_id that acquires the needed locks
int CompileBroker::assign_compile_id_unlocked(Thread* thread, const methodHandle& method, int osr_bci) {
  MutexLocker locker(thread, MethodCompileQueue_lock);
  return assign_compile_id(method, osr_bci);
}

// ------------------------------------------------------------------
// CompileBroker::create_compile_task
//
// Create a CompileTask object representing the current request for
// compilation.  Add this task to the queue.
CompileTask* CompileBroker::create_compile_task(CompileQueue*       queue,
                                                int                 compile_id,
                                                const methodHandle& method,
                                                int                 osr_bci,
                                                int                 comp_level,
                                                const methodHandle& hot_method,
                                                int                 hot_count,
                                                CompileTask::CompileReason compile_reason,
                                                bool                blocking) {
  CompileTask* new_task = CompileTask::allocate();
  new_task->initialize(compile_id, method, osr_bci, comp_level,
                       hot_method, hot_count, compile_reason,
                       blocking);
  queue->add(new_task);
  return new_task;
}

#if INCLUDE_JVMCI
// The number of milliseconds to wait before checking if
// JVMCI compilation has made progress.
static const long JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE = 1000;

// The number of JVMCI compilation progress checks that must fail
// before unblocking a thread waiting for a blocking compilation.
static const int JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS = 10;

/**
 * Waits for a JVMCI compiler to complete a given task. This thread
 * waits until either the task completes or it sees no JVMCI compilation
 * progress for N consecutive milliseconds where N is
 * JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE *
 * JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS.
 *
 * @return true if this thread needs to free/recycle the task
 */
bool CompileBroker::wait_for_jvmci_completion(JVMCICompiler* jvmci, CompileTask* task, JavaThread* thread) {
  assert(UseJVMCICompiler, "sanity");
  MonitorLocker ml(thread, task->lock());
  int progress_wait_attempts = 0;
  jint thread_jvmci_compilation_ticks = 0;
  jint global_jvmci_compilation_ticks = jvmci->global_compilation_ticks();
  while (!task->is_complete() && !is_compilation_disabled_forever() &&
         ml.wait(JVMCI_COMPILATION_PROGRESS_WAIT_TIMESLICE)) {
    JVMCICompileState* jvmci_compile_state = task->blocking_jvmci_compile_state();

    bool progress;
    if (jvmci_compile_state != nullptr) {
      jint ticks = jvmci_compile_state->compilation_ticks();
      progress = (ticks - thread_jvmci_compilation_ticks) != 0;
      JVMCI_event_1("waiting on compilation %d [ticks=%d]", task->compile_id(), ticks);
      thread_jvmci_compilation_ticks = ticks;
    } else {
      // Still waiting on JVMCI compiler queue. This thread may be holding a lock
      // that all JVMCI compiler threads are blocked on. We use the global JVMCI
      // compilation ticks to determine whether JVMCI compilation
      // is still making progress through the JVMCI compiler queue.
      jint ticks = jvmci->global_compilation_ticks();
      progress = (ticks - global_jvmci_compilation_ticks) != 0;
      JVMCI_event_1("waiting on compilation %d to be queued [ticks=%d]", task->compile_id(), ticks);
      global_jvmci_compilation_ticks = ticks;
    }

    if (!progress) {
      if (++progress_wait_attempts == JVMCI_COMPILATION_PROGRESS_WAIT_ATTEMPTS) {
        if (PrintCompilation) {
          task->print(tty, "wait for blocking compilation timed out");
        }
        JVMCI_event_1("waiting on compilation %d timed out", task->compile_id());
        break;
      }
    } else {
      progress_wait_attempts = 0;
    }
  }
  task->clear_waiter();
  return task->is_complete();
}
#endif

/**
 *  Wait for the compilation task to complete.
 */
void CompileBroker::wait_for_completion(CompileTask* task) {
  if (CIPrintCompileQueue) {
    ttyLocker ttyl;
    tty->print_cr("BLOCKING FOR COMPILE");
  }

  assert(task->is_blocking(), "can only wait on blocking task");

  JavaThread* thread = JavaThread::current();

  methodHandle method(thread, task->method());
  bool free_task;
#if INCLUDE_JVMCI
  AbstractCompiler* comp = compiler(task->comp_level());
  if (comp->is_jvmci() && !task->should_wait_for_compilation()) {
    // It may return before compilation is completed.
    free_task = wait_for_jvmci_completion((JVMCICompiler*) comp, task, thread);
  } else
#endif
  {
    MonitorLocker ml(thread, task->lock());
    free_task = true;
    while (!task->is_complete() && !is_compilation_disabled_forever()) {
      ml.wait();
    }
  }

  if (free_task) {
    if (is_compilation_disabled_forever()) {
      CompileTask::free(task);
      return;
    }

    // It is harmless to check this status without the lock, because
    // completion is a stable property (until the task object is recycled).
    assert(task->is_complete(), "Compilation should have completed");

    // By convention, the waiter is responsible for recycling a
    // blocking CompileTask. Since there is only one waiter ever
    // waiting on a CompileTask, we know that no one else will
    // be using this CompileTask; we can free it.
    CompileTask::free(task);
  }
}

/**
 * Initialize compiler thread(s) + compiler object(s). The postcondition
 * of this function is that the compiler runtimes are initialized and that
 * compiler threads can start compiling.
 */
bool CompileBroker::init_compiler_runtime() {
  CompilerThread* thread = CompilerThread::current();
  AbstractCompiler* comp = thread->compiler();
  // Final sanity check - the compiler object must exist
  guarantee(comp != nullptr, "Compiler object must exist");

  {
    // Must switch to native to allocate ci_env
    ThreadToNativeFromVM ttn(thread);
    ciEnv ci_env((CompileTask*)nullptr);
    // Cache Jvmti state
    ci_env.cache_jvmti_state();
    // Cache DTrace flags
    ci_env.cache_dtrace_flags();

    // Switch back to VM state to do compiler initialization
    ThreadInVMfromNative tv(thread);

    // Perform per-thread and global initializations
    comp->initialize();
  }

  if (comp->is_failed()) {
    disable_compilation_forever();
    // If compiler initialization failed, no compiler thread that is specific to a
    // particular compiler runtime will ever start to compile methods.
    shutdown_compiler_runtime(comp, thread);
    return false;
  }

  // C1 specific check
  if (comp->is_c1() && (thread->get_buffer_blob() == nullptr)) {
    warning("Initialization of %s thread failed (no space to run compilers)", thread->name());
    return false;
  }

  return true;
}

void CompileBroker::free_buffer_blob_if_allocated(CompilerThread* thread) {
  BufferBlob* blob = thread->get_buffer_blob();
  if (blob != nullptr) {
    blob->purge(true /* free_code_cache_data */, true /* unregister_nmethod */);
    MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    CodeCache::free(blob);
  }
}

/**
 * If C1 and/or C2 initialization failed, we shut down all compilation.
 * We do this to keep things simple. This can be changed if it ever turns
 * out to be a problem.
 */
void CompileBroker::shutdown_compiler_runtime(AbstractCompiler* comp, CompilerThread* thread) {
  free_buffer_blob_if_allocated(thread);

  if (comp->should_perform_shutdown()) {
    // There are two reasons for shutting down the compiler
    // 1) compiler runtime initialization failed
    // 2) The code cache is full and the following flag is set: -XX:-UseCodeCacheFlushing
    warning("%s initialization failed. Shutting down all compilers", comp->name());

    // Only one thread per compiler runtime object enters here
    // Set state to shut down
    comp->set_shut_down();

    // Delete all queued compilation tasks to make compiler threads exit faster.
    if (_c1_compile_queue != nullptr) {
      _c1_compile_queue->free_all();
    }

    if (_c2_compile_queue != nullptr) {
      _c2_compile_queue->free_all();
    }

    // Set flags so that we continue execution with using interpreter only.
    UseCompiler    = false;
    UseInterpreter = true;

    // We could delete compiler runtimes also. However, there are references to
    // the compiler runtime(s) (e.g.,  nmethod::is_compiled_by_c1()) which then
    // fail. This can be done later if necessary.
  }
}

/**
 * Helper function to create new or reuse old CompileLog.
 */
CompileLog* CompileBroker::get_log(CompilerThread* ct) {
  if (!LogCompilation) return nullptr;

  AbstractCompiler *compiler = ct->compiler();
  bool c1 = compiler->is_c1();
  jobject* compiler_objects = c1 ? _compiler1_objects : _compiler2_objects;
  assert(compiler_objects != nullptr, "must be initialized at this point");
  CompileLog** logs = c1 ? _compiler1_logs : _compiler2_logs;
  assert(logs != nullptr, "must be initialized at this point");
  int count = c1 ? _c1_count : _c2_count;

  // Find Compiler number by its threadObj.
  oop compiler_obj = ct->threadObj();
  int compiler_number = 0;
  bool found = false;
  for (; compiler_number < count; compiler_number++) {
    if (JNIHandles::resolve_non_null(compiler_objects[compiler_number]) == compiler_obj) {
      found = true;
      break;
    }
  }
  assert(found, "Compiler must exist at this point");

  // Determine pointer for this thread's log.
  CompileLog** log_ptr = &logs[compiler_number];

  // Return old one if it exists.
  CompileLog* log = *log_ptr;
  if (log != nullptr) {
    ct->init_log(log);
    return log;
  }

  // Create a new one and remember it.
  init_compiler_thread_log();
  log = ct->log();
  *log_ptr = log;
  return log;
}

// ------------------------------------------------------------------
// CompileBroker::compiler_thread_loop
//
// The main loop run by a CompilerThread.
void CompileBroker::compiler_thread_loop() {
  CompilerThread* thread = CompilerThread::current();
  CompileQueue* queue = thread->queue();
  // For the thread that initializes the ciObjectFactory
  // this resource mark holds all the shared objects
  ResourceMark rm;

  // First thread to get here will initialize the compiler interface

  {
    ASSERT_IN_VM;
    MutexLocker only_one (thread, CompileThread_lock);
    if (!ciObjectFactory::is_initialized()) {
      ciObjectFactory::initialize();
    }
  }

  // Open a log.
  CompileLog* log = get_log(thread);
  if (log != nullptr) {
    log->begin_elem("start_compile_thread name='%s' thread='" UINTX_FORMAT "' process='%d'",
                    thread->name(),
                    os::current_thread_id(),
                    os::current_process_id());
    log->stamp();
    log->end_elem();
  }

  // If compiler thread/runtime initialization fails, exit the compiler thread
  if (!init_compiler_runtime()) {
    return;
  }

  thread->start_idle_timer();

  // Poll for new compilation tasks as long as the JVM runs. Compilation
  // should only be disabled if something went wrong while initializing the
  // compiler runtimes. This, in turn, should not happen. The only known case
  // when compiler runtime initialization fails is if there is not enough free
  // 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);

    CompileTask* task = queue->get(thread);
    if (task == nullptr) {
      if (UseDynamicNumberOfCompilerThreads) {
        // Access compiler_count under lock to enforce consistency.
        MutexLocker only_one(CompileThread_lock);
        if (can_remove(thread, true)) {
          if (trace_compiler_threads()) {
            ResourceMark rm;
            stringStream msg;
            msg.print("Removing compiler thread %s after " JLONG_FORMAT " ms idle time",
                      thread->name(), thread->idle_time_millis());
            print_compiler_threads(msg);
          }

          // Notify compiler that the compiler thread is about to stop
          thread->compiler()->stopping_compiler_thread(thread);

          free_buffer_blob_if_allocated(thread);
          return; // Stop this thread.
        }
      }
    } else {
      // Assign the task to the current thread.  Mark this compilation
      // thread as active for the profiler.
      // CompileTaskWrapper also keeps the Method* from being deallocated if redefinition
      // occurs after fetching the compile task off the queue.
      CompileTaskWrapper ctw(task);
      methodHandle method(thread, task->method());

      // Never compile a method if breakpoints are present in it
      if (method()->number_of_breakpoints() == 0) {
        // Compile the method.
        if ((UseCompiler || AlwaysCompileLoopMethods) && CompileBroker::should_compile_new_jobs()) {
          invoke_compiler_on_method(task);
          thread->start_idle_timer();
        } else {
          // After compilation is disabled, remove remaining methods from queue
          method->clear_queued_for_compilation();
          task->set_failure_reason("compilation is disabled");
        }
      } else {
        task->set_failure_reason("breakpoints are present");
      }

      if (UseDynamicNumberOfCompilerThreads) {
        possibly_add_compiler_threads(thread);
        assert(!thread->has_pending_exception(), "should have been handled");
      }
    }
  }

  // Shut down compiler runtime
  shutdown_compiler_runtime(thread->compiler(), thread);
}

// ------------------------------------------------------------------
// CompileBroker::init_compiler_thread_log
//
// Set up state required by +LogCompilation.
void CompileBroker::init_compiler_thread_log() {
    CompilerThread* thread = CompilerThread::current();
    char  file_name[4*K];
    FILE* fp = nullptr;
    intx thread_id = os::current_thread_id();
    for (int try_temp_dir = 1; try_temp_dir >= 0; try_temp_dir--) {
      const char* dir = (try_temp_dir ? os::get_temp_directory() : nullptr);
      if (dir == nullptr) {
        jio_snprintf(file_name, sizeof(file_name), "hs_c" UINTX_FORMAT "_pid%u.log",
                     thread_id, os::current_process_id());
      } else {
        jio_snprintf(file_name, sizeof(file_name),
                     "%s%shs_c" UINTX_FORMAT "_pid%u.log", dir,
                     os::file_separator(), thread_id, os::current_process_id());
      }

      fp = os::fopen(file_name, "wt");
      if (fp != nullptr) {
        if (LogCompilation && Verbose) {
          tty->print_cr("Opening compilation log %s", file_name);
        }
        CompileLog* log = new(mtCompiler) CompileLog(file_name, fp, thread_id);
        if (log == nullptr) {
          fclose(fp);
          return;
        }
        thread->init_log(log);

        if (xtty != nullptr) {
          ttyLocker ttyl;
          // Record any per thread log files
          xtty->elem("thread_logfile thread='" INTX_FORMAT "' filename='%s'", thread_id, file_name);
        }
        return;
      }
    }
    warning("Cannot open log file: %s", file_name);
}

void CompileBroker::log_metaspace_failure() {
  const char* message = "some methods may not be compiled because metaspace "
                        "is out of memory";
  if (CompilationLog::log() != nullptr) {
    CompilationLog::log()->log_metaspace_failure(message);
  }
  if (PrintCompilation) {
    tty->print_cr("COMPILE PROFILING SKIPPED: %s", message);
  }
}


// ------------------------------------------------------------------
// CompileBroker::set_should_block
//
// Set _should_block.
// Call this from the VM, with Threads_lock held and a safepoint requested.
void CompileBroker::set_should_block() {
  assert(Threads_lock->owner() == Thread::current(), "must have threads lock");
  assert(SafepointSynchronize::is_at_safepoint(), "must be at a safepoint already");
#ifndef PRODUCT
  if (PrintCompilation && (Verbose || WizardMode))
    tty->print_cr("notifying compiler thread pool to block");
#endif
  _should_block = true;
}

// ------------------------------------------------------------------
// CompileBroker::maybe_block
//
// Call this from the compiler at convenient points, to poll for _should_block.
void CompileBroker::maybe_block() {
  if (_should_block) {
#ifndef PRODUCT
    if (PrintCompilation && (Verbose || WizardMode))
      tty->print_cr("compiler thread " INTPTR_FORMAT " poll detects block request", p2i(Thread::current()));
#endif
    ThreadInVMfromNative tivfn(JavaThread::current());
  }
}

// wrapper for CodeCache::print_summary()
static void codecache_print(bool detailed)
{
  stringStream s;
  // Dump code cache  into a buffer before locking the tty,
  {
    MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    CodeCache::print_summary(&s, detailed);
  }
  ttyLocker ttyl;
  tty->print("%s", s.freeze());
}

// wrapper for CodeCache::print_summary() using outputStream
static void codecache_print(outputStream* out, bool detailed) {
  stringStream s;

  // Dump code cache into a buffer
  {
    MutexLocker mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
    CodeCache::print_summary(&s, detailed);
  }

  char* remaining_log = s.as_string();
  while (*remaining_log != '\0') {
    char* eol = strchr(remaining_log, '\n');
    if (eol == nullptr) {
      out->print_cr("%s", remaining_log);
      remaining_log = remaining_log + strlen(remaining_log);
    } else {
      *eol = '\0';
      out->print_cr("%s", remaining_log);
      remaining_log = eol + 1;
    }
  }
}

void CompileBroker::handle_compile_error(CompilerThread* thread, CompileTask* task, ciEnv* ci_env,
                                         int compilable, const char* failure_reason) {
  if (!AbortVMOnCompilationFailure) {
    return;
  }
  if (compilable == ciEnv::MethodCompilable_not_at_tier) {
    fatal("Not compilable at tier %d: %s", task->comp_level(), failure_reason);
  }
  if (compilable == ciEnv::MethodCompilable_never) {
    fatal("Never compilable: %s", failure_reason);
  }
}

static void post_compilation_event(EventCompilation& event, CompileTask* task) {
  assert(task != nullptr, "invariant");
  CompilerEvent::CompilationEvent::post(event,
                                        task->compile_id(),
                                        task->compiler()->type(),
                                        task->method(),
                                        task->comp_level(),
                                        task->is_success(),
                                        task->osr_bci() != CompileBroker::standard_entry_bci,
                                        task->nm_total_size(),
                                        task->num_inlined_bytecodes());
}

int DirectivesStack::_depth = 0;
CompilerDirectives* DirectivesStack::_top = nullptr;
CompilerDirectives* DirectivesStack::_bottom = nullptr;

// ------------------------------------------------------------------
// CompileBroker::invoke_compiler_on_method
//
// Compile a method.
//
void CompileBroker::invoke_compiler_on_method(CompileTask* task) {
  task->print_ul();
  elapsedTimer time;

  DirectiveSet* directive = task->directive();
  if (directive->PrintCompilationOption) {
    ResourceMark rm;
    task->print_tty();
  }

  CompilerThread* thread = CompilerThread::current();
  ResourceMark rm(thread);

  if (CompilationLog::log() != nullptr) {
    CompilationLog::log()->log_compile(thread, task);
  }

  // Common flags.
  int compile_id = task->compile_id();
  int osr_bci = task->osr_bci();
  bool is_osr = (osr_bci != standard_entry_bci);
  bool should_log = (thread->log() != nullptr);
  bool should_break = false;
  const int task_level = task->comp_level();
  AbstractCompiler* comp = task->compiler();
  {
    // create the handle inside it's own block so it can't
    // accidentally be referenced once the thread transitions to
    // native.  The NoHandleMark before the transition should catch
    // any cases where this occurs in the future.
    methodHandle method(thread, task->method());

    assert(!method->is_native(), "no longer compile natives");

    // Update compile information when using perfdata.
    if (UsePerfData) {
      update_compile_perf_data(thread, method, is_osr);
    }

    DTRACE_METHOD_COMPILE_BEGIN_PROBE(method, compiler_name(task_level));
  }

  should_break = directive->BreakAtCompileOption || task->check_break_at_flags();
  if (should_log && !directive->LogOption) {
    should_log = false;
  }

  // Allocate a new set of JNI handles.
  JNIHandleMark jhm(thread);
  Method* target_handle = task->method();
  int compilable = ciEnv::MethodCompilable;
  const char* failure_reason = nullptr;
  bool failure_reason_on_C_heap = false;
  const char* retry_message = nullptr;

#if INCLUDE_JVMCI
  if (UseJVMCICompiler && comp != nullptr && comp->is_jvmci()) {
    JVMCICompiler* jvmci = (JVMCICompiler*) comp;

    TraceTime t1("compilation", &time);
    EventCompilation event;
    JVMCICompileState compile_state(task, jvmci);
    JVMCIRuntime *runtime = nullptr;

    if (JVMCI::in_shutdown()) {
      failure_reason = "in JVMCI shutdown";
      retry_message = "not retryable";
      compilable = ciEnv::MethodCompilable_never;
    } else if (compile_state.target_method_is_old()) {
      // Skip redefined methods
      failure_reason = "redefined method";
      retry_message = "not retryable";
      compilable = ciEnv::MethodCompilable_never;
    } else {
      JVMCIEnv env(thread, &compile_state, __FILE__, __LINE__);
      failure_reason = compile_state.failure_reason();
      if (failure_reason == nullptr) {
        methodHandle method(thread, target_handle);
        runtime = env.runtime();
        runtime->compile_method(&env, jvmci, method, osr_bci);

        failure_reason = compile_state.failure_reason();
        failure_reason_on_C_heap = compile_state.failure_reason_on_C_heap();
        if (!compile_state.retryable()) {
          retry_message = "not retryable";
          compilable = ciEnv::MethodCompilable_not_at_tier;
        }
        if (!task->is_success()) {
          assert(failure_reason != nullptr, "must specify failure_reason");
        }
      }
    }
    if (!task->is_success()) {
      handle_compile_error(thread, task, nullptr, compilable, failure_reason);
    }
    if (event.should_commit()) {
      post_compilation_event(event, task);
    }

    if (runtime != nullptr) {
      runtime->post_compile(thread);
    }
  } else
#endif // INCLUDE_JVMCI
  {
    NoHandleMark  nhm;
    ThreadToNativeFromVM ttn(thread);

    ciEnv ci_env(task);
    if (should_break) {
      ci_env.set_break_at_compile(true);
    }
    if (should_log) {
      ci_env.set_log(thread->log());
    }
    assert(thread->env() == &ci_env, "set by ci_env");
    // The thread-env() field is cleared in ~CompileTaskWrapper.

    // Cache Jvmti state
    bool method_is_old = ci_env.cache_jvmti_state();

    // Skip redefined methods
    if (method_is_old) {
      ci_env.record_method_not_compilable("redefined method", true);
    }

    // Cache DTrace flags
    ci_env.cache_dtrace_flags();

    ciMethod* target = ci_env.get_method_from_handle(target_handle);

    TraceTime t1("compilation", &time);
    EventCompilation event;

    if (comp == nullptr) {
      ci_env.record_method_not_compilable("no compiler");
    } else if (!ci_env.failing()) {
      if (WhiteBoxAPI && WhiteBox::compilation_locked) {
        MonitorLocker locker(Compilation_lock, Mutex::_no_safepoint_check_flag);
        while (WhiteBox::compilation_locked) {
          locker.wait();
        }
      }
      comp->compile_method(&ci_env, target, osr_bci, true, directive);

      /* Repeat compilation without installing code for profiling purposes */
      int repeat_compilation_count = directive->RepeatCompilationOption;
      while (repeat_compilation_count > 0) {
        ResourceMark rm(thread);
        task->print_ul("NO CODE INSTALLED");
        comp->compile_method(&ci_env, target, osr_bci, false, directive);
        repeat_compilation_count--;
      }
    }

    DirectivesStack::release(directive);

    if (!ci_env.failing() && !task->is_success()) {
      assert(ci_env.failure_reason() != nullptr, "expect failure reason");
      assert(false, "compiler should always document failure: %s", ci_env.failure_reason());
      // The compiler elected, without comment, not to register a result.
      // Do not attempt further compilations of this method.
      ci_env.record_method_not_compilable("compile failed");
    }

    // Copy this bit to the enclosing block:
    compilable = ci_env.compilable();

    if (ci_env.failing()) {
      // Duplicate the failure reason string, so that it outlives ciEnv
      failure_reason = os::strdup(ci_env.failure_reason(), mtCompiler);
      failure_reason_on_C_heap = true;
      retry_message = ci_env.retry_message();
      ci_env.report_failure(failure_reason);
    }

    if (ci_env.failing()) {
      handle_compile_error(thread, task, &ci_env, compilable, failure_reason);
    }
    if (event.should_commit()) {
      post_compilation_event(event, task);
    }
  }

  if (failure_reason != nullptr) {
    task->set_failure_reason(failure_reason, failure_reason_on_C_heap);
    if (CompilationLog::log() != nullptr) {
      CompilationLog::log()->log_failure(thread, task, failure_reason, retry_message);
    }
    if (PrintCompilation) {
      FormatBufferResource msg = retry_message != nullptr ?
        FormatBufferResource("COMPILE SKIPPED: %s (%s)", failure_reason, retry_message) :
        FormatBufferResource("COMPILE SKIPPED: %s",      failure_reason);
      task->print(tty, msg);
    }
  }

  methodHandle method(thread, task->method());

  DTRACE_METHOD_COMPILE_END_PROBE(method, compiler_name(task_level), task->is_success());

  collect_statistics(thread, time, task);

  if (PrintCompilation && PrintCompilation2) {
    tty->print("%7d ", (int) tty->time_stamp().milliseconds());  // print timestamp
    tty->print("%4d ", compile_id);    // print compilation number
    tty->print("%s ", (is_osr ? "%" : " "));
    if (task->is_success()) {
      tty->print("size: %d(%d) ", task->nm_total_size(), task->nm_insts_size());
    }
    tty->print_cr("time: %d inlined: %d bytes", (int)time.milliseconds(), task->num_inlined_bytecodes());
  }

  Log(compilation, codecache) log;
  if (log.is_debug()) {
    LogStream ls(log.debug());
    codecache_print(&ls, /* detailed= */ false);
  }
  if (PrintCodeCacheOnCompilation) {
    codecache_print(/* detailed= */ false);
  }
  // Disable compilation, if required.
  switch (compilable) {
  case ciEnv::MethodCompilable_never:
    if (is_osr)
      method->set_not_osr_compilable_quietly("MethodCompilable_never");
    else
      method->set_not_compilable_quietly("MethodCompilable_never");
    break;
  case ciEnv::MethodCompilable_not_at_tier:
    if (is_osr)
      method->set_not_osr_compilable_quietly("MethodCompilable_not_at_tier", task_level);
    else
      method->set_not_compilable_quietly("MethodCompilable_not_at_tier", task_level);
    break;
  }

  // Note that the queued_for_compilation bits are cleared without
  // protection of a mutex. [They were set by the requester thread,
  // when adding the task to the compile queue -- at which time the
  // compile queue lock was held. Subsequently, we acquired the compile
  // queue lock to get this task off the compile queue; thus (to belabour
  // the point somewhat) our clearing of the bits must be occurring
  // only after the setting of the bits. See also 14012000 above.
  method->clear_queued_for_compilation();
}

/**
 * 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(CodeBlobType code_blob_type) {
  UseInterpreter = true;
  if (UseCompiler || AlwaysCompileLoopMethods ) {
    if (xtty != nullptr) {
      stringStream s;
      // Dump code cache state into a buffer before locking the tty,
      // because log_state() will use locks causing lock conflicts.
      CodeCache::log_state(&s);
      // Lock to prevent tearing
      ttyLocker ttyl;
      xtty->begin_elem("code_cache_full");
      xtty->print("%s", s.freeze());
      xtty->stamp();
      xtty->end_elem();
    }

#ifndef PRODUCT
    if (ExitOnFullCodeCache) {
      codecache_print(/* detailed= */ true);
      before_exit(JavaThread::current());
      exit_globals(); // will delete tty
      vm_direct_exit(1);
    }
#endif
    if (UseCodeCacheFlushing) {
      // Since code cache is full, immediately stop new compiles
      if (CompileBroker::set_should_compile_new_jobs(CompileBroker::stop_compilation)) {
        log_info(codecache)("Code cache is full - disabling compilation");
      }
    } else {
      disable_compilation_forever();
    }

    CodeCache::report_codemem_full(code_blob_type, should_print_compiler_warning());
  }
}

// ------------------------------------------------------------------
// CompileBroker::update_compile_perf_data
//
// Record this compilation for debugging purposes.
void CompileBroker::update_compile_perf_data(CompilerThread* thread, const methodHandle& method, bool is_osr) {
  ResourceMark rm;
  char* method_name = method->name()->as_C_string();
  char current_method[CompilerCounters::cmname_buffer_length];
  size_t maxLen = CompilerCounters::cmname_buffer_length;

  const char* class_name = method->method_holder()->name()->as_C_string();

  size_t s1len = strlen(class_name);
  size_t s2len = strlen(method_name);

  // check if we need to truncate the string
  if (s1len + s2len + 2 > maxLen) {

    // the strategy is to lop off the leading characters of the
    // class name and the trailing characters of the method name.

    if (s2len + 2 > maxLen) {
      // lop of the entire class name string, let snprintf handle
      // truncation of the method name.
      class_name += s1len; // null string
    }
    else {
      // lop off the extra characters from the front of the class name
      class_name += ((s1len + s2len + 2) - maxLen);
    }
  }

  jio_snprintf(current_method, maxLen, "%s %s", class_name, method_name);

  int last_compile_type = normal_compile;
  if (CICountOSR && is_osr) {
    last_compile_type = osr_compile;
  } else if (CICountNative && method->is_native()) {
    last_compile_type = native_compile;
  }

  CompilerCounters* counters = thread->counters();
  counters->set_current_method(current_method);
  counters->set_compile_type((jlong) last_compile_type);
}

// ------------------------------------------------------------------
// CompileBroker::collect_statistics
//
// Collect statistics about the compilation.

void CompileBroker::collect_statistics(CompilerThread* thread, elapsedTimer time, CompileTask* task) {
  bool success = task->is_success();
  methodHandle method (thread, task->method());
  int compile_id = task->compile_id();
  bool is_osr = (task->osr_bci() != standard_entry_bci);
  const int comp_level = task->comp_level();
  CompilerCounters* counters = thread->counters();

  MutexLocker locker(CompileStatistics_lock);

  // _perf variables are production performance counters which are
  // updated regardless of the setting of the CITime and CITimeEach flags
  //

  // account all time, including bailouts and failures in this counter;
  // C1 and C2 counters are counting both successful and unsuccessful compiles
  _t_total_compilation.add(time);

  if (!success) {
    _total_bailout_count++;
    if (UsePerfData) {
      _perf_last_failed_method->set_value(counters->current_method());
      _perf_last_failed_type->set_value(counters->compile_type());
      _perf_total_bailout_count->inc();
    }
    _t_bailedout_compilation.add(time);
  } else if (!task->is_success()) {
    if (UsePerfData) {
      _perf_last_invalidated_method->set_value(counters->current_method());
      _perf_last_invalidated_type->set_value(counters->compile_type());
      _perf_total_invalidated_count->inc();
    }
    _total_invalidated_count++;
    _t_invalidated_compilation.add(time);
  } else {
    // Compilation succeeded

    // update compilation ticks - used by the implementation of
    // java.lang.management.CompilationMXBean
    _perf_total_compilation->inc(time.ticks());
    _peak_compilation_time = time.milliseconds() > _peak_compilation_time ? time.milliseconds() : _peak_compilation_time;

    if (CITime) {
      int bytes_compiled = method->code_size() + task->num_inlined_bytecodes();
      if (is_osr) {
        _t_osr_compilation.add(time);
        _sum_osr_bytes_compiled += bytes_compiled;
      } else {
        _t_standard_compilation.add(time);
        _sum_standard_bytes_compiled += method->code_size() + task->num_inlined_bytecodes();
      }

      // Collect statistic per compilation level
      if (comp_level > CompLevel_none && comp_level <= CompLevel_full_optimization) {
        CompilerStatistics* stats = &_stats_per_level[comp_level-1];
        if (is_osr) {
          stats->_osr.update(time, bytes_compiled);
        } else {
          stats->_standard.update(time, bytes_compiled);
        }
        stats->_nmethods_size += task->nm_total_size();
        stats->_nmethods_code_size += task->nm_insts_size();
      } else {
        assert(false, "CompilerStatistics object does not exist for compilation level %d", comp_level);
      }

      // Collect statistic per compiler
      AbstractCompiler* comp = compiler(comp_level);
      if (comp) {
        CompilerStatistics* stats = comp->stats();
        if (is_osr) {
          stats->_osr.update(time, bytes_compiled);
        } else {
          stats->_standard.update(time, bytes_compiled);
        }
        stats->_nmethods_size += task->nm_total_size();
        stats->_nmethods_code_size += task->nm_insts_size();
      } else { // if (!comp)
        assert(false, "Compiler object must exist");
      }
    }

    if (UsePerfData) {
      // save the name of the last method compiled
      _perf_last_method->set_value(counters->current_method());
      _perf_last_compile_type->set_value(counters->compile_type());
      _perf_last_compile_size->set_value(method->code_size() +
                                         task->num_inlined_bytecodes());
      if (is_osr) {
        _perf_osr_compilation->inc(time.ticks());
        _perf_sum_osr_bytes_compiled->inc(method->code_size() + task->num_inlined_bytecodes());
      } else {
        _perf_standard_compilation->inc(time.ticks());
        _perf_sum_standard_bytes_compiled->inc(method->code_size() + task->num_inlined_bytecodes());
      }
    }

    if (CITimeEach) {
      double compile_time = time.seconds();
      double bytes_per_sec = compile_time == 0.0 ? 0.0 : (double)(method->code_size() + task->num_inlined_bytecodes()) / compile_time;
      tty->print_cr("%3d   seconds: %6.3f bytes/sec : %f (bytes %d + %d inlined)",
                    compile_id, compile_time, bytes_per_sec, method->code_size(), task->num_inlined_bytecodes());
    }

    // Collect counts of successful compilations
    _sum_nmethod_size      += task->nm_total_size();
    _sum_nmethod_code_size += task->nm_insts_size();
    _total_compile_count++;

    if (UsePerfData) {
      _perf_sum_nmethod_size->inc(     task->nm_total_size());
      _perf_sum_nmethod_code_size->inc(task->nm_insts_size());
      _perf_total_compile_count->inc();
    }

    if (is_osr) {
      if (UsePerfData) _perf_total_osr_compile_count->inc();
      _total_osr_compile_count++;
    } else {
      if (UsePerfData) _perf_total_standard_compile_count->inc();
      _total_standard_compile_count++;
    }
  }
  // set the current method for the thread to null
  if (UsePerfData) counters->set_current_method("");
}

const char* CompileBroker::compiler_name(int comp_level) {
  AbstractCompiler *comp = CompileBroker::compiler(comp_level);
  if (comp == nullptr) {
    return "no compiler";
  } else {
    return (comp->name());
  }
}

jlong CompileBroker::total_compilation_ticks() {
  return _perf_total_compilation != nullptr ? _perf_total_compilation->get_value() : 0;
}

void CompileBroker::print_times(const char* name, CompilerStatistics* stats) {
  tty->print_cr("  %s {speed: %6.3f bytes/s; standard: %6.3f s, %d bytes, %d methods; osr: %6.3f s, %d bytes, %d methods; nmethods_size: %d bytes; nmethods_code_size: %d bytes}",
                name, stats->bytes_per_second(),
                stats->_standard._time.seconds(), stats->_standard._bytes, stats->_standard._count,
                stats->_osr._time.seconds(), stats->_osr._bytes, stats->_osr._count,
                stats->_nmethods_size, stats->_nmethods_code_size);
}

void CompileBroker::print_times(bool per_compiler, bool aggregate) {
  if (per_compiler) {
    if (aggregate) {
      tty->cr();
      tty->print_cr("Individual compiler times (for compiled methods only)");
      tty->print_cr("------------------------------------------------");
      tty->cr();
    }
    for (unsigned int i = 0; i < sizeof(_compilers) / sizeof(AbstractCompiler*); i++) {
      AbstractCompiler* comp = _compilers[i];
      if (comp != nullptr) {
        print_times(comp->name(), comp->stats());
      }
    }
    if (aggregate) {
      tty->cr();
      tty->print_cr("Individual compilation Tier times (for compiled methods only)");
      tty->print_cr("------------------------------------------------");
      tty->cr();
    }
    char tier_name[256];
    for (int tier = CompLevel_simple; tier <= CompilationPolicy::highest_compile_level(); tier++) {
      CompilerStatistics* stats = &_stats_per_level[tier-1];
      os::snprintf_checked(tier_name, sizeof(tier_name), "Tier%d", tier);
      print_times(tier_name, stats);
    }
  }

  if (!aggregate) {
    return;
  }

  elapsedTimer standard_compilation = CompileBroker::_t_standard_compilation;
  elapsedTimer osr_compilation = CompileBroker::_t_osr_compilation;
  elapsedTimer total_compilation = CompileBroker::_t_total_compilation;

  int standard_bytes_compiled = CompileBroker::_sum_standard_bytes_compiled;
  int osr_bytes_compiled = CompileBroker::_sum_osr_bytes_compiled;

  int standard_compile_count = CompileBroker::_total_standard_compile_count;
  int osr_compile_count = CompileBroker::_total_osr_compile_count;
  int total_compile_count = CompileBroker::_total_compile_count;
  int total_bailout_count = CompileBroker::_total_bailout_count;
  int total_invalidated_count = CompileBroker::_total_invalidated_count;

  int nmethods_code_size = CompileBroker::_sum_nmethod_code_size;
  int nmethods_size = CompileBroker::_sum_nmethod_size;

  tty->cr();
  tty->print_cr("Accumulated compiler times");
  tty->print_cr("----------------------------------------------------------");
               //0000000000111111111122222222223333333333444444444455555555556666666666
               //0123456789012345678901234567890123456789012345678901234567890123456789
  tty->print_cr("  Total compilation time   : %7.3f s", total_compilation.seconds());
  tty->print_cr("    Standard compilation   : %7.3f s, Average : %2.3f s",
                standard_compilation.seconds(),
                standard_compile_count == 0 ? 0.0 : standard_compilation.seconds() / standard_compile_count);
  tty->print_cr("    Bailed out compilation : %7.3f s, Average : %2.3f s",
                CompileBroker::_t_bailedout_compilation.seconds(),
                total_bailout_count == 0 ? 0.0 : CompileBroker::_t_bailedout_compilation.seconds() / total_bailout_count);
  tty->print_cr("    On stack replacement   : %7.3f s, Average : %2.3f s",
                osr_compilation.seconds(),
                osr_compile_count == 0 ? 0.0 : osr_compilation.seconds() / osr_compile_count);
  tty->print_cr("    Invalidated            : %7.3f s, Average : %2.3f s",
                CompileBroker::_t_invalidated_compilation.seconds(),
                total_invalidated_count == 0 ? 0.0 : CompileBroker::_t_invalidated_compilation.seconds() / total_invalidated_count);

  AbstractCompiler *comp = compiler(CompLevel_simple);
  if (comp != nullptr) {
    tty->cr();
    comp->print_timers();
  }
  comp = compiler(CompLevel_full_optimization);
  if (comp != nullptr) {
    tty->cr();
    comp->print_timers();
  }
#if INCLUDE_JVMCI
  if (EnableJVMCI) {
    JVMCICompiler *jvmci_comp = JVMCICompiler::instance(false, JavaThread::current_or_null());
    if (jvmci_comp != nullptr && jvmci_comp != comp) {
      tty->cr();
      jvmci_comp->print_timers();
    }
  }
#endif

  tty->cr();
  tty->print_cr("  Total compiled methods    : %8d methods", total_compile_count);
  tty->print_cr("    Standard compilation    : %8d methods", standard_compile_count);
  tty->print_cr("    On stack replacement    : %8d methods", osr_compile_count);
  int tcb = osr_bytes_compiled + standard_bytes_compiled;
  tty->print_cr("  Total compiled bytecodes  : %8d bytes", tcb);
  tty->print_cr("    Standard compilation    : %8d bytes", standard_bytes_compiled);
  tty->print_cr("    On stack replacement    : %8d bytes", osr_bytes_compiled);
  double tcs = total_compilation.seconds();
  int bps = tcs == 0.0 ? 0 : (int)(tcb / tcs);
  tty->print_cr("  Average compilation speed : %8d bytes/s", bps);
  tty->cr();
  tty->print_cr("  nmethod code size         : %8d bytes", nmethods_code_size);
  tty->print_cr("  nmethod total size        : %8d bytes", nmethods_size);
}

// Print general/accumulated JIT information.
void CompileBroker::print_info(outputStream *out) {
  if (out == nullptr) out = tty;
  out->cr();
  out->print_cr("======================");
  out->print_cr("   General JIT info   ");
  out->print_cr("======================");
  out->cr();
  out->print_cr("            JIT is : %7s",     should_compile_new_jobs() ? "on" : "off");
  out->print_cr("  Compiler threads : %7d",     (int)CICompilerCount);
  out->cr();
  out->print_cr("CodeCache overview");
  out->print_cr("--------------------------------------------------------");
  out->cr();
  out->print_cr("         Reserved size : " SIZE_FORMAT_W(7) " KB", CodeCache::max_capacity() / K);
  out->print_cr("        Committed size : " SIZE_FORMAT_W(7) " KB", CodeCache::capacity() / K);
  out->print_cr("  Unallocated capacity : " SIZE_FORMAT_W(7) " KB", CodeCache::unallocated_capacity() / K);
  out->cr();
}

// Note: tty_lock must not be held upon entry to this function.
//       Print functions called from herein do "micro-locking" on tty_lock.
//       That's a tradeoff which keeps together important blocks of output.
//       At the same time, continuous tty_lock hold time is kept in check,
//       preventing concurrently printing threads from stalling a long time.
void CompileBroker::print_heapinfo(outputStream* out, const char* function, size_t granularity) {
  TimeStamp ts_total;
  TimeStamp ts_global;
  TimeStamp ts;

  bool allFun = !strcmp(function, "all");
  bool aggregate = !strcmp(function, "aggregate") || !strcmp(function, "analyze") || allFun;
  bool usedSpace = !strcmp(function, "UsedSpace") || allFun;
  bool freeSpace = !strcmp(function, "FreeSpace") || allFun;
  bool methodCount = !strcmp(function, "MethodCount") || allFun;
  bool methodSpace = !strcmp(function, "MethodSpace") || allFun;
  bool methodAge = !strcmp(function, "MethodAge") || allFun;
  bool methodNames = !strcmp(function, "MethodNames") || allFun;
  bool discard = !strcmp(function, "discard") || allFun;

  if (out == nullptr) {
    out = tty;
  }

  if (!(aggregate || usedSpace || freeSpace || methodCount || methodSpace || methodAge || methodNames || discard)) {
    out->print_cr("\n__ CodeHeapStateAnalytics: Function %s is not supported", function);
    out->cr();
    return;
  }

  ts_total.update(); // record starting point

  if (aggregate) {
    print_info(out);
  }

  // We hold the CodeHeapStateAnalytics_lock all the time, from here until we leave this function.
  // That prevents other threads from destroying (making inconsistent) our view on the CodeHeap.
  // When we request individual parts of the analysis via the jcmd interface, it is possible
  // that in between another thread (another jcmd user or the vm running into CodeCache OOM)
  // updated the aggregated data. We will then see a modified, but again consistent, view
  // on the CodeHeap. That's a tolerable tradeoff we have to accept because we can't hold
  // a lock across user interaction.

  // We should definitely acquire this lock before acquiring Compile_lock and CodeCache_lock.
  // CodeHeapStateAnalytics_lock may be held by a concurrent thread for a long time,
  // leading to an unnecessarily long hold time of the other locks we acquired before.
  ts.update(); // record starting point
  MutexLocker mu0(CodeHeapStateAnalytics_lock, Mutex::_safepoint_check_flag);
  out->print_cr("\n__ CodeHeapStateAnalytics lock wait took %10.3f seconds _________\n", ts.seconds());

  // Holding the CodeCache_lock protects from concurrent alterations of the CodeCache.
  // Unfortunately, such protection is not sufficient:
  // When a new nmethod is created via ciEnv::register_method(), the
  // Compile_lock is taken first. After some initializations,
  // nmethod::new_nmethod() takes over, grabbing the CodeCache_lock
  // immediately (after finalizing the oop references). To lock out concurrent
  // modifiers, we have to grab both locks as well in the described sequence.
  //
  // If we serve an "allFun" call, it is beneficial to hold CodeCache_lock and Compile_lock
  // for the entire duration of aggregation and printing. That makes sure we see
  // a consistent picture and do not run into issues caused by concurrent alterations.
  bool should_take_Compile_lock   = !SafepointSynchronize::is_at_safepoint() &&
                                    !Compile_lock->owned_by_self();
  bool should_take_CodeCache_lock = !SafepointSynchronize::is_at_safepoint() &&
                                    !CodeCache_lock->owned_by_self();
  Mutex*   global_lock_1   = allFun ? (should_take_Compile_lock   ? Compile_lock   : nullptr) : nullptr;
  Monitor* global_lock_2   = allFun ? (should_take_CodeCache_lock ? CodeCache_lock : nullptr) : nullptr;
  Mutex*   function_lock_1 = allFun ? nullptr : (should_take_Compile_lock   ? Compile_lock    : nullptr);
  Monitor* function_lock_2 = allFun ? nullptr : (should_take_CodeCache_lock ? CodeCache_lock  : nullptr);
  ts_global.update(); // record starting point
  MutexLocker mu1(global_lock_1, Mutex::_safepoint_check_flag);
  MutexLocker mu2(global_lock_2, Mutex::_no_safepoint_check_flag);
  if ((global_lock_1 != nullptr) || (global_lock_2 != nullptr)) {
    out->print_cr("\n__ Compile & CodeCache (global) lock wait took %10.3f seconds _________\n", ts_global.seconds());
    ts_global.update(); // record starting point
  }

  if (aggregate) {
    ts.update(); // record starting point
    MutexLocker mu11(function_lock_1, Mutex::_safepoint_check_flag);
    MutexLocker mu22(function_lock_2, Mutex::_no_safepoint_check_flag);
    if ((function_lock_1 != nullptr) || (function_lock_2 != nullptr)) {
      out->print_cr("\n__ Compile & CodeCache (function) lock wait took %10.3f seconds _________\n", ts.seconds());
    }

    ts.update(); // record starting point
    CodeCache::aggregate(out, granularity);
    if ((function_lock_1 != nullptr) || (function_lock_2 != nullptr)) {
      out->print_cr("\n__ Compile & CodeCache (function) lock hold took %10.3f seconds _________\n", ts.seconds());
    }
  }

  if (usedSpace) CodeCache::print_usedSpace(out);
  if (freeSpace) CodeCache::print_freeSpace(out);
  if (methodCount) CodeCache::print_count(out);
  if (methodSpace) CodeCache::print_space(out);
  if (methodAge) CodeCache::print_age(out);
  if (methodNames) {
    if (allFun) {
      // print_names() can only be used safely if the locks have been continuously held
      // since aggregation begin. That is true only for function "all".
      CodeCache::print_names(out);
    } else {
      out->print_cr("\nCodeHeapStateAnalytics: Function 'MethodNames' is only available as part of function 'all'");
    }
  }
  if (discard) CodeCache::discard(out);

  if ((global_lock_1 != nullptr) || (global_lock_2 != nullptr)) {
    out->print_cr("\n__ Compile & CodeCache (global) lock hold took %10.3f seconds _________\n", ts_global.seconds());
  }
  out->print_cr("\n__ CodeHeapStateAnalytics total duration %10.3f seconds _________\n", ts_total.seconds());
}
