Date: Fri, 9 Jun 2023 14:30:14 +0800
Subject: 8181644: C1 crashes with -XX:+PrintCFGToFile

Bug url: https://bugs.openjdk.org/browse/JDK-8181644
---
 hotspot/src/share/vm/c1/c1_CFGPrinter.cpp  | 83 +++++-----------------
 hotspot/src/share/vm/c1/c1_CFGPrinter.hpp  | 45 ++++++++++--
 hotspot/src/share/vm/c1/c1_Compilation.cpp |  6 ++
 hotspot/src/share/vm/c1/c1_Compilation.hpp |  6 ++
 4 files changed, 71 insertions(+), 69 deletions(-)

diff --git a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
index c5b35d00c..63997caf4 100644
--- a/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
+++ b/hotspot/src/share/vm/c1/c1_CFGPrinter.cpp
@@ -32,86 +32,41 @@
 
 #ifndef PRODUCT
 
-
-class CFGPrinterOutput : public CHeapObj<mtCompiler> {
- private:
-  outputStream* _output;
-
-  Compilation*  _compilation;
-  bool _do_print_HIR;
-  bool _do_print_LIR;
-
-  class PrintBlockClosure: public BlockClosure {
-    void block_do(BlockBegin* block) { if (block != NULL) CFGPrinter::output()->print_block(block); }
-  };
-
-
-  outputStream* output() { assert(_output != NULL, ""); return _output; }
-
-  void inc_indent();
-  void dec_indent();
-  void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
-  void print_begin(const char* tag);
-  void print_end(const char* tag);
-
-  char* method_name(ciMethod* method, bool short_name = false);
-
- public:
-  CFGPrinterOutput();
-
-  void set_compilation(Compilation* compilation) { _compilation = compilation; }
-  void set_print_flags(bool do_print_HIR, bool do_print_LIR) { _do_print_HIR = do_print_HIR; _do_print_LIR = do_print_LIR; }
-
-  void print_compilation();
-  void print_intervals(IntervalList* intervals, const char* name);
-
-  void print_state(BlockBegin* block);
-  void print_operand(Value instr);
-  void print_HIR(Value instr);
-  void print_HIR(BlockBegin* block);
-  void print_LIR(BlockBegin* block);
-  void print_block(BlockBegin* block);
-  void print_cfg(BlockList* blocks, const char* name);
-  void print_cfg(IR* blocks, const char* name);
-};
-
-CFGPrinterOutput* CFGPrinter::_output = NULL;
-
-
-
-
 void CFGPrinter::print_compilation(Compilation* compilation) {
-  if (_output == NULL) {
-    _output = new CFGPrinterOutput();
-  }
-  output()->set_compilation(compilation);
-  output()->print_compilation();
+  CFGPrinterOutput* output = compilation->cfg_printer_output();
+  output->print_compilation();
 }
 
 void CFGPrinter::print_cfg(BlockList* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
-  output()->set_print_flags(do_print_HIR, do_print_LIR);
-  output()->print_cfg(blocks, name);
+  CFGPrinterOutput* output = Compilation::current()->cfg_printer_output();
+  output->set_print_flags(do_print_HIR, do_print_LIR);
+  output->print_cfg(blocks, name);
 }
 
 void CFGPrinter::print_cfg(IR* blocks, const char* name, bool do_print_HIR, bool do_print_LIR) {
-  output()->set_print_flags(do_print_HIR, do_print_LIR);
-  output()->print_cfg(blocks, name);
+  CFGPrinterOutput* output = Compilation::current()->cfg_printer_output();
+  output->set_print_flags(do_print_HIR, do_print_LIR);
+  output->print_cfg(blocks, name);
 }
 
-
 void CFGPrinter::print_intervals(IntervalList* intervals, const char* name) {
-  output()->print_intervals(intervals, name);
+  CFGPrinterOutput* output = Compilation::current()->cfg_printer_output();
+  output->print_intervals(intervals, name);
 }
 
-
-
-CFGPrinterOutput::CFGPrinterOutput()
- : _output(new(ResourceObj::C_HEAP, mtCompiler) fileStream("output.cfg"))
+CFGPrinterOutput::CFGPrinterOutput(Compilation* compilation)
+ : _output(NULL),
+   _compilation(compilation),
+   _do_print_HIR(false),
+   _do_print_LIR(false)
 {
+  char file_name[O_BUFLEN];
+  jio_snprintf(file_name, sizeof(file_name), "output_tid" UINTX_FORMAT "_pid%u.cfg",
+               os::current_thread_id(), os::current_process_id());
+  _output = new(ResourceObj::C_HEAP, mtCompiler) fileStream(file_name, "at");
 }
 
 
