diff options
| -rw-r--r-- | runtime/verifier/method_verifier.cc | 15 | ||||
| -rw-r--r-- | runtime/verifier/method_verifier.h | 3 | ||||
| -rw-r--r-- | runtime/verifier/scoped_newline.h | 64 |
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_ |