diff a/src/hotspot/share/compiler/compileTask.hpp b/src/hotspot/share/compiler/compileTask.hpp
--- a/src/hotspot/share/compiler/compileTask.hpp
+++ b/src/hotspot/share/compiler/compileTask.hpp
@@ -29,11 +29,14 @@
 #include "code/nmethod.hpp"
 #include "compiler/compileLog.hpp"
 #include "memory/allocation.hpp"
 #include "utilities/xmlstream.hpp"
 
+class CompileQueue;
+class CompileTrainingData;
 class DirectiveSet;
+class SCCEntry;
 
 JVMCI_ONLY(class JVMCICompileState;)
 
 enum class InliningResult { SUCCESS, FAILURE };
 
@@ -60,10 +63,13 @@
       Reason_Tiered,           // Tiered-policy
       Reason_Replay,           // ciReplay
       Reason_Whitebox,         // Whitebox API
       Reason_MustBeCompiled,   // Used for -Xcomp or AlwaysCompileLoopMethods (see CompilationPolicy::must_be_compiled())
       Reason_Bootstrap,        // JVMCI bootstrap
+      Reason_Preload,          // pre-load SC code
+      Reason_Precompile,
+      Reason_PrecompileForPreload,
       Reason_Count
   };
 
   static const char* reason_name(CompileTask::CompileReason compile_reason) {
     static const char* reason_names[] = {
@@ -72,77 +78,101 @@
       "backedge_count",
       "tiered",
       "replay",
       "whitebox",
       "must_be_compiled",
-      "bootstrap"
+      "bootstrap",
+      "preload",
+      "precompile",
+      "precompile_for_preload",
     };
     return reason_names[compile_reason];
   }
 
+  static bool reason_is_precompiled(CompileTask::CompileReason compile_reason) {
+    return (compile_reason == CompileTask::Reason_Precompile) ||
+           (compile_reason == CompileTask::Reason_PrecompileForPreload);
+  }
+
  private:
   static CompileTask*  _task_free_list;
   Monitor*             _lock;
   int                  _compile_id;
   Method*              _method;
   jobject              _method_holder;
   int                  _osr_bci;
   bool                 _is_complete;
   bool                 _is_success;
+  bool                 _requires_online_compilation;
   bool                 _is_blocking;
   CodeSection::csize_t _nm_content_size;
   CodeSection::csize_t _nm_total_size;
   CodeSection::csize_t _nm_insts_size;
   DirectiveSet*  _directive;
+  AbstractCompiler*    _compiler;
+  SCCEntry*            _scc_entry;
 #if INCLUDE_JVMCI
   bool                 _has_waiter;
   // Compilation state for a blocking JVMCI compilation
   JVMCICompileState*   _blocking_jvmci_compile_state;
 #endif
   int                  _comp_level;
   int                  _num_inlined_bytecodes;
-  CompileTask*         _next, *_prev;
+  CompileTask*         _next;
+  CompileTask*         _prev;
   bool                 _is_free;
   // Fields used for logging why the compilation was initiated:
+  jlong                _time_created; // time when task was created
   jlong                _time_queued;  // time when task was enqueued
   jlong                _time_started; // time when compilation started
+  jlong                _time_finished; // time when compilation finished
   Method*              _hot_method;   // which method actually triggered this task
   jobject              _hot_method_holder;
   int                  _hot_count;    // information about its invocation counter
   CompileReason        _compile_reason;      // more info about the task
   const char*          _failure_reason;
   // Specifies if _failure_reason is on the C heap.
   bool                 _failure_reason_on_C_heap;
+  CompileTrainingData* _training_data;
+  CompileQueue*        _compile_queue;
   size_t               _arena_bytes;  // peak size of temporary memory during compilation (e.g. node arenas)
 
  public:
   CompileTask() : _failure_reason(nullptr), _failure_reason_on_C_heap(false) {
     // May hold MethodCompileQueue_lock
     _lock = new Monitor(Mutex::safepoint-1, "CompileTask_lock");
   }
 
   void initialize(int compile_id, const methodHandle& method, int osr_bci, int comp_level,
-                  const methodHandle& hot_method, int hot_count,
-                  CompileTask::CompileReason compile_reason, bool is_blocking);
+                  const methodHandle& hot_method, int hot_count, SCCEntry* scc_entry,
+                  CompileTask::CompileReason compile_reason,
+                  CompileQueue* compile_queue,
+                  bool requires_online_compilation, bool is_blocking);
 
   static CompileTask* allocate();
   static void         free(CompileTask* task);
 
