summaryrefslogtreecommitdiff
path: root/compiler/optimizing/optimizing_compiler.cc
diff options
context:
space:
mode:
author Nicolas Geoffray <ngeoffray@google.com> 2016-11-10 15:19:15 +0000
committer Nicolas Geoffray <ngeoffray@google.com> 2016-11-10 16:55:22 +0000
commit00c141aaa07b95a8c2c492b617871abd3cf7162a (patch)
treee4777db1006e6ac42a0669bf5383b61235835dce /compiler/optimizing/optimizing_compiler.cc
parentee59d46595bb860fea26122f47f8797d2d0fe5f4 (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.cc31
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.