diff options
author | 2016-11-10 15:19:15 +0000 | |
---|---|---|
committer | 2016-11-10 16:55:22 +0000 | |
commit | 00c141aaa07b95a8c2c492b617871abd3cf7162a (patch) | |
tree | e4777db1006e6ac42a0669bf5383b61235835dce /compiler/optimizing/optimizing_compiler.cc | |
parent | ee59d46595bb860fea26122f47f8797d2d0fe5f4 (diff) |
Dump c1visualizer output before and after each pass.
In order to get the last state of a graph before a crash.
Test: dex2oat --dump-cfg
Change-Id: I461a26a47a170b95fadb9da21a443af26fe52181
Diffstat (limited to 'compiler/optimizing/optimizing_compiler.cc')
-rw-r--r-- | compiler/optimizing/optimizing_compiler.cc | 31 |
1 files changed, 15 insertions, 16 deletions
diff --git a/compiler/optimizing/optimizing_compiler.cc b/compiler/optimizing/optimizing_compiler.cc index 6f84cdcc4f..7a930cce71 100644 --- a/compiler/optimizing/optimizing_compiler.cc +++ b/compiler/optimizing/optimizing_compiler.cc @@ -167,24 +167,13 @@ class PassObserver : public ValueObject { LOG(INFO) << "TIMINGS " << GetMethodName(); LOG(INFO) << Dumpable<TimingLogger>(timing_logger_); } - if (visualizer_enabled_) { - MutexLock mu(Thread::Current(), visualizer_dump_mutex_); - *visualizer_output_ << visualizer_oss_.str(); - // The destructor of `visualizer_output_` is normally - // responsible for flushing (and closing) the stream, but it - // won't be invoked during fast exits in non-debug mode -- see - // art::Dex2Oat::~Dex2Oat, which explicitly abandons some - // objects (such as the compiler driver) in non-debug mode, to - // avoid the cost of destructing them. Therefore we explicitly - // flush the stream here to prevent truncated CFG visualizer - // files. - visualizer_output_->flush(); - } + DCHECK(visualizer_oss_.str().empty()); } - void DumpDisassembly() const { + void DumpDisassembly() REQUIRES(!visualizer_dump_mutex_) { if (visualizer_enabled_) { visualizer_.DumpGraphWithDisassembly(); + FlushVisualizer(); } } @@ -199,24 +188,34 @@ class PassObserver : public ValueObject { } private: - void StartPass(const char* pass_name) { + void StartPass(const char* pass_name) REQUIRES(!visualizer_dump_mutex_) { VLOG(compiler) << "Starting pass: " << pass_name; // Dump graph first, then start timer. if (visualizer_enabled_) { visualizer_.DumpGraph(pass_name, /* is_after_pass */ false, graph_in_bad_state_); + FlushVisualizer(); } if (timing_logger_enabled_) { timing_logger_.StartTiming(pass_name); } } - void EndPass(const char* pass_name) { + void FlushVisualizer() REQUIRES(!visualizer_dump_mutex_) { + MutexLock mu(Thread::Current(), visualizer_dump_mutex_); + *visualizer_output_ << visualizer_oss_.str(); + visualizer_output_->flush(); + visualizer_oss_.str(""); + visualizer_oss_.clear(); + } + + void EndPass(const char* pass_name) REQUIRES(!visualizer_dump_mutex_) { // Pause timer first, then dump graph. if (timing_logger_enabled_) { timing_logger_.EndTiming(); } if (visualizer_enabled_) { visualizer_.DumpGraph(pass_name, /* is_after_pass */ true, graph_in_bad_state_); + FlushVisualizer(); } // Validate the HGraph if running in debug mode. |