convert disassembler to use OStream
R=svenpanne@chromium.org BUG= Review URL: https://codereview.chromium.org/598703003 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24214 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
b3fb3f169c
commit
2f77113b50
@ -19,21 +19,6 @@ namespace internal {
|
||||
|
||||
#ifdef ENABLE_DISASSEMBLER
|
||||
|
||||
void Disassembler::Dump(FILE* f, byte* begin, byte* end) {
|
||||
for (byte* pc = begin; pc < end; pc++) {
|
||||
if (f == NULL) {
|
||||
PrintF("%" V8PRIxPTR " %4" V8PRIdPTR " %02x\n",
|
||||
reinterpret_cast<intptr_t>(pc),
|
||||
pc - begin,
|
||||
*pc);
|
||||
} else {
|
||||
PrintF(f, "%" V8PRIxPTR " %4" V8PRIdPTR " %02x\n",
|
||||
reinterpret_cast<uintptr_t>(pc), pc - begin, *pc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class V8NameConverter: public disasm::NameConverter {
|
||||
public:
|
||||
explicit V8NameConverter(Code* code) : code_(code) {}
|
||||
@ -74,12 +59,8 @@ const char* V8NameConverter::NameInCode(byte* addr) const {
|
||||
}
|
||||
|
||||
|
||||
static void DumpBuffer(FILE* f, StringBuilder* out) {
|
||||
if (f == NULL) {
|
||||
PrintF("%s\n", out->Finalize());
|
||||
} else {
|
||||
PrintF(f, "%s\n", out->Finalize());
|
||||
}
|
||||
static void DumpBuffer(OStream* os, StringBuilder* out) {
|
||||
(*os) << out->Finalize() << endl;
|
||||
out->Reset();
|
||||
}
|
||||
|
||||
@ -87,11 +68,8 @@ static void DumpBuffer(FILE* f, StringBuilder* out) {
|
||||
static const int kOutBufferSize = 2048 + String::kMaxShortPrintLength;
|
||||
static const int kRelocInfoPosition = 57;
|
||||
|
||||
static int DecodeIt(Isolate* isolate,
|
||||
FILE* f,
|
||||
const V8NameConverter& converter,
|
||||
byte* begin,
|
||||
byte* end) {
|
||||
static int DecodeIt(Isolate* isolate, OStream* os,
|
||||
const V8NameConverter& converter, byte* begin, byte* end) {
|
||||
SealHandleScope shs(isolate);
|
||||
DisallowHeapAllocation no_alloc;
|
||||
ExternalReferenceEncoder ref_encoder(isolate);
|
||||
@ -164,7 +142,7 @@ static int DecodeIt(Isolate* isolate,
|
||||
// Comments.
|
||||
for (int i = 0; i < comments.length(); i++) {
|
||||
out.AddFormatted(" %s", comments[i]);
|
||||
DumpBuffer(f, &out);
|
||||
DumpBuffer(os, &out);
|
||||
}
|
||||
|
||||
// Instruction address and instruction offset.
|
||||
@ -184,7 +162,7 @@ static int DecodeIt(Isolate* isolate,
|
||||
out.AddPadding(' ', kRelocInfoPosition - out.position());
|
||||
} else {
|
||||
// Additional reloc infos are printed on separate lines.
|
||||
DumpBuffer(f, &out);
|
||||
DumpBuffer(os, &out);
|
||||
out.AddPadding(' ', kRelocInfoPosition);
|
||||
}
|
||||
|
||||
@ -278,7 +256,7 @@ static int DecodeIt(Isolate* isolate,
|
||||
out.AddFormatted(" ;; %s", RelocInfo::RelocModeName(rmode));
|
||||
}
|
||||
}
|
||||
DumpBuffer(f, &out);
|
||||
DumpBuffer(os, &out);
|
||||
}
|
||||
|
||||
// Emit comments following the last instruction (if any).
|
||||
@ -287,7 +265,7 @@ static int DecodeIt(Isolate* isolate,
|
||||
if (RelocInfo::IsComment(it->rinfo()->rmode())) {
|
||||
out.AddFormatted(" %s",
|
||||
reinterpret_cast<const char*>(it->rinfo()->data()));
|
||||
DumpBuffer(f, &out);
|
||||
DumpBuffer(os, &out);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -297,40 +275,19 @@ static int DecodeIt(Isolate* isolate,
|
||||
}
|
||||
|
||||
|
||||
int Disassembler::Decode(Isolate* isolate, FILE* f, byte* begin, byte* end) {
|
||||
V8NameConverter defaultConverter(NULL);
|
||||
return DecodeIt(isolate, f, defaultConverter, begin, end);
|
||||
}
|
||||
|
||||
|
||||
// Called by Code::CodePrint.
|
||||
void Disassembler::Decode(FILE* f, Code* code) {
|
||||
Isolate* isolate = code->GetIsolate();
|
||||
int decode_size = code->is_crankshafted()
|
||||
? static_cast<int>(code->safepoint_table_offset())
|
||||
: code->instruction_size();
|
||||
// If there might be a back edge table, stop before reaching it.
|
||||
if (code->kind() == Code::FUNCTION) {
|
||||
decode_size =
|
||||
Min(decode_size, static_cast<int>(code->back_edge_table_offset()));
|
||||
}
|
||||
|
||||
byte* begin = code->instruction_start();
|
||||
byte* end = begin + decode_size;
|
||||
int Disassembler::Decode(Isolate* isolate, OStream* os, byte* begin, byte* end,
|
||||
Code* code) {
|
||||
V8NameConverter v8NameConverter(code);
|
||||
DecodeIt(isolate, f, v8NameConverter, begin, end);
|
||||
return DecodeIt(isolate, os, v8NameConverter, begin, end);
|
||||
}
|
||||
|
||||
#else // ENABLE_DISASSEMBLER
|
||||
|
||||
void Disassembler::Dump(FILE* f, byte* begin, byte* end) {}
|
||||
int Disassembler::Decode(Isolate* isolate, FILE* f, byte* begin, byte* end) {
|
||||
int Disassembler::Decode(Isolate* isolate, OStream* os, byte* begin, byte* end,
|
||||
Code* code) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void Disassembler::Decode(FILE* f, Code* code) {}
|
||||
|
||||
#endif // ENABLE_DISASSEMBLER
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -12,22 +12,12 @@ namespace internal {
|
||||
|
||||
class Disassembler : public AllStatic {
|
||||
public:
|
||||
// Print the bytes in the interval [begin, end) into f.
|
||||
static void Dump(FILE* f, byte* begin, byte* end);
|
||||
|
||||
// Decode instructions in the the interval [begin, end) and print the
|
||||
// code into f. Returns the number of bytes disassembled or 1 if no
|
||||
// code into os. Returns the number of bytes disassembled or 1 if no
|
||||
// instruction could be decoded.
|
||||
static int Decode(Isolate* isolate, FILE* f, byte* begin, byte* end);
|
||||
|
||||
// Decode instructions in code.
|
||||
static void Decode(FILE* f, Code* code);
|
||||
private:
|
||||
// Decode instruction at pc and print disassembled instruction into f.
|
||||
// Returns the instruction length in bytes, or 1 if the instruction could
|
||||
// not be decoded. The number of characters written is written into
|
||||
// the out parameter char_count.
|
||||
static int Decode(FILE* f, byte* pc, int* char_count);
|
||||
// the code object is used for name resolution and may be null.
|
||||
static int Decode(Isolate* isolate, OStream* os, byte* begin, byte* end,
|
||||
Code* code = NULL);
|
||||
};
|
||||
|
||||
} } // namespace v8::internal
|
||||
|
@ -2474,11 +2474,6 @@ void Assembler::emit_sse_operand(XMMRegister dst, Register src) {
|
||||
}
|
||||
|
||||
|
||||
void Assembler::Print() {
|
||||
Disassembler::Decode(isolate(), stdout, buffer_, pc_);
|
||||
}
|
||||
|
||||
|
||||
void Assembler::RecordJSReturn() {
|
||||
positions_recorder()->WriteRecordedPositions();
|
||||
EnsureSpace ensure_space(this);
|
||||
|
@ -1044,9 +1044,6 @@ class Assembler : public AssemblerBase {
|
||||
void prefetch(const Operand& src, int level);
|
||||
// TODO(lrn): Need SFENCE for movnt?
|
||||
|
||||
// Debugging
|
||||
void Print();
|
||||
|
||||
// Check the code size generated from label to here.
|
||||
int SizeOfCodeGeneratedSince(Label* label) {
|
||||
return pc_offset() - label->pos();
|
||||
|
@ -10871,10 +10871,19 @@ void Code::Disassemble(const char* name, OStream& os) { // NOLINT
|
||||
}
|
||||
|
||||
os << "Instructions (size = " << instruction_size() << ")\n";
|
||||
// TODO(svenpanne) The Disassembler should use streams, too!
|
||||
{
|
||||
CodeTracer::Scope trace_scope(GetIsolate()->GetCodeTracer());
|
||||
Disassembler::Decode(trace_scope.file(), this);
|
||||
Isolate* isolate = GetIsolate();
|
||||
int decode_size = is_crankshafted()
|
||||
? static_cast<int>(safepoint_table_offset())
|
||||
: instruction_size();
|
||||
// If there might be a back edge table, stop before reaching it.
|
||||
if (kind() == Code::FUNCTION) {
|
||||
decode_size =
|
||||
Min(decode_size, static_cast<int>(back_edge_table_offset()));
|
||||
}
|
||||
byte* begin = instruction_start();
|
||||
byte* end = begin + decode_size;
|
||||
Disassembler::Decode(isolate, &os, begin, end, this);
|
||||
}
|
||||
os << "\n";
|
||||
|
||||
|
@ -170,11 +170,10 @@ TEST(AssemblerIa323) {
|
||||
assm.GetCode(&desc);
|
||||
Handle<Code> code = isolate->factory()->NewCode(
|
||||
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
||||
// don't print the code - our disassembler can't handle cvttss2si
|
||||
// instead print bytes
|
||||
Disassembler::Dump(stdout,
|
||||
code->instruction_start(),
|
||||
code->instruction_start() + code->instruction_size());
|
||||
#ifdef OBJECT_PRINT
|
||||
OFStream os(stdout);
|
||||
code->Print(os);
|
||||
#endif
|
||||
F3 f = FUNCTION_CAST<F3>(code->entry());
|
||||
int res = f(static_cast<float>(-3.1415));
|
||||
::printf("f() = %d\n", res);
|
||||
@ -200,11 +199,10 @@ TEST(AssemblerIa324) {
|
||||
assm.GetCode(&desc);
|
||||
Handle<Code> code = isolate->factory()->NewCode(
|
||||
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
||||
// don't print the code - our disassembler can't handle cvttsd2si
|
||||
// instead print bytes
|
||||
Disassembler::Dump(stdout,
|
||||
code->instruction_start(),
|
||||
code->instruction_start() + code->instruction_size());
|
||||
#ifdef OBJECT_PRINT
|
||||
OFStream os(stdout);
|
||||
code->Print(os);
|
||||
#endif
|
||||
F4 f = FUNCTION_CAST<F4>(code->entry());
|
||||
int res = f(2.718281828);
|
||||
::printf("f() = %d\n", res);
|
||||
@ -261,13 +259,9 @@ TEST(AssemblerIa326) {
|
||||
assm.GetCode(&desc);
|
||||
Handle<Code> code = isolate->factory()->NewCode(
|
||||
desc, Code::ComputeFlags(Code::STUB), Handle<Code>());
|
||||
#ifdef DEBUG
|
||||
::printf("\n---\n");
|
||||
// don't print the code - our disassembler can't handle SSE instructions
|
||||
// instead print bytes
|
||||
Disassembler::Dump(stdout,
|
||||
code->instruction_start(),
|
||||
code->instruction_start() + code->instruction_size());
|
||||
#ifdef OBJECT_PRINT
|
||||
OFStream os(stdout);
|
||||
code->Print(os);
|
||||
#endif
|
||||
F5 f = FUNCTION_CAST<F5>(code->entry());
|
||||
double res = f(2.2, 1.1);
|
||||
|
Loading…
Reference in New Issue
Block a user