-
 void CFGPrinterOutput::inc_indent() {
   output()->inc();
   output()->inc();
diff --git a/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp b/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp
index 1cdde1186..60d18814d 100644
--- a/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp
+++ b/hotspot/src/share/vm/c1/c1_CFGPrinter.hpp
@@ -37,18 +37,53 @@ class CFGPrinterOutput;
 class IntervalList;
 
 class CFGPrinter : public AllStatic {
-private:
-  static CFGPrinterOutput* _output;
 public:
-  static CFGPrinterOutput* output() { assert(_output != NULL, ""); return _output; }
-
-
   static void print_compilation(Compilation* compilation);
   static void print_cfg(BlockList* blocks, const char* name, bool do_print_HIR, bool do_print_LIR);
   static void print_cfg(IR* blocks, const char* name, bool do_print_HIR, bool do_print_LIR);
   static void print_intervals(IntervalList* intervals, const char* name);
 };
 
+class CFGPrinterOutput : public CHeapObj<mtCompiler> {
+ private:
+  outputStream* _output;
+
+  Compilation*  _compilation;
+  bool _do_print_HIR;
+  bool _do_print_LIR;
+
+  class PrintBlockClosure: public BlockClosure {
+    void block_do(BlockBegin* block) { if (block != NULL) Compilation::current()->cfg_printer_output()->print_block(block); }
+  };
+
+  outputStream* output() { assert(_output != NULL, ""); return _output; }
+
+  void inc_indent();
+  void dec_indent();
+  void print(const char* format, ...) ATTRIBUTE_PRINTF(2, 3);
+  void print_begin(const char* tag);
+  void print_end(const char* tag);
+
+  char* method_name(ciMethod* method, bool short_name = false);
+
+ public:
+  CFGPrinterOutput(Compilation* compilation);
+
+  void set_print_flags(bool do_print_HIR, bool do_print_LIR) { _do_print_HIR = do_print_HIR; _do_print_LIR = do_print_LIR; }
+
+  void print_compilation();
+  void print_intervals(IntervalList* intervals, const char* name);
+
+  void print_state(BlockBegin* block);
+  void print_operand(Value instr);
+  void print_HIR(Value instr);
+  void print_HIR(BlockBegin* block);
+  void print_LIR(BlockBegin* block);
+  void print_block(BlockBegin* block);
+  void print_cfg(BlockList* blocks, const char* name);
+  void print_cfg(IR* blocks, const char* name);
+};
+
 #endif
 
 #endif // SHARE_VM_C1_C1_CFGPRINTER_HPP
diff --git a/hotspot/src/share/vm/c1/c1_Compilation.cpp b/hotspot/src/share/vm/c1/c1_Compilation.cpp
index 6a0b709f1..82e67fc02 100644
--- a/hotspot/src/share/vm/c1/c1_Compilation.cpp
+++ b/hotspot/src/share/vm/c1/c1_Compilation.cpp
@@ -549,6 +549,7 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
 , _interpreter_frame_size(0)
 #ifndef PRODUCT
 , _last_instruction_printed(NULL)
+, _cfg_printer_output(NULL)
 #endif // PRODUCT
 {
   PhaseTraceTime timeit(_t_compile);
@@ -556,6 +557,11 @@ Compilation::Compilation(AbstractCompiler* compiler, ciEnv* env, ciMethod* metho
   _env->set_compiler_data(this);
   _exception_info_list = new ExceptionInfoList();
   _implicit_exception_table.set_size(0);
+#ifndef PRODUCT
+  if (PrintCFGToFile) {
+    _cfg_printer_output = new CFGPrinterOutput(this);
+  }
+#endif
   compile_method();
   if (bailed_out()) {
     _env->record_method_not_compilable(bailout_msg(), !TieredCompilation);
diff --git a/hotspot/src/share/vm/c1/c1_Compilation.hpp b/hotspot/src/share/vm/c1/c1_Compilation.hpp
index 8ff7f3e50..aa7bd18b5 100644
--- a/hotspot/src/share/vm/c1/c1_Compilation.hpp
+++ b/hotspot/src/share/vm/c1/c1_Compilation.hpp
@@ -50,6 +50,7 @@ class ValueStack;
 class LIR_OprDesc;
 class C1_MacroAssembler;
 class CFGPrinter;
+class CFGPrinterOutput;
 typedef LIR_OprDesc* LIR_Opr;
 
 
@@ -113,6 +114,7 @@ class Compilation: public StackObj {
   Instruction*       _current_instruction;       // the instruction currently being processed
 #ifndef PRODUCT
   Instruction*       _last_instruction_printed;  // the last instruction printed during traversal
+  CFGPrinterOutput*  _cfg_printer_output;
 #endif // PRODUCT
 
  public:
@@ -182,6 +184,10 @@ class Compilation: public StackObj {
 
 #ifndef PRODUCT
   void maybe_print_current_instruction();
+  CFGPrinterOutput* cfg_printer_output() {
+    guarantee(_cfg_printer_output != NULL, "CFG printer output not initialized");
+    return _cfg_printer_output;
+  }
 #endif // PRODUCT
 
   // error handling
-- 
2.22.0

