[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: Ben Titzer <titzer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#50407}
This commit is contained in:
Clemens Hammacher 2018-01-08 13:42:55 +01:00 committed by Commit Bot
parent 501413b9b9
commit 3f3034825b
5 changed files with 34 additions and 19 deletions

View File

@ -36,6 +36,7 @@
#define V8_ASSEMBLER_H_
#include <forward_list>
#include <iosfwd>
#include "src/allocation.h"
#include "src/builtins/builtins.h"
@ -1338,6 +1339,12 @@ class RegisterBase {
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 v8
#endif // V8_ASSEMBLER_H_

View File

@ -391,6 +391,19 @@ uint32_t LiftoffAssembler::GetTotalFrameSlotCount() const {
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 TRACE

View File

@ -5,6 +5,7 @@
#ifndef V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_H_
#define V8_WASM_BASELINE_LIFTOFF_ASSEMBLER_H_
#include <iosfwd>
#include <memory>
// Clients of this interface shouldn't depend on lots of compiler internals.
@ -338,6 +339,8 @@ class LiftoffAssembler : public TurboAssembler {
LiftoffRegister SpillOneRegister(RegClass rc, LiftoffRegList pinned);
};
std::ostream& operator<<(std::ostream& os, LiftoffAssembler::VarState);
} // namespace wasm
} // namespace internal
} // namespace v8

View File

@ -771,35 +771,21 @@ class LiftoffCompiler {
void TraceCacheState(Decoder* decoder) const {
#ifdef DEBUG
if (!FLAG_trace_liftoff) return;
OFStream os(stdout);
for (int control_depth = decoder->control_depth() - 1; control_depth >= -1;
--control_depth) {
LiftoffAssembler::CacheState* cache_state =
control_depth == -1
? asm_->cache_state()
: &decoder->control_at(control_depth)->label_state;
int idx = 0;
bool first = true;
for (LiftoffAssembler::VarState& slot : cache_state->stack_state) {
if (idx++) PrintF("-");
PrintF("%s:", WasmOpcodes::TypeName(slot.type()));
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;
}
os << (first ? "" : "-") << slot;
first = false;
}
if (control_depth != -1) PrintF("; ");
}
PrintF("\n");
os << "\n";
#endif
}
};

View File

@ -5,6 +5,7 @@
#ifndef V8_WASM_BASELINE_LIFTOFF_REGISTER_H_
#define V8_WASM_BASELINE_LIFTOFF_REGISTER_H_
#include <iosfwd>
#include <memory>
// Clients of this interface shouldn't depend on lots of compiler internals.
@ -107,6 +108,11 @@ class LiftoffRegister {
static_assert(IS_TRIVIALLY_COPYABLE(LiftoffRegister),
"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 {
public:
static constexpr bool use_u16 = kAfterMaxLiftoffRegCode <= 16;