< prev index next >

src/hotspot/share/opto/c2compiler.cpp

Print this page
*** 22,10 ***
--- 22,11 ---
   *
   */
  
  #include "precompiled.hpp"
  #include "classfile/vmClasses.hpp"
+ #include "code/SCCache.hpp"
  #include "compiler/compilationMemoryStatistic.hpp"
  #include "compiler/compilerDefinitions.inline.hpp"
  #include "runtime/handles.inline.hpp"
  #include "jfr/support/jfrIntrinsics.hpp"
  #include "opto/c2compiler.hpp"

*** 59,10 ***
--- 60,14 ---
  }
  const char* C2Compiler::retry_no_superword() {
    return "retry without SuperWord";
  }
  
+ const char* C2Compiler::retry_no_clinit_barriers() {
+   return "retry without class initialization barriers";
+ }
+ 
  void compiler_stubs_init(bool in_compiler_thread);
  
  bool C2Compiler::init_c2_runtime() {
  
  #ifdef ASSERT

*** 94,11 ***
    Compile::pd_compiler2_init();
  
    CompilerThread* thread = CompilerThread::current();
  
    HandleMark handle_mark(thread);
!   return OptoRuntime::generate(thread->env());
  }
  
  void C2Compiler::initialize() {
    assert(!CompilerConfig::is_c1_or_interpreter_only_no_jvmci(), "C2 compiler is launched, it's not c1/interpreter only mode");
    // The first compiler thread that gets here will initialize the
--- 99,15 ---
    Compile::pd_compiler2_init();
  
    CompilerThread* thread = CompilerThread::current();
  
    HandleMark handle_mark(thread);
!   bool success = OptoRuntime::generate(thread->env());
+   if (success) {
+     SCCache::init_opto_table();
+   }
+   return success;
  }
  
  void C2Compiler::initialize() {
    assert(!CompilerConfig::is_c1_or_interpreter_only_no_jvmci(), "C2 compiler is launched, it's not c1/interpreter only mode");
    // The first compiler thread that gets here will initialize the

*** 115,31 ***
    }
  }
  
  void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci, bool install_code, DirectiveSet* directive) {
    assert(is_initialized(), "Compiler thread must be initialized");
- 
    CompilationMemoryStatisticMark cmsm(directive);
  
    bool subsume_loads = SubsumeLoads;
    bool do_escape_analysis = DoEscapeAnalysis;
    bool do_iterative_escape_analysis = DoEscapeAnalysis;
    bool do_reduce_allocation_merges = ReduceAllocationMerges && EliminateAllocations;
    bool eliminate_boxing = EliminateAutoBox;
    bool do_locks_coarsening = EliminateLocks;
    bool do_superword = UseSuperWord;
! 
    while (!env->failing()) {
      ResourceMark rm;
      // Attempt to compile while subsuming loads into machine instructions.
      Options options(subsume_loads,
                      do_escape_analysis,
                      do_iterative_escape_analysis,
                      do_reduce_allocation_merges,
                      eliminate_boxing,
                      do_locks_coarsening,
                      do_superword,
                      install_code);
      Compile C(env, target, entry_bci, options, directive);
  
      // Check result and retry if appropriate.
      if (C.failure_reason() != nullptr) {
--- 124,52 ---
    }
  }
  
  void C2Compiler::compile_method(ciEnv* env, ciMethod* target, int entry_bci, bool install_code, DirectiveSet* directive) {
    assert(is_initialized(), "Compiler thread must be initialized");
    CompilationMemoryStatisticMark cmsm(directive);
+   CompileTask* task = env->task();
+   if (install_code && task->is_scc()) {
+     bool success = SCCache::load_nmethod(env, target, entry_bci, this, CompLevel_full_optimization);
+     if (success) {
+       assert(task->is_success(), "sanity");
+       return;
+     }
+     if (!task->preload()) { // Do not mark entry if pre-loading failed - it can pass normal load
+       SCCache::invalidate(task->scc_entry()); // mark sca_entry as not entrant
+     }
+     if (SCCache::is_code_load_thread_on()) {
+       env->record_failure("Failed to load cached code");
+       // Bail out if failed to load cached code in SC thread
+       return;
+     }
+     task->clear_scc();
+   }
  
    bool subsume_loads = SubsumeLoads;
    bool do_escape_analysis = DoEscapeAnalysis;
    bool do_iterative_escape_analysis = DoEscapeAnalysis;
    bool do_reduce_allocation_merges = ReduceAllocationMerges && EliminateAllocations;
    bool eliminate_boxing = EliminateAutoBox;
    bool do_locks_coarsening = EliminateLocks;
    bool do_superword = UseSuperWord;
!   bool for_preload = (task->compile_reason() != CompileTask::Reason_Precompile) && // non-preload version is requested
+                      SCCache::gen_preload_code(target, entry_bci);
+   if (task->compile_reason() == CompileTask::Reason_PrecompileForPreload) {
+     assert(for_preload, "required");
+   }
    while (!env->failing()) {
      ResourceMark rm;
      // Attempt to compile while subsuming loads into machine instructions.
      Options options(subsume_loads,
                      do_escape_analysis,
                      do_iterative_escape_analysis,
                      do_reduce_allocation_merges,
                      eliminate_boxing,
                      do_locks_coarsening,
                      do_superword,
+                     for_preload,
                      install_code);
      Compile C(env, target, entry_bci, options, directive);
  
      // Check result and retry if appropriate.
      if (C.failure_reason() != nullptr) {

*** 171,10 ***
--- 201,15 ---
          assert(do_locks_coarsening, "must make progress");
          do_locks_coarsening = false;
          env->report_failure(C.failure_reason());
          continue;  // retry
        }
+       if (C.failure_reason_is(retry_no_clinit_barriers())) {
+         assert(for_preload, "must make progress");
+         for_preload = false;
+         continue;
+       }
        if (C.failure_reason_is(retry_no_superword())) {
          assert(do_superword, "must make progress");
          do_superword = false;
          env->report_failure(C.failure_reason());
          continue;  // retry
< prev index next >