-  int          compile_id() const                { return _compile_id; }
-  Method*      method() const                    { return _method; }
-  Method*      hot_method() const                { return _hot_method; }
-  int          osr_bci() const                   { return _osr_bci; }
-  bool         is_complete() const               { return _is_complete; }
-  bool         is_blocking() const               { return _is_blocking; }
-  bool         is_success() const                { return _is_success; }
-  DirectiveSet* directive() const                { return _directive; }
+  int          compile_id() const                   { return _compile_id; }
+  Method*      method() const                       { return _method; }
+  Method*      hot_method() const                   { return _hot_method; }
+  int          osr_bci() const                      { return _osr_bci; }
+  bool         is_complete() const                  { return _is_complete; }
+  bool         is_blocking() const                  { return _is_blocking; }
+  bool         is_success() const                   { return _is_success; }
+  bool         is_scc() const                       { return _scc_entry != nullptr; }
+  void         clear_scc()                          { _scc_entry = nullptr; }
+  SCCEntry*    scc_entry()                          { return _scc_entry; }
+  bool         requires_online_compilation() const  { return _requires_online_compilation; }
+  DirectiveSet* directive() const                   { return _directive; }
+  CompileReason compile_reason() const              { return _compile_reason; }
   CodeSection::csize_t nm_content_size() { return _nm_content_size; }
   void         set_nm_content_size(CodeSection::csize_t size) { _nm_content_size = size; }
   CodeSection::csize_t nm_insts_size() { return _nm_insts_size; }
   void         set_nm_insts_size(CodeSection::csize_t size) { _nm_insts_size = size; }
   CodeSection::csize_t nm_total_size() { return _nm_total_size; }
   void         set_nm_total_size(CodeSection::csize_t size) { _nm_total_size = size; }
+  bool         preload() const                   { return (_compile_reason == Reason_Preload); }
   bool         can_become_stale() const          {
     switch (_compile_reason) {
       case Reason_BackedgeCount:
       case Reason_InvocationCount:
       case Reason_Tiered:
@@ -170,53 +200,71 @@
   void         set_blocking_jvmci_compile_state(JVMCICompileState* state) {
     _blocking_jvmci_compile_state = state;
   }
 #endif
 
+  bool is_precompiled() {
+    return reason_is_precompiled(compile_reason());
+  }
+
   Monitor*     lock() const                      { return _lock; }
 
+  CompileQueue* compile_queue() const            { return _compile_queue; }
+
   void         mark_complete()                   { _is_complete = true; }
   void         mark_success()                    { _is_success = true; }
+  void         mark_queued(jlong time)           { _time_queued = time; }
   void         mark_started(jlong time)          { _time_started = time; }
+  void         mark_finished(jlong time)         { _time_finished = time; }
 
   int          comp_level()                      { return _comp_level;}
   void         set_comp_level(int comp_level)    { _comp_level = comp_level;}
 
   AbstractCompiler* compiler() const;
   CompileTask*      select_for_compilation();
 
   int          num_inlined_bytecodes() const     { return _num_inlined_bytecodes; }
   void         set_num_inlined_bytecodes(int n)  { _num_inlined_bytecodes = n; }
 
+  static CompileTask* volatile* next_ptr(CompileTask& task) { return &task._next; }
+
   CompileTask* next() const                      { return _next; }
   void         set_next(CompileTask* next)       { _next = next; }
   CompileTask* prev() const                      { return _prev; }
   void         set_prev(CompileTask* prev)       { _prev = prev; }
   bool         is_free() const                   { return _is_free; }
   void         set_is_free(bool val)             { _is_free = val; }
   bool         is_unloaded() const;
 
+  CompileTrainingData* training_data() const     { return _training_data; }
+  void set_training_data(CompileTrainingData*td) { _training_data = td; }
+
+  CompileReason compile_reason()                 { return _compile_reason; }
+
   // RedefineClasses support
   void         metadata_do(MetadataClosure* f);
   void         mark_on_stack();
 
   void         set_arena_bytes(size_t s)         { _arena_bytes = s; }
   size_t       arena_bytes() const               { return _arena_bytes; }
 
 private:
   static void  print_impl(outputStream* st, Method* method, int compile_id, int comp_level,
                                       bool is_osr_method = false, int osr_bci = -1, bool is_blocking = false,
+                                      bool is_scc = false, bool is_preload = false,
+                                      const char* compiler_name = nullptr,
                                       const char* msg = nullptr, bool short_form = false, bool cr = true,
-                                      jlong time_queued = 0, jlong time_started = 0);
+                                      jlong time_created = 0, jlong time_queued = 0, jlong time_started = 0, jlong time_finished = 0);
 
 public:
   void         print(outputStream* st = tty, const char* msg = nullptr, bool short_form = false, bool cr = true);
   void         print_ul(const char* msg = nullptr);
   static void  print(outputStream* st, const nmethod* nm, const char* msg = nullptr, bool short_form = false, bool cr = true) {
     print_impl(st, nm->method(), nm->compile_id(), nm->comp_level(),
                            nm->is_osr_method(), nm->is_osr_method() ? nm->osr_entry_bci() : -1, /*is_blocking*/ false,
-                           msg, short_form, cr);
+                           nm->scc_entry() != nullptr, nm->preloaded(),
+                           nm->compiler_name(), msg, short_form, cr);
   }
   static void  print_ul(const nmethod* nm, const char* msg = nullptr);
 
   static void  print_inline_indent(int inline_level, outputStream* st = tty);
 
