Commit ab1d270a authored by mtrofin's avatar mtrofin Committed by Commit bot

[assembler] Introduce proper AssemblerBase::Print() for improved debuggability.

While working on frame elision, I wanted to disassemble codegen in the
debugger, as the code generation is progressing. I discovered we had a
 "Print" member on the x64 assembler, without any implementation. I
pulled it up to AssemblerBase and gave it an implementation that
should work for the other architectures.

Also checked that ia32, x87, arm and arm64 assemblers didn't have
such an implementation - free Print.

Arm64 has a naming conflict with the v8::internal::Disassembler. I
renamed the arm64 type with a more specific name.

Opportunistically fixed a bug in the name converter. This debug-time
printer doesn't provide a Code object, which should be OK with the
name converters, by the looks of other APIs there. All this means is that
when using the Print() API, we just get addresses dumped without any
context (like what this address may be - a stub maybe, etc). This seems
fine for the scenario.

There may be other places that assume a Code object. Since this is
a diagnostics-only scenario, for codegen developers, I feel it is
reasonable to fix such other places as we find them.

Review URL: https://codereview.chromium.org/1431933003

Cr-Commit-Position: refs/heads/master@{#31869}
parent be4d1b19
This diff is collapsed.
......@@ -14,11 +14,11 @@ namespace v8 {
namespace internal {
class Disassembler: public DecoderVisitor {
class DisassemblingDecoder : public DecoderVisitor {
public:
Disassembler();
Disassembler(char* text_buffer, int buffer_size);
virtual ~Disassembler();
DisassemblingDecoder();
DisassemblingDecoder(char* text_buffer, int buffer_size);
virtual ~DisassemblingDecoder();
char* GetOutput();
// Declare all Visitor functions.
......@@ -73,7 +73,7 @@ class Disassembler: public DecoderVisitor {
};
class PrintDisassembler: public Disassembler {
class PrintDisassembler : public DisassemblingDecoder {
public:
explicit PrintDisassembler(FILE* stream) : stream_(stream) { }
~PrintDisassembler() { }
......
......@@ -46,9 +46,11 @@
#include "src/counters.h"
#include "src/debug/debug.h"
#include "src/deoptimizer.h"
#include "src/disassembler.h"
#include "src/execution.h"
#include "src/ic/ic.h"
#include "src/ic/stub-cache.h"
#include "src/ostreams.h"
#include "src/profiler/cpu-profiler.h"
#include "src/regexp/jsregexp.h"
#include "src/regexp/regexp-macro-assembler.h"
......@@ -215,6 +217,12 @@ void AssemblerBase::FlushICacheWithoutIsolate(void* start, size_t size) {
}
void AssemblerBase::Print() {
OFStream os(stdout);
v8::internal::Disassembler::Decode(isolate(), &os, buffer_, pc_, nullptr);
}
// -----------------------------------------------------------------------------
// Implementation of PredictableCodeSizeScope
......
......@@ -100,6 +100,9 @@ class AssemblerBase: public Malloced {
// the assembler could clean up internal data structures.
virtual void AbortedCodeGeneration() { }
// Debugging
void Print();
static const int kMinimalBufferSize = 4*KB;
static void FlushICache(Isolate* isolate, void* start, size_t size);
......
......@@ -32,7 +32,9 @@ class V8NameConverter: public disasm::NameConverter {
const char* V8NameConverter::NameOfAddress(byte* pc) const {
const char* name = code_->GetIsolate()->builtins()->Lookup(pc);
const char* name =
code_ == NULL ? NULL : code_->GetIsolate()->builtins()->Lookup(pc);
if (name != NULL) {
SNPrintF(v8_buffer_, "%s (%p)", name, pc);
return v8_buffer_.start();
......
......@@ -1614,9 +1614,6 @@ class Assembler : public AssemblerBase {
void rorxl(Register dst, Register src, byte imm8);
void rorxl(Register dst, const Operand& src, byte imm8);
// Debugging
void Print();
// Check the code size generated from label to here.
int SizeOfCodeGeneratedSince(Label* label) {
return pc_offset() - label->pos();
......
......@@ -45,16 +45,16 @@ using namespace v8::internal;
#define EXP_SIZE (256)
#define INSTR_SIZE (1024)
#define SET_UP_CLASS(ASMCLASS) \
InitializeVM(); \
Isolate* isolate = Isolate::Current(); \
HandleScope scope(isolate); \
byte* buf = static_cast<byte*>(malloc(INSTR_SIZE)); \
uint32_t encoding = 0; \
ASMCLASS* assm = new ASMCLASS(isolate, buf, INSTR_SIZE); \
Decoder<DispatchingDecoderVisitor>* decoder = \
new Decoder<DispatchingDecoderVisitor>(); \
Disassembler* disasm = new Disassembler(); \
#define SET_UP_CLASS(ASMCLASS) \
InitializeVM(); \
Isolate* isolate = Isolate::Current(); \
HandleScope scope(isolate); \
byte* buf = static_cast<byte*>(malloc(INSTR_SIZE)); \
uint32_t encoding = 0; \
ASMCLASS* assm = new ASMCLASS(isolate, buf, INSTR_SIZE); \
Decoder<DispatchingDecoderVisitor>* decoder = \
new Decoder<DispatchingDecoderVisitor>(); \
DisassemblingDecoder* disasm = new DisassemblingDecoder(); \
decoder->AppendVisitor(disasm)
#define SET_UP() SET_UP_CLASS(Assembler)
......
......@@ -59,7 +59,7 @@ TEST(FUZZ_disasm) {
seed48(seed);
Decoder<DispatchingDecoderVisitor> decoder;
Disassembler disasm;
DisassemblingDecoder disasm;
Instruction buffer[kInstructionSize];
decoder.AppendVisitor(&disasm);
......
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