< prev index next >

src/hotspot/share/ci/ciEnv.cpp

Print this page
@@ -20,10 +20,12 @@
   * or visit www.oracle.com if you need additional information or have any
   * questions.
   *
   */
  
+ #include "cds/archiveBuilder.hpp"
+ #include "cds/cdsConfig.hpp"
  #include "ci/ciConstant.hpp"
  #include "ci/ciEnv.hpp"
  #include "ci/ciField.hpp"
  #include "ci/ciInstance.hpp"
  #include "ci/ciInstanceKlass.hpp"

@@ -36,18 +38,20 @@
  #include "classfile/javaClasses.inline.hpp"
  #include "classfile/systemDictionary.hpp"
  #include "classfile/vmClasses.hpp"
  #include "classfile/vmSymbols.hpp"
  #include "code/codeCache.hpp"
+ #include "code/SCCache.hpp"
  #include "code/scopeDesc.hpp"
  #include "compiler/compilationLog.hpp"
  #include "compiler/compilationPolicy.hpp"
  #include "compiler/compileBroker.hpp"
  #include "compiler/compileLog.hpp"
  #include "compiler/compilerEvent.hpp"
  #include "compiler/compileTask.hpp"
  #include "compiler/disassembler.hpp"
+ #include "gc/shared/barrierSetNMethod.hpp"
  #include "gc/shared/collectedHeap.inline.hpp"
  #include "interpreter/bytecodeStream.hpp"
  #include "interpreter/linkResolver.hpp"
  #include "jfr/jfrEvents.hpp"
  #include "jvm.h"

@@ -63,13 +67,15 @@
  #include "oops/objArrayKlass.hpp"
  #include "oops/objArrayOop.inline.hpp"
  #include "oops/oop.inline.hpp"
  #include "oops/resolvedIndyEntry.hpp"
  #include "oops/symbolHandle.hpp"
+ #include "oops/trainingData.hpp"
  #include "prims/jvmtiExport.hpp"
  #include "prims/methodHandles.hpp"
  #include "runtime/fieldDescriptor.inline.hpp"
+ #include "runtime/flags/flagSetting.hpp"
  #include "runtime/handles.inline.hpp"
  #include "runtime/init.hpp"
  #include "runtime/javaThread.hpp"
  #include "runtime/jniHandles.inline.hpp"
  #include "runtime/reflection.hpp"

@@ -170,10 +176,12 @@
    _jvmti_can_hotswap_or_post_breakpoint = false;
    _jvmti_can_access_local_variables = false;
    _jvmti_can_post_on_exceptions = false;
    _jvmti_can_pop_frame = false;
  
+   _scc_clinit_barriers_entry = nullptr;
+ 
    _dyno_klasses = nullptr;
    _dyno_locs = nullptr;
    _dyno_name[0] = '\0';
  }
  

@@ -290,10 +298,12 @@
    _jvmti_can_hotswap_or_post_breakpoint = false;
    _jvmti_can_access_local_variables = false;
    _jvmti_can_post_on_exceptions = false;
    _jvmti_can_pop_frame = false;
  
