Commit 3f303482 authored by Clemens Hammacher's avatar Clemens Hammacher Committed by Commit Bot

[Liftoff] Add printing for registers and cache state

This prints nicer error messages for checks like
"DCHECK_EQ(reg1, reg2)", and also splits cache state tracing into
one method for printing the overall state, one for printing each slot,
and one for printing the register.

R=titzer@chromium.org

Bug: v8:6600
Change-Id: I36e83ba2542986dd8ad17dbfe7cbb8df54a56755
Reviewed-on: https://chromium-review.googlesource.com/853495
Commit-Queue: Clemens Hammacher <clemensh@chromium.org>
Reviewed-by: 's avatarBen Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50407}
parent 501413b9
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#define V8_ASSEMBLER_H_ #define V8_ASSEMBLER_H_
#include <forward_list> #include <forward_list>
#include <iosfwd>
#include "src/allocation.h" #include "src/allocation.h"
#include "src/builtins/builtins.h" #include "src/builtins/builtins.h"
...@@ -1338,6 +1339,12 @@ class RegisterBase { ...@@ -1338,6 +1339,12 @@ class RegisterBase {
int reg_code_; int reg_code_;
}; };
template <typename SubType, int kAfterLastRegister>
inline std::ostream& operator<<(std::ostream& os,
RegisterBase<SubType, kAfterLastRegister> reg) {
return reg.is_valid() ? os << "r" << reg.code() : os << "<invalid reg>";
}
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
#endif // V8_ASSEMBLER_H_ #endif // V8_ASSEMBLER_H_
...@@ -391,6 +391,19 @@ uint32_t LiftoffAssembler::GetTotalFrameSlotCount() const { ...@@ -391,6 +391,19 @@ uint32_t LiftoffAssembler::GetTotalFrameSlotCount() const {
return num_locals() + kMaxValueStackHeight; return num_locals() + kMaxValueStackHeight;
} }
std::ostream& operator<<(std::ostream& os, VarState slot) {
os << WasmOpcodes::TypeName(slot.type()) << ":";
switch (slot.loc()) {
case VarState::kStack:
return os << "s";
case VarState::kRegister:
return os << slot.reg();
case VarState::kConstant:
return os << "c" << slot.i32_const();
}
UNREACHABLE();
}
#undef __ #undef __
#undef TRACE #undef TRACE
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_H_ #ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_H_ #define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_H_
#include <iosfwd>
#include <memory> #include <memory>
// Clients of this interface shouldn't depend on lots of compiler internals. // Clients of this interface shouldn't depend on lots of compiler internals.
...@@ -338,6 +339,8 @@ class LiftoffAssembler : public TurboAssembler { ...@@ -338,6 +339,8 @@ class LiftoffAssembler : public TurboAssembler {
LiftoffRegister SpillOneRegister(RegClass rc, LiftoffRegList pinned); LiftoffRegister SpillOneRegister(RegClass rc, LiftoffRegList pinned);
}; };
std::ostream& operator<<(std::ostream& os, LiftoffAssembler::VarState);
} // namespace wasm } // namespace wasm
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
......
...@@ -771,35 +771,21 @@ class LiftoffCompiler { ...@@ -771,35 +771,21 @@ class LiftoffCompiler {
void TraceCacheState(Decoder* decoder) const { void TraceCacheState(Decoder* decoder) const {
#ifdef DEBUG #ifdef DEBUG
if (!FLAG_trace_liftoff) return; if (!FLAG_trace_liftoff) return;
OFStream os(stdout);
for (int control_depth = decoder->control_depth() - 1; control_depth >= -1; for (int control_depth = decoder->control_depth() - 1; control_depth >= -1;
--control_depth) { --control_depth) {
LiftoffAssembler::CacheState* cache_state = LiftoffAssembler::CacheState* cache_state =
control_depth == -1 control_depth == -1
? asm_->cache_state() ? asm_->cache_state()
: &decoder->control_at(control_depth)->label_state; : &decoder->control_at(control_depth)->label_state;
int idx = 0; bool first = true;
for (LiftoffAssembler::VarState& slot : cache_state->stack_state) { for (LiftoffAssembler::VarState& slot : cache_state->stack_state) {
if (idx++) PrintF("-"); os << (first ? "" : "-") << slot;
PrintF("%s:", WasmOpcodes::TypeName(slot.type())); first = false;
switch (slot.loc()) {
case kStack:
PrintF("s");
break;
case kRegister:
if (slot.reg().is_gp()) {
PrintF("gp%d", slot.reg().gp().code());
} else {
PrintF("fp%d", slot.reg().fp().code());
}
break;
case kConstant:
PrintF("c");
break;
}
} }
if (control_depth != -1) PrintF("; "); if (control_depth != -1) PrintF("; ");
} }
PrintF("\n"); os << "\n";
#endif #endif
} }
}; };
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#ifndef V8_WASM_BASELINE_LIFTOFF_REGISTER_H_ #ifndef V8_WASM_BASELINE_LIFTOFF_REGISTER_H_
#define V8_WASM_BASELINE_LIFTOFF_REGISTER_H_ #define V8_WASM_BASELINE_LIFTOFF_REGISTER_H_
#include <iosfwd>
#include <memory> #include <memory>
// Clients of this interface shouldn't depend on lots of compiler internals. // Clients of this interface shouldn't depend on lots of compiler internals.
...@@ -107,6 +108,11 @@ class LiftoffRegister { ...@@ -107,6 +108,11 @@ class LiftoffRegister {
static_assert(IS_TRIVIALLY_COPYABLE(LiftoffRegister), static_assert(IS_TRIVIALLY_COPYABLE(LiftoffRegister),
"LiftoffRegister can efficiently be passed by value"); "LiftoffRegister can efficiently be passed by value");
inline std::ostream& operator<<(std::ostream& os, LiftoffRegister reg) {
return reg.is_gp() ? os << "gp" << reg.gp().code()
: os << "fp" << reg.fp().code();
}
class LiftoffRegList { class LiftoffRegList {
public: public:
static constexpr bool use_u16 = kAfterMaxLiftoffRegCode <= 16; static constexpr bool use_u16 = kAfterMaxLiftoffRegCode <= 16;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment