Source map in DebugInfo. IVM needs to port its stuff over eventually.

This commit is contained in:
Ben Vanik
2014-01-25 21:20:28 -08:00
parent 4609339c5a
commit 0cca23cdd7
12 changed files with 135 additions and 19 deletions

View File

@@ -185,7 +185,8 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
// --------------------------------------------------------------------------
table->AddSequence(OPCODE_COMMENT, [](X64Emitter& e, Instr*& i) {
//char* str = (char*)i->src1.offset;
// TODO(benvanik): pass through.
auto str = (const char*)i->src1.offset;
//lb.Comment(str);
//UNIMPLEMENTED_SEQ();
i = i->next;
@@ -206,8 +207,7 @@ void alloy::backend::x64::lowering::RegisterSequences(LoweringTable* table) {
table->AddSequence(OPCODE_SOURCE_OFFSET, [](X64Emitter& e, Instr*& i) {
// TODO(benvanik): translate source offsets for mapping? We're just passing
// down the original offset - it may be nice to have two.
//lb.SourceOffset(i->src1.offset);
//UNIMPLEMENTED_SEQ();
e.MarkSourceOffset(i);
i = i->next;
return true;
});

View File

@@ -70,12 +70,14 @@ int X64Assembler::Assemble(
// Lower HIR -> x64.
void* machine_code = 0;
size_t code_size = 0;
result = emitter_->Emit(builder, machine_code, code_size);
result = emitter_->Emit(builder,
debug_info_flags, debug_info,
machine_code, code_size);
XEEXPECTZERO(result);
// Stash generated machine code.
if (debug_info_flags & DEBUG_INFO_MACHINE_CODE_DISASM) {
DumpMachineCode(machine_code, code_size, &string_buffer_);
DumpMachineCode(debug_info, machine_code, code_size, &string_buffer_);
debug_info->set_machine_code_disasm(string_buffer_.ToString());
string_buffer_.Reset();
}
@@ -94,14 +96,31 @@ XECLEANUP:
}
void X64Assembler::DumpMachineCode(
void* machine_code, size_t code_size, StringBuffer* str) {
DebugInfo* debug_info,
void* machine_code, size_t code_size,
StringBuffer* str) {
BE::DISASM disasm;
xe_zero_struct(&disasm, sizeof(disasm));
disasm.Archi = 64;
disasm.Options = BE::Tabulation + BE::MasmSyntax + BE::PrefixedNumeral;
disasm.EIP = (BE::UIntPtr)machine_code;
BE::UIntPtr eip_end = disasm.EIP + code_size;
uint64_t prev_source_offset = 0;
while (disasm.EIP < eip_end) {
// Look up source offset.
auto map_entry = debug_info->LookupCodeOffset(
disasm.EIP - (BE::UIntPtr)machine_code);
if (map_entry) {
if (map_entry->source_offset == prev_source_offset) {
str->Append(" ");
} else {
str->Append("%.8X ", map_entry->source_offset);
prev_source_offset = map_entry->source_offset;
}
} else {
str->Append("? ");
}
size_t len = BE::Disasm(&disasm);
if (len == BE::UNKNOWN_OPCODE) {
break;

View File

@@ -38,7 +38,9 @@ public:
runtime::Function** out_function);
private:
void DumpMachineCode(void* machine_code, size_t code_size, StringBuffer* str);
void DumpMachineCode(runtime::DebugInfo* debug_info,
void* machine_code, size_t code_size,
StringBuffer* str);
private:
X64Backend* x64_backend_;

View File

@@ -13,6 +13,7 @@
#include <alloy/backend/x64/x64_code_cache.h>
#include <alloy/backend/x64/lowering/lowering_table.h>
#include <alloy/hir/hir_builder.h>
#include <alloy/runtime/debug_info.h>
using namespace alloy;
using namespace alloy::backend;
@@ -51,7 +52,15 @@ int X64Emitter::Initialize() {
}
int X64Emitter::Emit(
HIRBuilder* builder, void*& out_code_address, size_t& out_code_size) {
HIRBuilder* builder,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info,
void*& out_code_address, size_t& out_code_size) {
// Reset.
if (debug_info_flags & DEBUG_INFO_SOURCE_MAP) {
source_map_count_ = 0;
source_map_arena_.Reset();
}
// Fill the generator with code.
int result = Emit(builder);
if (result) {
@@ -62,6 +71,13 @@ int X64Emitter::Emit(
out_code_size = getSize();
out_code_address = Emplace(code_cache_);
// Stash source map.
if (debug_info_flags & DEBUG_INFO_SOURCE_MAP) {
debug_info->InitializeSourceMap(
source_map_count_,
(SourceMapEntry*)source_map_arena_.CloneContents());
}
return 0;
}
@@ -211,3 +227,11 @@ void X64Emitter::FindFreeRegs(
FindFreeRegs(v2, v2_idx, v2_flags);
FindFreeRegs(v3, v3_idx, v3_flags);
}
void X64Emitter::MarkSourceOffset(Instr* i) {
auto entry = source_map_arena_.Alloc<SourceMapEntry>();
entry->source_offset = i->src1.offset;
entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal;
entry->code_offset = getSize();
source_map_count_++;
}

View File

@@ -18,6 +18,7 @@
XEDECLARECLASS2(alloy, hir, HIRBuilder);
XEDECLARECLASS2(alloy, hir, Instr);
XEDECLARECLASS2(alloy, runtime, DebugInfo);
namespace alloy {
namespace backend {
@@ -45,6 +46,7 @@ public:
int Initialize();
int Emit(hir::HIRBuilder* builder,
uint32_t debug_info_flags, runtime::DebugInfo* debug_info,
void*& out_code_address, size_t& out_code_size);
public:
@@ -132,6 +134,8 @@ public:
static uint32_t GetRegBit(const Xbyak::Reg64& r) { return 1 << r.getIdx(); }
static uint32_t GetRegBit(const Xbyak::Xmm& r) { return 1 << (16 + r.getIdx()); }
void MarkSourceOffset(hir::Instr* i);
private:
void* Emplace(X64CodeCache* code_cache);
int Emit(hir::HIRBuilder* builder);
@@ -150,6 +154,9 @@ private:
// Current register values.
hir::Value* reg_values[32];
} reg_state_;
size_t source_map_count_;
Arena source_map_arena_;
};

View File

@@ -20,11 +20,12 @@ using namespace alloy::runtime;
X64Function::X64Function(FunctionInfo* symbol_info) :
machine_code_(0), code_size_(0),
machine_code_(NULL), code_size_(0),
GuestFunction(symbol_info) {
}
X64Function::~X64Function() {
// machine_code_ is freed by code cache.
}
void X64Function::Setup(void* machine_code, size_t code_size) {

View File

@@ -34,8 +34,8 @@ protected:
uint64_t return_address);
private:
void* machine_code_;
size_t code_size_;
void* machine_code_;
size_t code_size_;
};