summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/verifier/method_verifier.cc15
-rw-r--r--runtime/verifier/method_verifier.h3
-rw-r--r--runtime/verifier/scoped_newline.h64
3 files changed, 75 insertions, 7 deletions
diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc
index b6497b4a31..fae3af31d5 100644
--- a/runtime/verifier/method_verifier.cc
+++ b/runtime/verifier/method_verifier.cc
@@ -57,6 +57,7 @@
#include "reg_type-inl.h"
#include "register_line-inl.h"
#include "runtime.h"
+#include "scoped_newline.h"
#include "scoped_thread_state_change-inl.h"
#include "stack.h"
#include "vdex_file.h"
@@ -690,9 +691,11 @@ std::ostream& MethodVerifier::Fail(VerifyError error) {
return *failure_message;
}
-std::ostream& MethodVerifier::LogVerifyInfo() {
- return info_messages_ << "VFY: " << dex_file_->PrettyMethod(dex_method_idx_)
- << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : ";
+ScopedNewLine MethodVerifier::LogVerifyInfo() {
+ ScopedNewLine ret{info_messages_};
+ ret << "VFY: " << dex_file_->PrettyMethod(dex_method_idx_)
+ << '[' << reinterpret_cast<void*>(work_insn_idx_) << "] : ";
+ return ret;
}
void MethodVerifier::PrependToLastFailMessage(std::string prepend) {
@@ -1814,8 +1817,8 @@ bool MethodVerifier::CodeFlowVerifyInstruction(uint32_t* start_guess) {
bool just_set_result = false;
if (UNLIKELY(VLOG_IS_ON(verifier_debug))) {
// Generate processing back trace to debug verifier
- LogVerifyInfo() << "Processing " << inst->DumpString(dex_file_) << "\n"
- << work_line_->Dump(this) << "\n";
+ LogVerifyInfo() << "Processing " << inst->DumpString(dex_file_) << std::endl
+ << work_line_->Dump(this);
}
/*
@@ -4751,7 +4754,7 @@ bool MethodVerifier::UpdateRegisters(uint32_t next_insn, RegisterLine* merge_lin
<< " to [" << reinterpret_cast<void*>(next_insn) << "]: " << "\n"
<< copy->Dump(this) << " MERGE\n"
<< merge_line->Dump(this) << " ==\n"
- << target_line->Dump(this) << "\n";
+ << target_line->Dump(this);
}
if (update_merge_line && changed) {
merge_line->CopyFromLine(target_line);
diff --git a/runtime/verifier/method_verifier.h b/runtime/verifier/method_verifier.h
index 92abe9bd5d..06482c4b9a 100644
--- a/runtime/verifier/method_verifier.h
+++ b/runtime/verifier/method_verifier.h
@@ -59,6 +59,7 @@ class MethodVerifier;
class RegisterLine;
using RegisterLineArenaUniquePtr = std::unique_ptr<RegisterLine, RegisterLineArenaDelete>;
class RegType;
+struct ScopedNewLine;
// We don't need to store the register data for many instructions, because we either only need
// it at branch points (for verification) or GC points and branches (for verification +
@@ -126,7 +127,7 @@ class MethodVerifier {
std::ostream& Fail(VerifyError error);
// Log for verification information.
- std::ostream& LogVerifyInfo();
+ ScopedNewLine LogVerifyInfo();
// Dump the failures encountered by the verifier.
std::ostream& DumpFailures(std::ostream& os);
diff --git a/runtime/verifier/scoped_newline.h b/runtime/verifier/scoped_newline.h
new file mode 100644
index 0000000000..eb81bfacda
--- /dev/null
+++ b/runtime/verifier/scoped_newline.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_RUNTIME_VERIFIER_SCOPED_NEWLINE_H_
+#define ART_RUNTIME_VERIFIER_SCOPED_NEWLINE_H_
+
+#include <ostream>
+
+#include <android-base/logging.h>
+
+namespace art {
+namespace verifier {
+
+// RAII to inject a newline after a message.
+struct ScopedNewLine {
+ explicit ScopedNewLine(std::ostream& os) : stream(os) {}
+
+ ScopedNewLine(ScopedNewLine&& other) : stream(other.stream), active(other.active) {
+ other.active = false;
+ }
+
+ ScopedNewLine(ScopedNewLine&) = delete;
+ ScopedNewLine& operator=(ScopedNewLine&) = delete;
+
+ ~ScopedNewLine() {
+ if (active) {
+ stream << std::endl;
+ }
+ }
+
+ template <class T>
+ ScopedNewLine& operator<<(const T& t) {
+ DCHECK(active);
+ stream << t;
+ return *this;
+ }
+
+ ScopedNewLine& operator<<(std::ostream& (*f)(std::ostream&)) {
+ DCHECK(active);
+ stream << f;
+ return *this;
+ }
+
+ std::ostream& stream;
+ bool active = true;
+};
+
+} // namespace verifier
+} // namespace art
+
+#endif // ART_RUNTIME_VERIFIER_SCOPED_NEWLINE_H_