diff --git a/src/hotspot/share/nmt/memReporter.cpp b/src/hotspot/share/nmt/memReporter.cpp index e5969bbaf8f..bd2f38acdd0 100644 --- a/src/hotspot/share/nmt/memReporter.cpp +++ b/src/hotspot/share/nmt/memReporter.cpp @@ -51,13 +51,7 @@ static ssize_t counter_diff(size_t c1, size_t c2) { } MemReporterBase::MemReporterBase(outputStream* out, size_t scale) : - _scale(scale), _output(out) { - _output->set_autoindent(true); -} - -MemReporterBase::~MemReporterBase() { - _output->set_autoindent(false); -} + _scale(scale), _output(out), _auto_indentor(out) {} size_t MemReporterBase::reserved_total(const MallocMemory* malloc, const VirtualMemory* vm) { return malloc->malloc_size() + malloc->arena_size() + vm->reserved(); diff --git a/src/hotspot/share/nmt/memReporter.hpp b/src/hotspot/share/nmt/memReporter.hpp index 3f08ecbd284..c10a9979508 100644 --- a/src/hotspot/share/nmt/memReporter.hpp +++ b/src/hotspot/share/nmt/memReporter.hpp @@ -38,6 +38,7 @@ class MemReporterBase : public StackObj { private: const size_t _scale; // report in this scale outputStream* const _output; // destination + StreamAutoIndentor _auto_indentor; public: @@ -45,7 +46,6 @@ class MemReporterBase : public StackObj { static const size_t default_scale = K; MemReporterBase(outputStream* out, size_t scale = default_scale); - ~MemReporterBase(); // Helper functions // Calculate total reserved and committed amount diff --git a/src/hotspot/share/utilities/ostream.cpp b/src/hotspot/share/utilities/ostream.cpp index 6057d1a7710..5d6731785a3 100644 --- a/src/hotspot/share/utilities/ostream.cpp +++ b/src/hotspot/share/utilities/ostream.cpp @@ -277,6 +277,12 @@ outputStream& outputStream::indent() { return *this; } +bool outputStream::set_autoindent(bool value) { + const bool old = _autoindent; + _autoindent = value; + return old; +} + void outputStream::print_jlong(jlong value) { print(JLONG_FORMAT, value); } diff --git a/src/hotspot/share/utilities/ostream.hpp b/src/hotspot/share/utilities/ostream.hpp index b4ce7c32c60..bff682a3e5a 100644 --- a/src/hotspot/share/utilities/ostream.hpp +++ b/src/hotspot/share/utilities/ostream.hpp @@ -109,7 +109,8 @@ class outputStream : public CHeapObjBase { // line starts depending on the current indentation level: // print(), print_cr(), print_raw(), print_raw_cr() // Other APIs are unaffected - void set_autoindent(bool value) { _autoindent = value; } + // Returns old autoindent state. + bool set_autoindent(bool value); // sizing int position() const { return _position; } @@ -175,17 +176,26 @@ class outputStream : public CHeapObjBase { extern outputStream* tty; // tty output class streamIndentor : public StackObj { - private: - outputStream* _str; - int _amount; - - public: + outputStream* const _str; + const int _amount; + NONCOPYABLE(streamIndentor); +public: streamIndentor(outputStream* str, int amt = 2) : _str(str), _amount(amt) { _str->inc(_amount); } ~streamIndentor() { _str->dec(_amount); } }; +class StreamAutoIndentor : public StackObj { + outputStream* const _os; + const bool _old; + NONCOPYABLE(StreamAutoIndentor); + public: + StreamAutoIndentor(outputStream* os) : + _os(os), _old(os->set_autoindent(true)) {} + ~StreamAutoIndentor() { _os->set_autoindent(_old); } +}; + // advisory locking for the shared tty stream: class ttyLocker: StackObj { friend class ttyUnlocker; diff --git a/test/hotspot/gtest/utilities/test_ostream.cpp b/test/hotspot/gtest/utilities/test_ostream.cpp index 26fd9d227c1..5d25c51f3f9 100644 --- a/test/hotspot/gtest/utilities/test_ostream.cpp +++ b/test/hotspot/gtest/utilities/test_ostream.cpp @@ -106,7 +106,8 @@ TEST_VM(ostream, bufferedStream_dynamic_small) { static void test_autoindent(bool on) { stringStream ss; - ss.set_autoindent(on); + const bool prior = ss.set_autoindent(on); + EXPECT_FALSE(prior); { streamIndentor si(&ss, 5); ss.print("ABC"); @@ -146,6 +147,8 @@ static void test_autoindent(bool on) { "end" ); } + bool prior2 = ss.set_autoindent(prior); + EXPECT_EQ(prior2, on); } TEST_VM(ostream, autoindent_on) { test_autoindent(true); }