Speeding up source map lookup for x64 disasm.
This commit is contained in:
parent
14e1438ec0
commit
9c58426231
|
@ -101,6 +101,11 @@ bool X64Assembler::Assemble(FunctionInfo* symbol_info, HIRBuilder* builder,
|
||||||
|
|
||||||
void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
|
void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
|
||||||
size_t code_size, StringBuffer* str) {
|
size_t code_size, StringBuffer* str) {
|
||||||
|
auto source_map_entries = debug_info->source_map_entries();
|
||||||
|
auto source_map_count = debug_info->source_map_count();
|
||||||
|
auto source_map_index = 0;
|
||||||
|
uint32_t next_code_offset = source_map_entries[0].code_offset;
|
||||||
|
|
||||||
BE::DISASM disasm = {0};
|
BE::DISASM disasm = {0};
|
||||||
disasm.Archi = 64;
|
disasm.Archi = 64;
|
||||||
disasm.Options = BE::Tabulation + BE::MasmSyntax + BE::PrefixedNumeral;
|
disasm.Options = BE::Tabulation + BE::MasmSyntax + BE::PrefixedNumeral;
|
||||||
|
@ -109,24 +114,23 @@ void X64Assembler::DumpMachineCode(DebugInfo* debug_info, void* machine_code,
|
||||||
uint64_t prev_source_offset = 0;
|
uint64_t prev_source_offset = 0;
|
||||||
while (disasm.EIP < eip_end) {
|
while (disasm.EIP < eip_end) {
|
||||||
// Look up source offset.
|
// Look up source offset.
|
||||||
auto map_entry = debug_info->LookupCodeOffset(
|
auto code_offset =
|
||||||
static_cast<uint32_t>(disasm.EIP - (BE::UIntPtr)machine_code));
|
static_cast<uint32_t>(disasm.EIP - (BE::UIntPtr)machine_code);
|
||||||
if (map_entry) {
|
if (code_offset >= next_code_offset &&
|
||||||
if (map_entry->source_offset == prev_source_offset) {
|
source_map_index < source_map_count) {
|
||||||
str->Append(" ");
|
auto& source_map_entry = source_map_entries[source_map_index];
|
||||||
} else {
|
str->AppendFormat("%.8X ", source_map_entry.source_offset);
|
||||||
str->AppendFormat("%.8X ", map_entry->source_offset);
|
++source_map_index;
|
||||||
prev_source_offset = map_entry->source_offset;
|
next_code_offset = source_map_entries[source_map_index].code_offset;
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
str->Append("? ");
|
str->Append(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t len = BE::Disasm(&disasm);
|
size_t len = BE::Disasm(&disasm);
|
||||||
if (len == BE::UNKNOWN_OPCODE) {
|
if (len == BE::UNKNOWN_OPCODE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
str->AppendFormat("%p %s\n", disasm.EIP, disasm.CompleteInstr);
|
str->AppendFormat("%.8X %s\n", uint32_t(disasm.EIP), disasm.CompleteInstr);
|
||||||
disasm.EIP += len;
|
disasm.EIP += len;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -255,7 +255,7 @@ void X64Emitter::MarkSourceOffset(const Instr* i) {
|
||||||
auto entry = source_map_arena_.Alloc<SourceMapEntry>();
|
auto entry = source_map_arena_.Alloc<SourceMapEntry>();
|
||||||
entry->source_offset = static_cast<uint32_t>(i->src1.offset);
|
entry->source_offset = static_cast<uint32_t>(i->src1.offset);
|
||||||
entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal;
|
entry->hir_offset = uint32_t(i->block->ordinal << 16) | i->ordinal;
|
||||||
entry->code_offset = static_cast<uint32_t>(getSize());
|
entry->code_offset = static_cast<uint32_t>(getSize() + 1);
|
||||||
source_map_count_++;
|
source_map_count_++;
|
||||||
|
|
||||||
if (FLAGS_debug) {
|
if (FLAGS_debug) {
|
||||||
|
|
|
@ -20,10 +20,10 @@ DebugInfo::DebugInfo()
|
||||||
hir_disasm_(nullptr),
|
hir_disasm_(nullptr),
|
||||||
machine_code_disasm_(nullptr),
|
machine_code_disasm_(nullptr),
|
||||||
source_map_count_(0),
|
source_map_count_(0),
|
||||||
source_map_(nullptr) {}
|
source_map_entries_(nullptr) {}
|
||||||
|
|
||||||
DebugInfo::~DebugInfo() {
|
DebugInfo::~DebugInfo() {
|
||||||
free(source_map_);
|
free(source_map_entries_);
|
||||||
free(source_disasm_);
|
free(source_disasm_);
|
||||||
free(raw_hir_disasm_);
|
free(raw_hir_disasm_);
|
||||||
free(hir_disasm_);
|
free(hir_disasm_);
|
||||||
|
@ -33,7 +33,7 @@ DebugInfo::~DebugInfo() {
|
||||||
void DebugInfo::InitializeSourceMap(size_t source_map_count,
|
void DebugInfo::InitializeSourceMap(size_t source_map_count,
|
||||||
SourceMapEntry* source_map) {
|
SourceMapEntry* source_map) {
|
||||||
source_map_count_ = source_map_count;
|
source_map_count_ = source_map_count;
|
||||||
source_map_ = source_map;
|
source_map_entries_ = source_map;
|
||||||
|
|
||||||
// TODO(benvanik): ensure sorted in some way? MC offset?
|
// TODO(benvanik): ensure sorted in some way? MC offset?
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ void DebugInfo::InitializeSourceMap(size_t source_map_count,
|
||||||
SourceMapEntry* DebugInfo::LookupSourceOffset(uint32_t offset) {
|
SourceMapEntry* DebugInfo::LookupSourceOffset(uint32_t offset) {
|
||||||
// TODO(benvanik): binary search? We know the list is sorted by code order.
|
// TODO(benvanik): binary search? We know the list is sorted by code order.
|
||||||
for (size_t n = 0; n < source_map_count_; n++) {
|
for (size_t n = 0; n < source_map_count_; n++) {
|
||||||
auto entry = &source_map_[n];
|
auto entry = &source_map_entries_[n];
|
||||||
if (entry->source_offset == offset) {
|
if (entry->source_offset == offset) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ SourceMapEntry* DebugInfo::LookupSourceOffset(uint32_t offset) {
|
||||||
SourceMapEntry* DebugInfo::LookupHIROffset(uint32_t offset) {
|
SourceMapEntry* DebugInfo::LookupHIROffset(uint32_t offset) {
|
||||||
// TODO(benvanik): binary search? We know the list is sorted by code order.
|
// TODO(benvanik): binary search? We know the list is sorted by code order.
|
||||||
for (size_t n = 0; n < source_map_count_; n++) {
|
for (size_t n = 0; n < source_map_count_; n++) {
|
||||||
auto entry = &source_map_[n];
|
auto entry = &source_map_entries_[n];
|
||||||
if (entry->hir_offset >= offset) {
|
if (entry->hir_offset >= offset) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ SourceMapEntry* DebugInfo::LookupHIROffset(uint32_t offset) {
|
||||||
SourceMapEntry* DebugInfo::LookupCodeOffset(uint32_t offset) {
|
SourceMapEntry* DebugInfo::LookupCodeOffset(uint32_t offset) {
|
||||||
// TODO(benvanik): binary search? We know the list is sorted by code order.
|
// TODO(benvanik): binary search? We know the list is sorted by code order.
|
||||||
for (int64_t n = source_map_count_ - 1; n >= 0; n--) {
|
for (int64_t n = source_map_count_ - 1; n >= 0; n--) {
|
||||||
auto entry = &source_map_[n];
|
auto entry = &source_map_entries_[n];
|
||||||
if (entry->code_offset <= offset) {
|
if (entry->code_offset <= offset) {
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,8 @@ class DebugInfo {
|
||||||
const char* machine_code_disasm() const { return machine_code_disasm_; }
|
const char* machine_code_disasm() const { return machine_code_disasm_; }
|
||||||
void set_machine_code_disasm(char* value) { machine_code_disasm_ = value; }
|
void set_machine_code_disasm(char* value) { machine_code_disasm_ = value; }
|
||||||
|
|
||||||
|
size_t source_map_count() const { return source_map_count_; }
|
||||||
|
SourceMapEntry* source_map_entries() const { return source_map_entries_; }
|
||||||
void InitializeSourceMap(size_t source_map_count, SourceMapEntry* source_map);
|
void InitializeSourceMap(size_t source_map_count, SourceMapEntry* source_map);
|
||||||
SourceMapEntry* LookupSourceOffset(uint32_t offset);
|
SourceMapEntry* LookupSourceOffset(uint32_t offset);
|
||||||
SourceMapEntry* LookupHIROffset(uint32_t offset);
|
SourceMapEntry* LookupHIROffset(uint32_t offset);
|
||||||
|
@ -90,7 +92,7 @@ class DebugInfo {
|
||||||
char* machine_code_disasm_;
|
char* machine_code_disasm_;
|
||||||
|
|
||||||
size_t source_map_count_;
|
size_t source_map_count_;
|
||||||
SourceMapEntry* source_map_;
|
SourceMapEntry* source_map_entries_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace cpu
|
} // namespace cpu
|
||||||
|
|
Loading…
Reference in New Issue