mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-14 09:18:09 +00:00
filter out duplicate page entries before computing the buffer size
This commit is contained in:
@@ -26,16 +26,20 @@ void_node_concat_atomic(VoidNode **head, VoidNode *node)
|
||||
node->next = ins_atomic_ptr_eval_assign(head, node);
|
||||
}
|
||||
|
||||
internal void
|
||||
u64_list_push_node(U64List *list, U64Node *n)
|
||||
{
|
||||
SLLQueuePush(list->first, list->last, n);
|
||||
list->count += 1;
|
||||
}
|
||||
|
||||
internal U64Node *
|
||||
u64_list_push(Arena *arena, U64List *list, U64 data)
|
||||
{
|
||||
U64Node *n = push_array(arena, U64Node, 1);
|
||||
n->next = 0;
|
||||
n->data = data;
|
||||
|
||||
SLLQueuePush(list->first, list->last, n);
|
||||
++list->count;
|
||||
|
||||
u64_list_push_node(list, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ typedef struct VoidNode
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
internal void u64_list_push_node(U64List *list, U64Node *n);
|
||||
internal U64Node * u64_list_push(Arena *arena, U64List *list, U64 data);
|
||||
internal void u64_list_concat_in_place(U64List *list, U64List *to_concat);
|
||||
internal U64Array u64_array_from_list(Arena *arena, U64List *list);
|
||||
|
||||
+55
-37
@@ -3637,44 +3637,59 @@ THREAD_POOL_TASK_FUNC(lnk_gather_base_reloc_pages_task)
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
internal
|
||||
THREAD_POOL_TASK_FUNC(lnk_filter_out_duplicate_base_reloc_entries_task)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
LNK_BaseRelocsTask *task = raw_task;
|
||||
|
||||
HashTable *voff_ht = hash_table_init(scratch.arena, task->page_size);
|
||||
for EachInRange(page_idx, task->serialize.ranges[task_id]) {
|
||||
LNK_BaseRelocPage *page = &task->serialize.pages.v[page_idx];
|
||||
|
||||
U64List unique_entries32 = {0};
|
||||
U64List unique_entries64 = {0};
|
||||
|
||||
// filter out duplicate 32-bit virtual offsets
|
||||
for (U64Node *curr = page->entries_addr32->first, *next; curr != 0; curr = next) {
|
||||
next = curr->next;
|
||||
if (hash_table_search_u64(voff_ht, curr->data)) { continue; }
|
||||
hash_table_push_u64_u64(scratch.arena, voff_ht, curr->data, 0);
|
||||
u64_list_push_node(&unique_entries32, curr);
|
||||
}
|
||||
|
||||
// filter out duplicate 64-bit virtual offsets
|
||||
for (U64Node *curr = page->entries_addr64->first, *next; curr != 0; curr = next) {
|
||||
next = curr->next;
|
||||
if (hash_table_search_u64(voff_ht, curr->data)) { continue; }
|
||||
hash_table_push_u64_u64(scratch.arena, voff_ht, curr->data, 0);
|
||||
u64_list_push_node(&unique_entries64, curr);
|
||||
}
|
||||
|
||||
*page->entries_addr32 = unique_entries32;
|
||||
*page->entries_addr64 = unique_entries64;
|
||||
|
||||
// purge hash table for the next run
|
||||
hash_table_purge(voff_ht);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
ProfEnd();
|
||||
}
|
||||
|
||||
internal
|
||||
THREAD_POOL_TASK_FUNC(lnk_serialize_base_reloc_pages_task)
|
||||
{
|
||||
ProfBeginFunction();
|
||||
Temp scratch = scratch_begin(0, 0);
|
||||
|
||||
LNK_BaseRelocsTask *task = raw_task;
|
||||
HashTable *voff_ht = hash_table_init(scratch.arena, task->page_size);
|
||||
|
||||
U64 voffs_max = task->page_size;
|
||||
U32 *voffs32 = push_array(scratch.arena, U32, voffs_max);
|
||||
U64 *voffs64 = push_array(scratch.arena, U64, voffs_max);
|
||||
LNK_BaseRelocsTask *task = raw_task;
|
||||
|
||||
for EachInRange(page_idx, task->serialize.ranges[task_id]) {
|
||||
LNK_BaseRelocPage *page = &task->serialize.pages.v[page_idx];
|
||||
|
||||
// filter out duplicate 32-bit virtual offsets
|
||||
U64 voff_count32 = 0;
|
||||
for EachNode(voff_n, U64Node, page->entries_addr32->first) {
|
||||
if (hash_table_search_u64(voff_ht, voff_n->data)) { continue; }
|
||||
hash_table_push_u64_u64(scratch.arena, voff_ht, voff_n->data, 0);
|
||||
voffs32[voff_count32] = voff_n->data;
|
||||
voff_count32 += 1;
|
||||
}
|
||||
|
||||
// filter out duplicate 64-bit virtual offsets
|
||||
U64 voff_count64 = 0;
|
||||
for EachNode(voff_n, U64Node, page->entries_addr64->first) {
|
||||
if (hash_table_search_u64(voff_ht, voff_n->data)) { continue; }
|
||||
hash_table_push_u64_u64(scratch.arena, voff_ht, voff_n->data, 0);
|
||||
voffs64[voff_count64] = voff_n->data;
|
||||
voff_count64 += 1;
|
||||
}
|
||||
|
||||
// gather step is not deterministic
|
||||
radsort(voffs32, voff_count32, u32_is_before);
|
||||
radsort(voffs64, voff_count64, u64_is_before);
|
||||
|
||||
// find block bytes in the buffer
|
||||
void *block = task->serialize.buffer + page->buffer_offset;
|
||||
|
||||
@@ -3685,18 +3700,22 @@ THREAD_POOL_TASK_FUNC(lnk_serialize_base_reloc_pages_task)
|
||||
U16 *reloc_arr_ptr = reloc_arr_base;
|
||||
|
||||
// write 32-bit relocation entries
|
||||
for EachIndex(i, voff_count32) {
|
||||
U64 rel_off = voffs32[i] - page->voff;
|
||||
U16 *reloc_entries32 = reloc_arr_ptr;
|
||||
for EachNode(n, U64Node, page->entries_addr32->first) {
|
||||
U64 rel_off = n->data - page->voff;
|
||||
*reloc_arr_ptr = PE_BaseRelocMake(PE_BaseRelocKind_HIGHLOW, rel_off);
|
||||
reloc_arr_ptr += 1;
|
||||
}
|
||||
radsort(reloc_entries32, page->entries_addr32->count, u16_is_before);
|
||||
|
||||
// write 64-bit relocation entries
|
||||
for EachIndex(i, voff_count64) {
|
||||
U64 rel_off = voffs64[i] - page->voff;
|
||||
U16 *reloc_entries64 = reloc_arr_ptr;
|
||||
for EachNode(n, U64Node, page->entries_addr64->first) {
|
||||
U64 rel_off = n->data - page->voff;
|
||||
*reloc_arr_ptr = PE_BaseRelocMake(PE_BaseRelocKind_DIR64, rel_off);
|
||||
reloc_arr_ptr += 1;
|
||||
}
|
||||
radsort(reloc_entries64, page->entries_addr64->count, u16_is_before);
|
||||
|
||||
// compute block size
|
||||
U64 reloc_arr_size = IntFromPtr(reloc_arr_ptr - reloc_arr_base) * sizeof(reloc_arr_ptr[0]);
|
||||
@@ -3710,9 +3729,6 @@ THREAD_POOL_TASK_FUNC(lnk_serialize_base_reloc_pages_task)
|
||||
// write page header
|
||||
*page_voff_ptr = safe_cast_u32(page->voff);
|
||||
*block_size_ptr = safe_cast_u32(block_size_aligned);
|
||||
|
||||
// purge hash table for the next run
|
||||
hash_table_purge(voff_ht);
|
||||
}
|
||||
|
||||
scratch_end(scratch);
|
||||
@@ -3786,6 +3802,10 @@ lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config, U6
|
||||
|
||||
String8 base_relocs = {0};
|
||||
{
|
||||
task.serialize.pages = pages;
|
||||
task.serialize.ranges = tp_divide_work(scratch.arena, pages.count, tp->worker_count);
|
||||
tp_for_parallel(tp, 0, tp->worker_count, lnk_filter_out_duplicate_base_reloc_entries_task, &task);
|
||||
|
||||
ProfBegin("Compute Buffer Size");
|
||||
U64 buffer_size = 0;
|
||||
for EachIndex(page_idx, pages.count) {
|
||||
@@ -3804,8 +3824,6 @@ lnk_build_base_relocs(TP_Context *tp, TP_Arena *tp_arena, LNK_Config *config, U6
|
||||
|
||||
task.serialize.buffer_size = buffer_size;
|
||||
task.serialize.buffer = buffer;
|
||||
task.serialize.pages = pages;
|
||||
task.serialize.ranges = tp_divide_work(scratch.arena, pages.count, tp->worker_count);
|
||||
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_serialize_base_reloc_pages_task, &task, "Serialize");
|
||||
|
||||
base_relocs = str8(task.serialize.buffer, task.serialize.buffer_size);
|
||||
|
||||
Reference in New Issue
Block a user