+   _scc_clinit_barriers_entry = nullptr;
+ 
    _dyno_klasses = nullptr;
    _dyno_locs = nullptr;
  }
  
  ciEnv::~ciEnv() {

@@ -665,11 +675,11 @@
  ciConstant ciEnv::get_constant_by_index_impl(const constantPoolHandle& cpool,
                                               int index, int obj_index,
                                               ciInstanceKlass* accessor) {
    if (obj_index >= 0) {
      ciConstant con = get_resolved_constant(cpool, obj_index);
-     if (con.is_valid()) {
+     if (con.should_be_constant()) {
        return con;
      }
    }
    constantTag tag = cpool->tag_at(index);
    if (tag.is_int()) {

@@ -866,15 +876,15 @@
  
      if (holder_is_accessible) {  // Our declared holder is loaded.
        constantTag tag = cpool->tag_ref_at(index, bc);
        assert(accessor->get_instanceKlass() == cpool->pool_holder(), "not the pool holder?");
        Method* m = lookup_method(accessor, holder, name_sym, sig_sym, bc, tag);
-       if (m != nullptr &&
-           (bc == Bytecodes::_invokestatic
-            ?  m->method_holder()->is_not_initialized()
-            : !m->method_holder()->is_loaded())) {
-         m = nullptr;
+       if (m != nullptr) {
+         ciInstanceKlass* cik = get_instance_klass(m->method_holder());
+         if ((bc == Bytecodes::_invokestatic && cik->is_not_initialized()) || !cik->is_loaded()) {
+           m = nullptr;
+         }
        }
        if (m != nullptr && ReplayCompiles && !ciReplay::is_loaded(m)) {
          m = nullptr;
        }
        if (m != nullptr) {

@@ -951,11 +961,11 @@
  // ciEnv::validate_compile_task_dependencies
  //
  // Check for changes during compilation (e.g. class loads, evolution,
  // breakpoints, call site invalidation).
  void ciEnv::validate_compile_task_dependencies(ciMethod* target) {
-   if (failing())  return;  // no need for further checks
+   assert(!failing(), "should not call this when failing");
  
    Dependencies::DepType result = dependencies()->validate_dependencies(_task);
    if (result != Dependencies::end_marker) {
      if (result == Dependencies::call_site_target_value) {
        _inc_decompile_count_on_failure = false;

@@ -966,10 +976,218 @@
        record_failure("invalid non-klass dependency");
      }
    }
  }
  
+ // scc_entry != nullptr implies loading compiled code from AOT code cache
+ bool ciEnv::is_compilation_valid(JavaThread* thread, ciMethod* target, bool preload, bool install_code, CodeBuffer* code_buffer, SCCEntry* scc_entry) {
+   methodHandle method(thread, target->get_Method());
+ 
+   // We require method counters to store some method state (max compilation levels) required by the compilation policy.
+   if (!preload && method->get_method_counters(thread) == nullptr) {
+     record_failure("can't create method counters");
+     if (code_buffer != nullptr) {
+       code_buffer->free_blob();
+     }
+     return false;
+   }
+ 
+   if (scc_entry != nullptr) {
+     // Invalid compilation states:
+     //  - SCCache is closed, SCC entry is garbage.
+     //  - SCC entry indicates this shared code was marked invalid while it was loaded.
+     if (!SCCache::is_on() || scc_entry->not_entrant()) {
+       return false;
+     }
+   }
+ 
+   // Change in Jvmti state may invalidate compilation.
+   if (!failing() && jvmti_state_changed()) {
+     record_failure("Jvmti state change invalidated dependencies");
+   }
+ 
+   // Change in DTrace flags may invalidate compilation.
+   if (!failing() &&
+       ( (!dtrace_method_probes() && DTraceMethodProbes) ||
+         (!dtrace_alloc_probes() && DTraceAllocProbes) )) {
+     record_failure("DTrace flags change invalidated dependencies");
+   }
+ 
+   if (!preload && !failing() && target->needs_clinit_barrier() &&
+       target->holder()->is_in_error_state()) {
+     record_failure("method holder is in error state");
+   }
+ 
+   if (!failing() && (scc_entry == nullptr)) {
+     if (log() != nullptr) {
+       // Log the dependencies which this compilation declares.
+       dependencies()->log_all_dependencies();
+     }
+ 
+     // Encode the dependencies now, so we can check them right away.
+     dependencies()->encode_content_bytes();
+   }
+   // Check for {class loads, evolution, breakpoints, ...} during compilation
+   if (!failing() && install_code) {
+     // Check for {class loads, evolution, breakpoints, ...} during compilation
+     validate_compile_task_dependencies(target);
+     if (failing() && preload) {
+       ResourceMark rm;
+       char *method_name = method->name_and_sig_as_C_string();
+       log_info(scc)("preload code for '%s' failed dependency check", method_name);
+     }
+   }
+ 
+   if (failing()) {
+     // While not a true deoptimization, it is a preemptive decompile.
+     MethodData* mdo = method()->method_data();
+     if (mdo != nullptr && _inc_decompile_count_on_failure) {
+       mdo->inc_decompile_count();
+     }
+ 
+     if (code_buffer != nullptr) {
+       code_buffer->free_blob();
+     }
+     return false;
+   }
+   return true;
+ }
+ 
+ void ciEnv::make_code_usable(JavaThread* thread, ciMethod* target, bool preload, int entry_bci, SCCEntry* scc_entry, nmethod* nm) {
+   methodHandle method(thread, target->get_Method());
+ 
+   if (entry_bci == InvocationEntryBci) {
+     if (TieredCompilation) {
+       // If there is an old version we're done with it
+       nmethod* old = method->code();
+       if (TraceMethodReplacement && old != nullptr) {
+         ResourceMark rm;
+         char *method_name = method->name_and_sig_as_C_string();
+         tty->print_cr("Replacing method %s", method_name);
+       }
+       if (old != nullptr) {
+         old->make_not_used();
+       }
+     }
+ 
+     LogTarget(Info, nmethod, install) lt;
+     if (lt.is_enabled()) {
+       ResourceMark rm;
+       char *method_name = method->name_and_sig_as_C_string();
+       lt.print("Installing method (L%d) %s id=%d scc=%s%s%u",
+                task()->comp_level(), method_name, compile_id(),
+                task()->is_scc() ? "A" : "", preload ? "P" : "",
+                (scc_entry != nullptr ? scc_entry->offset() : 0));
+     }
+     // Allow the code to be executed
+     MutexLocker ml(NMethodState_lock, Mutex::_no_safepoint_check_flag);
+     if (nm->make_in_use()) {
+ #ifdef ASSERT
+       BarrierSetNMethod* bs_nm = BarrierSet::barrier_set()->barrier_set_nmethod();
+       if (bs_nm != nullptr && bs_nm->supports_entry_barrier(nm)) {
+         if (!bs_nm->is_armed(nm)) {
+           log_info(init)("nmethod %d %d not armed", nm->compile_id(), nm->comp_level());
+         }
+       }
+ #endif // ASSERT
+       if (preload) {
+         nm->set_preloaded(true);
+         method->set_preload_code(nm);
+       }
+       if (!preload || target->holder()->is_linked()) {
+         method->set_code(method, nm);
+       }
+     }
+   } else {
+     LogTarget(Info, nmethod, install) lt;
+     if (lt.is_enabled()) {
+       ResourceMark rm;
+       char *method_name = method->name_and_sig_as_C_string();
+       lt.print("Installing osr method (L%d) %s @ %d id=%u scc=%s%u",
+                task()->comp_level(), method_name, entry_bci, compile_id(),
+                task()->is_scc() ? "A" : "",
+                (scc_entry != nullptr ? scc_entry->offset() : 0));
+     }
+     MutexLocker ml(NMethodState_lock, Mutex::_no_safepoint_check_flag);
+     if (nm->make_in_use()) {
+       method->method_holder()->add_osr_nmethod(nm);
+     }
+   }
+ }
+ 
+ void ciEnv::register_aot_method(JavaThread* thread,
+                                 ciMethod* target,
+                                 AbstractCompiler* compiler,
+                                 nmethod* archived_nm,
+                                 address reloc_data,
+                                 GrowableArray<Handle>& oop_list,
+                                 GrowableArray<Metadata*>& metadata_list,
+                                 ImmutableOopMapSet* oopmaps,
+                                 address immutable_data,
+                                 GrowableArray<Handle>& reloc_imm_oop_list,
+                                 GrowableArray<Metadata*>& reloc_imm_metadata_list,
+ #ifndef PRODUCT
+                                 AsmRemarks& asm_remarks,
+                                 DbgStrings& dbg_strings,
+ #endif /* PRODUCT */
+                                 SCCReader* scc_reader)
+ {
+   SCCEntry* scc_entry = task()->scc_entry();
+   assert(scc_entry != nullptr, "must be");
+   nmethod* nm = nullptr;
+   {
+     methodHandle method(thread, target->get_Method());
+     bool preload = task()->preload(); // Code is preloaded before Java method execution
+ 
+     // Check if memory should be freed before allocation
+     CodeCache::gc_on_allocation();
+ 
+     // To prevent compile queue updates.
+     MutexLocker locker(thread, task()->compile_queue()->lock());
+ 
+     // Prevent InstanceKlass::add_to_hierarchy from running
+     // and invalidating our dependencies until we install this method.
+     // No safepoints are allowed. Otherwise, class redefinition can occur in between.
+     MutexLocker ml(Compile_lock);
+     NoSafepointVerifier nsv;
+ 
+     if (!is_compilation_valid(thread, target, preload, true /*install_code*/, nullptr /*code_buffer*/, scc_entry)) {
+       return;
+     }
+ 
+     nm = nmethod::new_nmethod(archived_nm,
+                               method,
+                               compiler,
+                               compile_id(),
+                               reloc_data,
+                               oop_list,
+                               metadata_list,
+                               oopmaps,
+                               immutable_data,
+                               reloc_imm_oop_list,
+                               reloc_imm_metadata_list,
+                               NOT_PRODUCT_ARG(asm_remarks)
+                               NOT_PRODUCT_ARG(dbg_strings)
+                               scc_reader);
+ 
+     if (nm != nullptr) {
+       make_code_usable(thread, target, preload, InvocationEntryBci, scc_entry, nm);
+     }
+   }
+ 
+   NoSafepointVerifier nsv;
+   if (nm != nullptr) {
+     // Compilation succeeded, post what we know about it
+     nm->post_compiled_method(task());
+     task()->set_num_inlined_bytecodes(num_inlined_bytecodes());
+   } else {
+     // The CodeCache is full.
+     record_failure("code cache is full");
+   }
+   // safepoints are allowed again
+ }
+ 
  // ------------------------------------------------------------------
  // ciEnv::register_method
  void ciEnv::register_method(ciMethod* target,
                              int entry_bci,
                              CodeOffsets* offsets,

@@ -978,159 +1196,95 @@
                              int frame_words,
                              OopMapSet* oop_map_set,
                              ExceptionHandlerTable* handler_table,
                              ImplicitExceptionTable* inc_table,
                              AbstractCompiler* compiler,
+                             bool has_clinit_barriers,
+                             bool for_preload,
                              bool has_unsafe_access,
                              bool has_wide_vectors,
                              bool has_monitors,
                              bool has_scoped_access,
-                             int immediate_oops_patched) {
+                             int immediate_oops_patched,
+                             bool install_code,
+                             SCCEntry* scc_entry) {
    VM_ENTRY_MARK;
    nmethod* nm = nullptr;
    {
      methodHandle method(THREAD, target->get_Method());
- 
-     // We require method counters to store some method state (max compilation levels) required by the compilation policy.
-     if (method->get_method_counters(THREAD) == nullptr) {
-       record_failure("can't create method counters");
-       // All buffers in the CodeBuffer are allocated in the CodeCache.
-       // If the code buffer is created on each compile attempt
-       // as in C2, then it must be freed.
-       code_buffer->free_blob();
-       return;
-     }
+     bool preload = task()->preload(); // Code is preloaded before Java method execution
  
      // Check if memory should be freed before allocation
      CodeCache::gc_on_allocation();
  
      // To prevent compile queue updates.
-     MutexLocker locker(THREAD, MethodCompileQueue_lock);
+     MutexLocker locker(THREAD, task()->compile_queue()->lock());
  
      // Prevent InstanceKlass::add_to_hierarchy from running
      // and invalidating our dependencies until we install this method.
      // No safepoints are allowed. Otherwise, class redefinition can occur in between.
      MutexLocker ml(Compile_lock);
      NoSafepointVerifier nsv;
  
-     // Change in Jvmti state may invalidate compilation.
-     if (!failing() && jvmti_state_changed()) {
-       record_failure("Jvmti state change invalidated dependencies");
-     }
- 
-     // Change in DTrace flags may invalidate compilation.
-     if (!failing() &&
-         ( (!dtrace_method_probes() && DTraceMethodProbes) ||
-           (!dtrace_alloc_probes() && DTraceAllocProbes) )) {
-       record_failure("DTrace flags change invalidated dependencies");
-     }
- 
-     if (!failing() && target->needs_clinit_barrier() &&
-         target->holder()->is_in_error_state()) {
-       record_failure("method holder is in error state");
-     }
- 
-     if (!failing()) {
-       if (log() != nullptr) {
-         // Log the dependencies which this compilation declares.
-         dependencies()->log_all_dependencies();
-       }
- 
-       // Encode the dependencies now, so we can check them right away.
-       dependencies()->encode_content_bytes();
- 
-       // Check for {class loads, evolution, breakpoints, ...} during compilation
-       validate_compile_task_dependencies(target);
-     }
- 
-     if (failing()) {
-       // While not a true deoptimization, it is a preemptive decompile.
-       MethodData* mdo = method()->method_data();
-       if (mdo != nullptr && _inc_decompile_count_on_failure) {
-         mdo->inc_decompile_count();
-       }
- 
-       // All buffers in the CodeBuffer are allocated in the CodeCache.
-       // If the code buffer is created on each compile attempt
-       // as in C2, then it must be freed.
-       code_buffer->free_blob();
+     if (!is_compilation_valid(THREAD, target, preload, install_code, code_buffer, scc_entry)) {
        return;
      }
  
      assert(offsets->value(CodeOffsets::Deopt) != -1, "must have deopt entry");
      assert(offsets->value(CodeOffsets::Exceptions) != -1, "must have exception entry");
  
-     nm =  nmethod::new_nmethod(method,
-                                compile_id(),
-                                entry_bci,
-                                offsets,
-                                orig_pc_offset,
-                                debug_info(), dependencies(), code_buffer,
-                                frame_words, oop_map_set,
-                                handler_table, inc_table,
-                                compiler, CompLevel(task()->comp_level()));
- 
+     if (install_code) {
+       nm =  nmethod::new_nmethod(method,
+                                  compile_id(),
+                                  entry_bci,
+                                  offsets,
+                                  orig_pc_offset,
+                                  debug_info(), dependencies(), code_buffer,
+                                  frame_words, oop_map_set,
+                                  handler_table, inc_table,
+                                  compiler, CompLevel(task()->comp_level()),
+                                  scc_entry);
+     }
      // Free codeBlobs
      code_buffer->free_blob();
  
      if (nm != nullptr) {
        nm->set_has_unsafe_access(has_unsafe_access);
        nm->set_has_wide_vectors(has_wide_vectors);
        nm->set_has_monitors(has_monitors);
        nm->set_has_scoped_access(has_scoped_access);
+       nm->set_preloaded(preload);
+       nm->set_has_clinit_barriers(has_clinit_barriers);
        assert(!method->is_synchronized() || nm->has_monitors(), "");
  
-       if (entry_bci == InvocationEntryBci) {
-         if (TieredCompilation) {
-           // If there is an old version we're done with it
-           nmethod* old = method->code();
-           if (TraceMethodReplacement && old != nullptr) {
-             ResourceMark rm;
-             char *method_name = method->name_and_sig_as_C_string();
-             tty->print_cr("Replacing method %s", method_name);
+       if (scc_entry == nullptr) {
+         scc_entry = SCCache::store_nmethod(nm, compiler, for_preload);
+         if (scc_entry != nullptr) {
+           scc_entry->set_inlined_bytecodes(num_inlined_bytecodes());
+           if (has_clinit_barriers) {
+             set_scc_clinit_barriers_entry(scc_entry); // Record it
+             return;
+           } else if (!for_preload) {
+             SCCEntry* previous_entry = scc_clinit_barriers_entry();
+             scc_entry->set_next(previous_entry); // Link it for case of deoptimization
            }
-           if (old != nullptr) {
-             old->make_not_used();
-           }
-         }
- 
-         LogTarget(Info, nmethod, install) lt;
-         if (lt.is_enabled()) {
-           ResourceMark rm;
-           char *method_name = method->name_and_sig_as_C_string();
-           lt.print("Installing method (%d) %s ",
-                     task()->comp_level(), method_name);
-         }
-         // Allow the code to be executed
-         MutexLocker ml(NMethodState_lock, Mutex::_no_safepoint_check_flag);
-         if (nm->make_in_use()) {
-           method->set_code(method, nm);
-         }
-       } else {
-         LogTarget(Info, nmethod, install) lt;
-         if (lt.is_enabled()) {
-           ResourceMark rm;
-           char *method_name = method->name_and_sig_as_C_string();
-           lt.print("Installing osr method (%d) %s @ %d",
-                     task()->comp_level(), method_name, entry_bci);
-         }
-         MutexLocker ml(NMethodState_lock, Mutex::_no_safepoint_check_flag);
-         if (nm->make_in_use()) {
-           method->method_holder()->add_osr_nmethod(nm);
          }
        }
+       make_code_usable(THREAD, target, preload, entry_bci, scc_entry, nm);
      }
    }
  
    NoSafepointVerifier nsv;
    if (nm != nullptr) {
      // Compilation succeeded, post what we know about it
      nm->post_compiled_method(task());
      task()->set_num_inlined_bytecodes(num_inlined_bytecodes());
-   } else {
+   } else if (install_code) {
      // The CodeCache is full.
      record_failure("code cache is full");
+   } else {
+     task()->set_num_inlined_bytecodes(num_inlined_bytecodes());
    }
  
    // safepoints are allowed again
  }
  

@@ -1157,10 +1311,17 @@
  
  // ------------------------------------------------------------------
  // ciEnv::notice_inlined_method()
  void ciEnv::notice_inlined_method(ciMethod* method) {
    _num_inlined_bytecodes += method->code_size_for_inlining();
+   CompileTrainingData* td = task()->training_data();
+   if (td != nullptr) {
+     GUARDED_VM_ENTRY({
+       methodHandle mh(Thread::current(), method->get_Method());
+       td->notice_inlined_method(task(), mh);
+     });
+   }
  }
  
  // ------------------------------------------------------------------
  // ciEnv::num_inlined_bytecodes()
  int ciEnv::num_inlined_bytecodes() const {

@@ -1680,5 +1841,77 @@
  }
  
  void ciEnv::dump_replay_data_version(outputStream* out) {
    out->print_cr("version %d", REPLAY_VERSION);
  }
+ 
+ bool ciEnv::is_precompiled() {
+   return (task() != nullptr) && (task()->compile_reason() == CompileTask::Reason_Precompile          ||
+                                  task()->compile_reason() == CompileTask::Reason_PrecompileForPreload);
+ }
+ 
+ bool ciEnv::is_fully_initialized(InstanceKlass* ik) {
+   assert(is_precompiled(), "");
+   if (task()->method()->method_holder() == ik) {
+     return true; // FIXME: may be too strong; being_initialized, at least
+   }
+   switch (task()->compile_reason()) {
+     case CompileTask::Reason_Precompile: {
+       // check init dependencies
+       MethodTrainingData* mtd = nullptr;
+       GUARDED_VM_ENTRY(mtd = MethodTrainingData::find(methodHandle(Thread::current(), task()->method())); )
+       if (mtd != nullptr) {
+         CompileTrainingData* ctd = mtd->last_toplevel_compile(task()->comp_level());
+         if (ctd != nullptr) {
+           for (int i = 0; i < ctd->init_dep_count(); i++) {
+             KlassTrainingData* ktd = ctd->init_dep(i);
+             if (ktd->has_holder() && (ktd->holder() == ik)) {
+               log_trace(precompile)("%d: init_dependency: %s: %s", task()->compile_id(), InstanceKlass::state2name(ik->init_state()), ik->external_name());
+               return true; // init dependency present
+             }
+           }
+         }
+       }
+       return false; // no init dependency
+     }
+     case CompileTask::Reason_PrecompileForPreload: {
+       // FIXME: assumes that all shared classes are initialized
+       if (ik->is_shared()) {
+         return true; // class init barriers
+       }
+       if (CDSConfig::is_dumping_final_static_archive() && ArchiveBuilder::is_active() &&
+           ArchiveBuilder::current()->has_been_archived((address)ik)) {
+         return true; // class init barriers
+       }
+       return false;
+     }
+     default: fatal("%s", CompileTask::reason_name(task()->compile_reason()));
+   }
+   return false;
+ }
+ 
+ InstanceKlass::ClassState ciEnv::compute_init_state_for_precompiled(InstanceKlass* ik) {
+   ASSERT_IN_VM;
+   assert(is_precompiled(), "");
+   ResourceMark rm;
+   if (is_fully_initialized(ik)) {
+     log_trace(precompile)("%d: fully_initialized: %s", task()->compile_id(), ik->external_name());
+     return InstanceKlass::ClassState::fully_initialized;
+   } else if (MetaspaceObj::is_shared(ik)) {
+     guarantee(ik->is_loaded(), ""); // FIXME: assumes pre-loading by CDS; ik->is_linked() requires pre-linking
+     log_trace(precompile)("%d: %s: %s", task()->compile_id(), InstanceKlass::state2name(ik->init_state()), ik->external_name());
+     return ik->init_state(); // not yet initialized
+   } else if (CDSConfig::is_dumping_final_static_archive() && ArchiveBuilder::is_active()) {
+     if (!ArchiveBuilder::current()->has_been_archived((address)ik)) {
+       fatal("New workflow: should not compile code for unarchived class: %s", ik->external_name());
+     }
+     guarantee(ik->is_loaded(), "");
+     log_trace(precompile)("%d: %s: %s", task()->compile_id(), InstanceKlass::state2name(ik->init_state()), ik->external_name());
+     return ik->init_state(); // not yet initialized
+   } else {
+     // Not present in the archive.
+     fatal("unloaded: %s", ik->external_name());
+ //    guarantee(SystemDictionaryShared::lookup_init_state(ik) == ik->init_state(), "");
+     log_trace(precompile)("%d: allocated: %s", task()->compile_id(), ik->external_name());
+     return InstanceKlass::ClassState::allocated; // not yet linked
+   }
+ }
< prev index next >