mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-07 14:28:40 +00:00
parallelize image fill
This commit is contained in:
+65
-40
@@ -2828,7 +2828,7 @@ THREAD_POOL_TASK_FUNC(lnk_patch_regular_symbols_task)
|
|||||||
U64 obj_idx = task_id;
|
U64 obj_idx = task_id;
|
||||||
LNK_Obj *obj = task->objs[obj_idx];
|
LNK_Obj *obj = task->objs[obj_idx];
|
||||||
|
|
||||||
ProfBegin("Patch Regular Symbols [%S]", obj->path);
|
ProfBeginV("Patch Regular Symbols [%S]", obj->path);
|
||||||
COFF_ParsedSymbol symbol;
|
COFF_ParsedSymbol symbol;
|
||||||
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
for (U64 symbol_idx = 0; symbol_idx < obj->header.symbol_count; symbol_idx += (1 + symbol.aux_symbol_count)) {
|
||||||
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
symbol = lnk_parsed_symbol_from_coff_symbol_idx(obj, symbol_idx);
|
||||||
@@ -2944,6 +2944,27 @@ THREAD_POOL_TASK_FUNC(lnk_patch_weak_symbols_task)
|
|||||||
lnk_patch_obj_symtab(task->symtab, task->objs[task_id], task->u.patch_symtabs.was_symbol_patched[task_id], COFF_SymbolValueInterp_Weak);
|
lnk_patch_obj_symtab(task->symtab, task->objs[task_id], task->u.patch_symtabs.was_symbol_patched[task_id], COFF_SymbolValueInterp_Weak);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal
|
||||||
|
THREAD_POOL_TASK_FUNC(lnk_image_fill_task)
|
||||||
|
{
|
||||||
|
ProfBeginFunction();
|
||||||
|
LNK_BuildImageTask *task = raw_task;
|
||||||
|
String8 image_data = task->u.image_fill.image_data;
|
||||||
|
for EachNode(n, LNK_ImageFillNode, task->u.image_fill.fill_nodes[task_id]) {
|
||||||
|
for EachIndex(i, n->sc_count) {
|
||||||
|
LNK_SectionContrib *sc = n->sc[i];
|
||||||
|
U64 cursor = 0;
|
||||||
|
for EachNode(data_n, String8Node, &sc->first_data_node) {
|
||||||
|
U64 image_off = sc->u.off + n->base_foff + cursor;
|
||||||
|
Assert(image_off + data_n->string.size <= image_data.size);
|
||||||
|
MemoryCopyStr8(image_data.str + image_off, data_n->string);
|
||||||
|
cursor += data_n->string.size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ProfEnd();
|
||||||
|
}
|
||||||
|
|
||||||
internal U64
|
internal U64
|
||||||
lnk_compute_win32_image_header_size(LNK_Config *config, U64 sect_count)
|
lnk_compute_win32_image_header_size(LNK_Config *config, U64 sect_count)
|
||||||
{
|
{
|
||||||
@@ -4406,55 +4427,59 @@ lnk_build_image(TP_Arena *arena, TP_Context *tp, LNK_Config *config, LNK_SymbolT
|
|||||||
{
|
{
|
||||||
ProfBegin("Image Fill");
|
ProfBegin("Image Fill");
|
||||||
|
|
||||||
LNK_SectionArray sects = lnk_section_array_from_list(scratch.arena, sectab->list);
|
ProfBeginV("Alloc Image Buffer [%M]", lnk_section_table_total_fsize(sectab));
|
||||||
|
image_data.size = lnk_section_table_total_fsize(sectab);
|
||||||
|
image_data.str = push_array_no_zero(arena->v[0], U8, image_data.size);
|
||||||
|
ProfEnd();
|
||||||
|
|
||||||
U64 image_size = 0;
|
ProfBegin("Fill Align Bytes");
|
||||||
for EachIndex(sect_idx, sects.count) { image_size += sects.v[sect_idx]->fsize; }
|
for EachNode(sect_n, LNK_SectionNode, sectab->list.first) {
|
||||||
|
LNK_Section *sect = §_n->data;
|
||||||
image_data.size = image_size;
|
ProfBeginV("Section: %S Size: %M", sect->name, sect->fsize);
|
||||||
image_data.str = push_array_no_zero(arena->v[0], U8, image_size);
|
U8 fill_byte = sect->flags & COFF_SectionFlag_CntCode ? coff_code_align_byte_from_machine(config->machine) : 0;
|
||||||
|
MemorySet(image_data.str + sect->foff, fill_byte, sect->fsize);
|
||||||
for EachIndex(sect_idx, sects.count) {
|
ProfEnd();
|
||||||
LNK_Section *sect = sects.v[sect_idx];
|
|
||||||
|
|
||||||
if (~sect->flags & COFF_SectionFlag_CntUninitializedData) {
|
|
||||||
// pick fill pick
|
|
||||||
U8 fill_byte = 0;
|
|
||||||
if (sect->flags & COFF_SectionFlag_CntCode) {
|
|
||||||
fill_byte = coff_code_align_byte_from_machine(config->machine);
|
|
||||||
}
|
}
|
||||||
|
ProfEnd();
|
||||||
|
|
||||||
// copy section contribution
|
Temp temp = temp_begin(scratch.arena);
|
||||||
U64 prev_sc_opl = 0;
|
|
||||||
for (LNK_SectionContribChunk *sc_chunk = sect->contribs.first; sc_chunk != 0; sc_chunk = sc_chunk->next) {
|
|
||||||
for EachIndex(sc_idx, sc_chunk->count) {
|
|
||||||
LNK_SectionContrib *sc = sc_chunk->v[sc_idx];
|
|
||||||
|
|
||||||
// fill align bytes
|
ProfBegin("Prepare Worker Nodes");
|
||||||
Assert(sc->u.off >= prev_sc_opl);
|
LNK_ImageFillNode **fill_nodes = push_array(scratch.arena, LNK_ImageFillNode *, tp->worker_count);
|
||||||
U64 fill_size = sc->u.off - prev_sc_opl;
|
U64 worker_cap = 4096, worker_load = 0, worker_idx = 0;
|
||||||
MemorySet(image_data.str + sect->foff + prev_sc_opl, fill_byte, fill_size);
|
for EachNode(sect_n, LNK_SectionNode, sectab->list.first) {
|
||||||
prev_sc_opl = sc->u.off + lnk_size_from_section_contrib(sc);
|
LNK_Section *sect = §_n->data;
|
||||||
|
|
||||||
// copy contrib contents
|
// skip bss sections
|
||||||
{
|
if (sect->flags & COFF_SectionFlag_CntUninitializedData) { continue; }
|
||||||
U64 cursor = 0;
|
|
||||||
for (String8Node *data_n = &sc->first_data_node; data_n != 0; data_n = data_n->next) {
|
for EachNode(sc_chunk, LNK_SectionContribChunk, sect->contribs.first) {
|
||||||
Assert(sc->u.off + data_n->string.size <= sect->vsize);
|
for (U64 sc_left = sc_chunk->count; sc_left > 0; ) {
|
||||||
MemoryCopy(image_data.str + sect->foff + sc->u.off + cursor, data_n->string.str, data_n->string.size);
|
U64 count = Min(worker_cap - worker_load, sc_left);
|
||||||
cursor += data_n->string.size;
|
U64 sc_pos = sc_chunk->count - sc_left;
|
||||||
|
sc_left -= count;
|
||||||
|
|
||||||
|
LNK_ImageFillNode *n = push_array(scratch.arena, LNK_ImageFillNode, 1);
|
||||||
|
n->base_foff = sect->foff;
|
||||||
|
n->sc_count = count;
|
||||||
|
n->sc = sc_chunk->v + sc_pos;
|
||||||
|
SLLStackPush(fill_nodes[worker_idx], n);
|
||||||
|
|
||||||
|
worker_load += count;
|
||||||
|
if (worker_load >= worker_cap) {
|
||||||
|
worker_load = 0;
|
||||||
|
worker_idx = (worker_idx + 1) % tp->worker_count;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ProfEnd();
|
||||||
|
|
||||||
// fill section align bytes
|
task.u.image_fill.image_data = image_data;
|
||||||
{
|
task.u.image_fill.fill_nodes = fill_nodes;
|
||||||
U64 fill_size = sect->fsize - prev_sc_opl;
|
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_image_fill_task, &task, "Fill");
|
||||||
MemorySet(image_data.str + sect->foff + prev_sc_opl, fill_byte, fill_size);
|
|
||||||
}
|
temp_end(temp);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ProfEnd();
|
ProfEnd();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -193,6 +193,15 @@ typedef struct
|
|||||||
LNK_RelocRefsList *reloc_refs;
|
LNK_RelocRefsList *reloc_refs;
|
||||||
} LNK_OptRefTask;
|
} LNK_OptRefTask;
|
||||||
|
|
||||||
|
typedef struct LNK_ImageFillNode
|
||||||
|
{
|
||||||
|
U64 base_foff;
|
||||||
|
U64 sc_count;
|
||||||
|
LNK_SectionContrib **sc;
|
||||||
|
|
||||||
|
struct LNK_ImageFillNode *next;
|
||||||
|
} LNK_ImageFillNode;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
LNK_SymbolTable *symtab;
|
LNK_SymbolTable *symtab;
|
||||||
@@ -224,6 +233,10 @@ typedef struct
|
|||||||
LNK_CommonBlockContrib *common_block_contribs;
|
LNK_CommonBlockContrib *common_block_contribs;
|
||||||
COFF_SymbolValueInterpType fixup_type;
|
COFF_SymbolValueInterpType fixup_type;
|
||||||
} patch_symtabs;
|
} patch_symtabs;
|
||||||
|
struct {
|
||||||
|
String8 image_data;
|
||||||
|
LNK_ImageFillNode **fill_nodes;
|
||||||
|
} image_fill;
|
||||||
} u;
|
} u;
|
||||||
} LNK_BuildImageTask;
|
} LNK_BuildImageTask;
|
||||||
|
|
||||||
|
|||||||
@@ -310,6 +310,22 @@ lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_l
|
|||||||
ProfEnd();
|
ProfEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal U64
|
||||||
|
lnk_section_table_total_fsize(LNK_SectionTable *sectab)
|
||||||
|
{
|
||||||
|
U64 total_fsize = 0;
|
||||||
|
for EachNode(n, LNK_SectionNode, sectab->list.first) { total_fsize += n->data.fsize; }
|
||||||
|
return total_fsize;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal U64
|
||||||
|
lnk_section_table_total_vsize(LNK_SectionTable *sectab)
|
||||||
|
{
|
||||||
|
U64 total_vsize = 0;
|
||||||
|
for EachNode(n, LNK_SectionNode, sectab->list.first) { total_vsize += n->data.vsize; }
|
||||||
|
return total_vsize;
|
||||||
|
}
|
||||||
|
|
||||||
internal int
|
internal int
|
||||||
lnk_section_contrib_chunk_is_before(void *raw_a, void *raw_b)
|
lnk_section_contrib_chunk_is_before(void *raw_a, void *raw_b)
|
||||||
{
|
{
|
||||||
@@ -468,3 +484,4 @@ lnk_get_first_section_contrib_voff(COFF_SectionHeader **image_section_table, LNK
|
|||||||
LNK_SectionContrib *sc = lnk_get_first_section_contrib(sect);
|
LNK_SectionContrib *sc = lnk_get_first_section_contrib(sect);
|
||||||
return lnk_voff_from_section_contrib(image_section_table, sc);
|
return lnk_voff_from_section_contrib(image_section_table, sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,6 +110,8 @@ internal void lnk_section_table_purge(LNK_SectionTable *sectab, S
|
|||||||
internal LNK_Section * lnk_section_table_search(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags);
|
internal LNK_Section * lnk_section_table_search(LNK_SectionTable *sectab, String8 name, COFF_SectionFlags flags);
|
||||||
internal LNK_SectionArray lnk_section_table_search_many(Arena *arena, LNK_SectionTable *sectab, String8 full_or_partial_name);
|
internal LNK_SectionArray lnk_section_table_search_many(Arena *arena, LNK_SectionTable *sectab, String8 full_or_partial_name);
|
||||||
internal void lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_list);
|
internal void lnk_section_table_merge(LNK_SectionTable *sectab, LNK_MergeDirectiveList merge_list);
|
||||||
|
internal U64 lnk_section_table_total_fsize(LNK_SectionTable *sectab);
|
||||||
|
internal U64 lnk_section_table_total_vsize(LNK_SectionTable *sectab);
|
||||||
|
|
||||||
// --- Section Finalization ----------------------------------------------------
|
// --- Section Finalization ----------------------------------------------------
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user