mirror of
https://github.com/Ed94/raddebugger.git
synced 2026-08-07 22:38:41 +00:00
switch over to 64-bit pointer tagging
This commit is contained in:
+37
-54
@@ -2167,26 +2167,21 @@ lnk_link_image(TP_Context *tp, TP_Arena *arena, LNK_Config *config, LNK_Inputer
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
lnk_reloc_refs_list_push_node(LNK_RelocRefsList *list, LNK_RelocRefsNode *tagged_node)
|
lnk_reloc_refs_list_push_node(LNK_RelocRefsList *list, LNK_RelocRefsNode *node)
|
||||||
{
|
{
|
||||||
U64 node_tag = UnpackPointerTag(tagged_node);
|
LNK_RelocRefsPointer old_head = list->head;
|
||||||
LNK_RelocRefsNode *node = UnpackPointer(tagged_node);
|
node->next = old_head.node;
|
||||||
|
list->head = (LNK_RelocRefsPointer){ .node = node, .tag = old_head.tag + 1 };
|
||||||
node->next = list->head;
|
|
||||||
list->head = PackPointer(node, node_tag);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal LNK_RelocRefsNode *
|
internal LNK_RelocRefsNode *
|
||||||
lnk_reloc_refs_list_pop_node(LNK_RelocRefsList *list)
|
lnk_reloc_refs_list_pop_node(LNK_RelocRefsList *list)
|
||||||
{
|
{
|
||||||
LNK_RelocRefsNode *result = list->head;
|
LNK_RelocRefsPointer old_head = list->head;
|
||||||
|
if (old_head.node) {
|
||||||
if (list->head) {
|
list->head = (LNK_RelocRefsPointer){ .node = old_head.node->next, .tag = old_head.tag + 1};
|
||||||
LNK_RelocRefsNode *head = UnpackPointer(list->head);
|
|
||||||
list->head = head->next;
|
|
||||||
}
|
}
|
||||||
|
return old_head.node;
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal LNK_RelocRefsNode *
|
internal LNK_RelocRefsNode *
|
||||||
@@ -2201,43 +2196,34 @@ lnk_reloc_refs_list_push(Arena *arena, LNK_RelocRefsList *list, LNK_RelocRefs *v
|
|||||||
internal LNK_RelocRefsNode *
|
internal LNK_RelocRefsNode *
|
||||||
lnk_reloc_refs_list_pop_node_atomic(LNK_RelocRefsList *list)
|
lnk_reloc_refs_list_pop_node_atomic(LNK_RelocRefsList *list)
|
||||||
{
|
{
|
||||||
LNK_RelocRefsNode *tagged_node;
|
LNK_RelocRefsPointer old_head = { .node = ins_atomic_ptr_eval(&list->head.node), .tag = ins_atomic_u64_eval(&list->head.tag) };
|
||||||
for (;;) {
|
for (;;) {
|
||||||
tagged_node = list->head;
|
if (old_head.node == 0) { break; }
|
||||||
if (tagged_node == 0) { break; }
|
LNK_RelocRefsPointer new_head = { .node = old_head.node->next, .tag = old_head.tag + 1 };
|
||||||
|
if (ins_atomic_u128_eval_cond_assign(&list->head, &new_head, &old_head)) { break; }
|
||||||
LNK_RelocRefsNode *head = UnpackPointer(tagged_node);
|
|
||||||
LNK_RelocRefsNode *tagged_next = head->next;
|
|
||||||
|
|
||||||
void *swap = ins_atomic_ptr_eval_cond_assign(&list->head, tagged_next, tagged_node);
|
|
||||||
if (swap == tagged_node) { break; }
|
|
||||||
}
|
}
|
||||||
return tagged_node;
|
return old_head.node;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
lnk_reloc_refs_list_push_node_atomic(LNK_RelocRefsList *list, LNK_RelocRefsNode *tagged_node)
|
lnk_reloc_refs_list_push_node_atomic(LNK_RelocRefsList *list, LNK_RelocRefsNode *node)
|
||||||
{
|
{
|
||||||
tagged_node = BumpPointerTag(tagged_node);
|
LNK_RelocRefsPointer old_head = { .node = ins_atomic_ptr_eval(&list->head.node), .tag = ins_atomic_u64_eval(&list->head.tag) };
|
||||||
for (;;) {
|
for (;;) {
|
||||||
LNK_RelocRefsNode *old_head = list->head;
|
node->next = old_head.node;
|
||||||
LNK_RelocRefsNode *node = UnpackPointer(tagged_node);
|
LNK_RelocRefsPointer new_head = { .node = node, .tag = old_head.tag + 1 };
|
||||||
node->next = old_head;
|
if (ins_atomic_u128_eval_cond_assign(&list->head, &new_head, &old_head)) { break; }
|
||||||
void *swap = ins_atomic_ptr_eval_cond_assign(&list->head, tagged_node, old_head);
|
|
||||||
if (swap == old_head) { break; }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
lnk_reloc_refs_list_concat_in_place(LNK_RelocRefsList *list, LNK_RelocRefsNode *tagged_first, LNK_RelocRefsNode *tagged_last)
|
lnk_reloc_refs_list_concat_in_place(LNK_RelocRefsList *list, LNK_RelocRefsNode *first, LNK_RelocRefsNode *last)
|
||||||
{
|
{
|
||||||
tagged_first = BumpPointerTag(tagged_first);
|
LNK_RelocRefsPointer old_head = { .node = ins_atomic_ptr_eval(&list->head.node), .tag = ins_atomic_u64_eval(&list->head.tag) };
|
||||||
for (;;) {
|
for (;;) {
|
||||||
LNK_RelocRefsNode *old_head = list->head;
|
last->next = old_head.node;
|
||||||
LNK_RelocRefsNode *last = UnpackPointer(tagged_last);
|
LNK_RelocRefsPointer new_head = { .node = first, .tag = old_head.tag + 1 };
|
||||||
last->next = old_head;
|
if (ins_atomic_u128_eval_cond_assign(&list->head, &new_head, &old_head)) { break; }
|
||||||
void *swap = ins_atomic_ptr_eval_cond_assign(&list->head, tagged_first, old_head);
|
|
||||||
if (swap == old_head) { break;}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2257,11 +2243,10 @@ THREAD_POOL_TASK_FUNC(lnk_walk_relocs_and_mark_ref_sections_task)
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
// pop head node
|
// pop head node
|
||||||
LNK_RelocRefsNode *node = lnk_reloc_refs_list_pop_node_atomic(&task->reloc_refs);
|
LNK_RelocRefsNode *node = lnk_reloc_refs_list_pop_node_atomic(task->reloc_refs);
|
||||||
if (!node) { break; }
|
if (!node) { break; }
|
||||||
|
|
||||||
LNK_RelocRefsNode *reloc_refs_node = UnpackPointer(node);
|
LNK_RelocRefs *reloc_refs = node->v;
|
||||||
LNK_RelocRefs *reloc_refs = reloc_refs_node->v;
|
|
||||||
|
|
||||||
LNK_RelocRefsNode *first_node = 0, *last_node = 0;
|
LNK_RelocRefsNode *first_node = 0, *last_node = 0;
|
||||||
for EachIndex(reloc_idx, reloc_refs->relocs.count) {
|
for EachIndex(reloc_idx, reloc_refs->relocs.count) {
|
||||||
@@ -2330,25 +2315,23 @@ THREAD_POOL_TASK_FUNC(lnk_walk_relocs_and_mark_ref_sections_task)
|
|||||||
// mark section live
|
// mark section live
|
||||||
section_header->flags |= LNK_SECTION_FLAG_LIVE;
|
section_header->flags |= LNK_SECTION_FLAG_LIVE;
|
||||||
|
|
||||||
LNK_RelocRefsNode *tagged_node;
|
LNK_RelocRefsNode *node;
|
||||||
if (free_list.head) {
|
if (free_list.head.node) {
|
||||||
tagged_node = lnk_reloc_refs_list_pop_node(&free_list);
|
node = lnk_reloc_refs_list_pop_node(&free_list);
|
||||||
tagged_node = BumpPointerTag(tagged_node);
|
|
||||||
} else {
|
} else {
|
||||||
tagged_node = push_array(scratch.arena, LNK_RelocRefsNode, 1);
|
node = push_array(scratch.arena, LNK_RelocRefsNode, 1);
|
||||||
tagged_node->v = push_array(scratch.arena, LNK_RelocRefs, 1);
|
node->v = push_array(scratch.arena, LNK_RelocRefs, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
LNK_RelocRefsNode *node = UnpackPointer(tagged_node);
|
|
||||||
node->v->obj = ref_obj;
|
node->v->obj = ref_obj;
|
||||||
node->v->relocs = lnk_coff_reloc_info_from_section_number(ref_obj, section_number_n->data);
|
node->v->relocs = lnk_coff_reloc_info_from_section_number(ref_obj, section_number_n->data);
|
||||||
|
|
||||||
if (first_node == 0) {
|
if (first_node == 0) {
|
||||||
first_node = tagged_node;
|
first_node = node;
|
||||||
last_node = tagged_node;
|
last_node = node;
|
||||||
} else {
|
} else {
|
||||||
node->next = first_node;
|
node->next = first_node;
|
||||||
first_node = tagged_node;
|
first_node = node;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2357,18 +2340,18 @@ THREAD_POOL_TASK_FUNC(lnk_walk_relocs_and_mark_ref_sections_task)
|
|||||||
lnk_reloc_refs_list_push_node(&free_list, node);
|
lnk_reloc_refs_list_push_node(&free_list, node);
|
||||||
|
|
||||||
if (first_node && last_node) {
|
if (first_node && last_node) {
|
||||||
lnk_reloc_refs_list_concat_in_place(&task->reloc_refs, first_node, last_node);
|
lnk_reloc_refs_list_concat_in_place(task->reloc_refs, first_node, last_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// are all threads done walking?
|
// are all threads done walking?
|
||||||
U32 active_thread_count = ins_atomic_u32_dec_eval(&task->active_thread_count);
|
U32 active_thread_count = ins_atomic_u32_dec_eval(&task->active_thread_count);
|
||||||
if (active_thread_count == 0 && task->reloc_refs.head == 0) {
|
if (active_thread_count == 0 && ins_atomic_ptr_eval(&task->reloc_refs->head.node) == 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// comprehensive solution to the waiting problem
|
// comprehensive solution to the waiting problem
|
||||||
for (; ins_atomic_ptr_eval(&task->reloc_refs.head) == 0; ) {
|
for (; ins_atomic_ptr_eval(&task->reloc_refs->head.node) == 0; ) {
|
||||||
// was signaled to exit?
|
// was signaled to exit?
|
||||||
if (ins_atomic_u64_eval(&task->active_thread_count) == 0) { goto exit; }
|
if (ins_atomic_u64_eval(&task->active_thread_count) == 0) { goto exit; }
|
||||||
}
|
}
|
||||||
@@ -2455,7 +2438,7 @@ lnk_opt_ref(TP_Context *tp, LNK_SymbolTable *symtab, LNK_Config *config, LNK_Obj
|
|||||||
//
|
//
|
||||||
LNK_OptRefTask task = {0};
|
LNK_OptRefTask task = {0};
|
||||||
task.symtab = symtab;
|
task.symtab = symtab;
|
||||||
task.reloc_refs = reloc_refs;
|
task.reloc_refs = &reloc_refs;
|
||||||
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_walk_relocs_and_mark_ref_sections_task, &task, "Mark Live Sections");
|
tp_for_parallel_prof(tp, 0, tp->worker_count, lnk_walk_relocs_and_mark_ref_sections_task, &task, "Mark Live Sections");
|
||||||
|
|
||||||
ProfBegin("Remove Unreachable Sections");
|
ProfBegin("Remove Unreachable Sections");
|
||||||
|
|||||||
+12
-15
@@ -120,18 +120,6 @@ typedef struct LNK_CommonBlockContrib
|
|||||||
|
|
||||||
// --- Ref ---------------------------------------------------------------------
|
// --- Ref ---------------------------------------------------------------------
|
||||||
|
|
||||||
#define PointerBitSize 64u
|
|
||||||
#define PointerFreeBitsSize 16u
|
|
||||||
|
|
||||||
#define PointerTagBitSize PointerFreeBitsSize
|
|
||||||
#define PointerTagMask ((1ull << (PointerTagBitSize)) - 1u)
|
|
||||||
#define PointerTagShift (PointerBitSize - PointerTagBitSize)
|
|
||||||
|
|
||||||
#define PackPointer(ptr, tag) (void *)(IntFromPtr(ptr) | (((tag) & PointerTagMask) << PointerTagShift))
|
|
||||||
#define UnpackPointerTag(ptr) ((IntFromPtr(ptr) >> PointerTagShift) & PointerTagMask)
|
|
||||||
#define UnpackPointer(ptr) (void *)(IntFromPtr(ptr) & ~(PointerTagMask << PointerTagShift))
|
|
||||||
#define BumpPointerTag(ptr) PackPointer(UnpackPointer(ptr), UnpackPointerTag(ptr) + 1)
|
|
||||||
|
|
||||||
#define LNK_RELOCS_PER_TASK 0x1000
|
#define LNK_RELOCS_PER_TASK 0x1000
|
||||||
|
|
||||||
typedef struct LNK_RelocRefs
|
typedef struct LNK_RelocRefs
|
||||||
@@ -146,9 +134,18 @@ typedef struct LNK_RelocRefsNode
|
|||||||
struct LNK_RelocRefsNode *next;
|
struct LNK_RelocRefsNode *next;
|
||||||
} LNK_RelocRefsNode;
|
} LNK_RelocRefsNode;
|
||||||
|
|
||||||
typedef struct LNK_RelocRefsList
|
typedef union LNK_RelocRefsPointer
|
||||||
{
|
{
|
||||||
LNK_RelocRefsNode *head;
|
struct {
|
||||||
|
LNK_RelocRefsNode *node;
|
||||||
|
U64 tag;
|
||||||
|
};
|
||||||
|
U64 v[2];
|
||||||
|
} LNK_RelocRefsPointer;
|
||||||
|
|
||||||
|
typedef struct AlignType(16) LNK_RelocRefsList
|
||||||
|
{
|
||||||
|
LNK_RelocRefsPointer head;
|
||||||
} LNK_RelocRefsList;
|
} LNK_RelocRefsList;
|
||||||
|
|
||||||
// --- Base Reloc --------------------------------------------------------------
|
// --- Base Reloc --------------------------------------------------------------
|
||||||
@@ -193,7 +190,7 @@ typedef struct
|
|||||||
{
|
{
|
||||||
LNK_SymbolTable *symtab;
|
LNK_SymbolTable *symtab;
|
||||||
U32 active_thread_count;
|
U32 active_thread_count;
|
||||||
LNK_RelocRefsList reloc_refs;
|
LNK_RelocRefsList *reloc_refs;
|
||||||
} LNK_OptRefTask;
|
} LNK_OptRefTask;
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|||||||
Reference in New Issue
Block a user