Skip to content

Commit

Permalink
Only compact objects when writing to disk
Browse files Browse the repository at this point in the history
  • Loading branch information
nickg committed Jan 25, 2025
1 parent a0a87f1 commit 53b2448
Show file tree
Hide file tree
Showing 17 changed files with 146 additions and 263 deletions.
2 changes: 1 addition & 1 deletion src/jit/jit-code.c
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ static void code_blob_print_value(text_buf_t *tb, jit_value_t value)
tb_printf(tb, "<%s:%d>", loc_file_str(&value.loc), value.loc.first_line);
break;
case JIT_VALUE_LOCUS:
tb_printf(tb, "%s%+d", istr(value.ident), value.disp);
tb_printf(tb, "%p", value.locus);
break;
case JIT_VALUE_VPOS:
tb_printf(tb, "%u:%u", value.vpos.block, value.vpos.op);
Expand Down
20 changes: 4 additions & 16 deletions src/jit/jit-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -470,8 +470,7 @@ void *jit_link(jit_t *j, jit_handle_t handle)
tlab_t tlab = jit_null_tlab(j);
jit_scalar_t p1 = { .pointer = NULL }, p2 = p1, result;
if (!jit_fastcall(j, f->handle, &result, p1, p2, &tlab)) {
object_t *obj = object_from_locus(f->module, f->offset, lib_load_handler);
error_at(&(obj->loc), "failed to initialise %s", istr(f->name));
error_at(&(f->object->loc), "failed to initialise %s", istr(f->name));
result.pointer = NULL;
}
else if (result.pointer == NULL)
Expand Down Expand Up @@ -578,10 +577,7 @@ jit_stack_trace_t *jit_stack_trace(void)
for (jit_anchor_t *a = thread->anchor; a; a = a->caller, frame++) {
jit_fill_irbuf(a->func);

frame->object = NULL;
if (a->func->module != NULL)
frame->object = object_from_locus(a->func->module, a->func->offset,
lib_load_handler);
frame->object = a->func->object;

// Scan backwards to find the last debug info
assert(a->irpos < a->func->nirs);
Expand Down Expand Up @@ -796,8 +792,7 @@ void *jit_call_thunk(jit_t *j, vcode_unit_t unit, void *context,
f->jit = j;
f->handle = JIT_HANDLE_INVALID;
f->entry = jit_interp;

vcode_unit_object(unit, &f->module, &f->offset);
f->object = vcode_unit_object(unit);

jit_irgen(f);

Expand Down Expand Up @@ -1020,8 +1015,7 @@ object_t *jit_get_object(jit_t *j, jit_handle_t handle)
{
jit_func_t *f = jit_get_func(j, handle);
jit_fill_irbuf(f);

return object_from_locus(f->module, f->offset, lib_load_handler);
return f->object;
}

bool jit_writes_flags(jit_ir_t *ir)
Expand Down Expand Up @@ -1391,12 +1385,6 @@ int32_t *jit_get_cover_ptr(jit_t *j, jit_value_t addr)
return base + addr.int64;
}

object_t *jit_get_locus(jit_value_t value)
{
assert(value.kind == JIT_VALUE_LOCUS);
return object_from_locus(value.ident, value.disp, lib_load_handler);
}

void jit_interrupt(jit_t *j, jit_irq_fn_t fn, void *ctx)
{
relaxed_store(&j->interrupt_ctx, ctx);
Expand Down
2 changes: 1 addition & 1 deletion src/jit/jit-dump.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ static int jit_dump_value(jit_dump_t *d, jit_value_t value)
return printf("<%s:%d>", loc_file_str(&value.loc), value.loc.first_line);
case JIT_VALUE_LOCUS:
{
object_t *obj = jit_get_locus(value);
object_t *obj = value.locus;
switch (obj->tag) {
case OBJECT_TAG_TREE:
return printf("%s@%p", tree_kind_str(obj->kind), obj);
Expand Down
2 changes: 1 addition & 1 deletion src/jit/jit-interp.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ static inline jit_scalar_t interp_get_scalar(jit_interp_t *state,
case JIT_VALUE_HANDLE:
return (jit_scalar_t){ .integer = value.handle };
case JIT_VALUE_LOCUS:
return (jit_scalar_t){ .pointer = jit_get_locus(value) };
return (jit_scalar_t){ .pointer = value.locus };
case JIT_ADDR_CPOOL:
JIT_ASSERT(value.int64 >= 0 && value.int64 <= state->func->cpoolsz);
return (jit_scalar_t){ .pointer = state->func->cpool + value.int64 };
Expand Down
9 changes: 2 additions & 7 deletions src/jit/jit-irgen.c
Original file line number Diff line number Diff line change
Expand Up @@ -1792,13 +1792,9 @@ static void irgen_op_store(jit_irgen_t *g, int op)

static void irgen_op_debug_locus(jit_irgen_t *g, int op)
{
ident_t unit = vcode_get_ident(op);
const ptrdiff_t offset = vcode_get_value(op);

g->map[vcode_get_result(op)] = (jit_value_t){
.kind = JIT_VALUE_LOCUS,
.disp = offset,
.ident = unit
.locus = vcode_get_object(op),
};
}

Expand Down Expand Up @@ -4471,8 +4467,7 @@ void jit_irgen(jit_func_t *f)

f->nregs = g->next_reg;
f->cpoolsz = g->cpoolptr;

vcode_unit_object(f->unit, &f->module, &f->offset);
f->object = vcode_unit_object(f->unit);

for (irgen_label_t *it = g->labels, *tmp; it; it = tmp) {
assert(it->label < g->func->nirs);
Expand Down
30 changes: 11 additions & 19 deletions src/jit/jit-llvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1118,34 +1118,26 @@ static LLVMValueRef cgen_load_from_reloc(llvm_obj_t *obj, cgen_func_t *func,

static LLVMValueRef cgen_rematerialise_object(llvm_obj_t *obj,
cgen_func_t *func,
ident_t unit, ptrdiff_t offset)
object_t *locus)
{
if (unit != func->source->module || offset < 0 || func->mode == CGEN_AOT) {
// Locus refers to another module that may not be loaded or the
// pointer is not stable
LLVMValueRef unit_str;
if (func->mode == CGEN_AOT) {
LOCAL_TEXT_BUF tb = tb_new();
tb_istr(tb, unit);
if (func->mode == CGEN_AOT) {
ident_t module;
ptrdiff_t offset;
object_locus(locus, &module, &offset);

object_fixup_locus(unit, &offset);
LOCAL_TEXT_BUF tb = tb_new();
tb_istr(tb, module);

unit_str = llvm_const_string(obj, tb_get(tb));
}
else
unit_str = llvm_ptr(obj, (void *)istr(unit));
LLVMValueRef unit_str = llvm_const_string(obj, tb_get(tb));

LLVMValueRef args[] = {
unit_str,
llvm_intptr(obj, offset),
};
return llvm_call_fn(obj, LLVM_GET_OBJECT, args, ARRAY_LEN(args));
}
else {
// Locus refers to the module containing the unit being compiled
// which is guaranteed to be loaded
return llvm_ptr(obj, object_from_locus(unit, offset, NULL));
}
else
return llvm_ptr(obj, locus);
}

static LLVMValueRef cgen_rematerialise_handle(llvm_obj_t *obj,
Expand Down Expand Up @@ -1234,7 +1226,7 @@ static LLVMValueRef cgen_get_value(llvm_obj_t *obj, cgen_block_t *cgb,
else
return llvm_ptr(obj, jit_get_cover_ptr(cgb->func->source->jit, value));
case JIT_VALUE_LOCUS:
return cgen_rematerialise_object(obj, cgb->func, value.ident, value.disp);
return cgen_rematerialise_object(obj, cgb->func, value.locus);
default:
fatal_trace("cannot handle value kind %d", value.kind);
}
Expand Down
33 changes: 22 additions & 11 deletions src/jit/jit-pack.c
Original file line number Diff line number Diff line change
Expand Up @@ -171,11 +171,13 @@ static void pack_handle(pack_writer_t *pw, jit_t *j, jit_handle_t handle)
pack_str(pw, istr(jit_get_func(j, handle)->name));
}

static void pack_locus(pack_writer_t *pw, ident_t unit, ptrdiff_t offset)
static void pack_locus(pack_writer_t *pw, object_t *obj)
{
object_fixup_locus(unit, &offset);
ident_t module;
ptrdiff_t offset;
object_locus(obj, &module, &offset);

pack_str(pw, istr(unit));
pack_str(pw, istr(module));
pack_uint(pw, offset);
}

Expand Down Expand Up @@ -225,7 +227,7 @@ static void pack_value(pack_writer_t *pw, jit_t *j, jit_value_t value)
pack_loc(pw, &(value.loc));
break;
case JIT_VALUE_LOCUS:
pack_locus(pw, value.ident, value.disp);
pack_locus(pw, value.locus);
break;
default:
fatal_trace("cannot handle value kind %d in pack_value", value.kind);
Expand All @@ -248,10 +250,12 @@ static void pack_func(pack_writer_t *pw, jit_t *j, jit_func_t *f)
pack_uint(pw, f->linktab[i].offset);
}

object_fixup_locus(f->module, &f->offset);
ident_t module;
ptrdiff_t offset;
object_locus(f->object, &module, &offset);

pack_str(pw, istr(f->module));
pack_uint(pw, f->offset);
pack_str(pw, istr(module));
pack_uint(pw, offset);

for (int i = 0; i < f->nirs; i++) {
jit_ir_t *ir = &(f->irbuf[i]);
Expand Down Expand Up @@ -459,6 +463,13 @@ static jit_handle_t unpack_handle(pack_func_t *pf, jit_t *j)
return jit_lazy_compile(j, ident_new(str));
}

static object_t *unpack_locus(pack_func_t *pf)
{
ident_t module = ident_new(unpack_str(pf));
ptrdiff_t disp = unpack_uint(pf);
return object_from_locus(module, disp, lib_load_handler);
}

static jit_value_t unpack_value(pack_func_t *pf, jit_t *j)
{
jit_value_t value;
Expand Down Expand Up @@ -500,8 +511,7 @@ static jit_value_t unpack_value(pack_func_t *pf, jit_t *j)
value.loc = unpack_loc(pf);
break;
case JIT_VALUE_LOCUS:
value.ident = ident_new(unpack_str(pf));
value.disp = unpack_uint(pf);
value.locus = unpack_locus(pf);
break;
default:
fatal_trace("cannot handle value kind %d in unpack_value", value.kind);
Expand Down Expand Up @@ -568,8 +578,9 @@ bool jit_pack_fill(jit_pack_t *jp, jit_t *j, jit_func_t *f)
}
}

f->module = ident_new(unpack_str(pf));
f->offset = unpack_uint(pf);
ident_t module = ident_new(unpack_str(pf));
ptrdiff_t offset = unpack_uint(pf);
f->object = object_from_locus(module, offset, lib_load_handler);

for (int i = 0; i < f->nirs; i++) {
jit_ir_t *ir = &(f->irbuf[i]);
Expand Down
6 changes: 2 additions & 4 deletions src/jit/jit-priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ typedef struct {
jit_exit_t exit;
loc_t loc;
jit_vpos_t vpos;
ident_t ident;
object_t *locus;
};
} jit_value_t;

Expand Down Expand Up @@ -308,8 +308,7 @@ typedef struct _jit_func {
jit_tier_t *next_tier;
jit_cfg_t *cfg;
ffi_spec_t spec;
ident_t module;
ptrdiff_t offset;
object_t *object;
} jit_func_t;

// The code generator knows the layout of this struct
Expand Down Expand Up @@ -380,7 +379,6 @@ void jit_tier_up(jit_func_t *f);
jit_thread_local_t *jit_thread_local(void);
void jit_fill_irbuf(jit_func_t *f);
int32_t *jit_get_cover_ptr(jit_t *j, jit_value_t addr);
object_t *jit_get_locus(jit_value_t value);
jit_entry_fn_t jit_bind_intrinsic(ident_t name);
jit_thread_local_t *jit_attach_thread(jit_anchor_t *anchor);

Expand Down
4 changes: 2 additions & 2 deletions src/jit/jit-x86.c
Original file line number Diff line number Diff line change
Expand Up @@ -1266,7 +1266,7 @@ static void jit_x86_get_copy(code_blob_t *blob, x86_operand_t dst,
MOV(dst, __EAX, __QWORD);
break;
case JIT_VALUE_LOCUS:
MOV(dst, PTR(jit_get_locus(src)), __QWORD);
MOV(dst, PTR(src.locus), __QWORD);
break;
case JIT_ADDR_REG:
if (src.disp == 0)
Expand Down Expand Up @@ -1314,7 +1314,7 @@ static x86_operand_t jit_x86_get(code_blob_t *blob, x86_operand_t tmp,
MOV(tmp, IMM(src.int64), __QWORD);
return tmp;
case JIT_VALUE_LOCUS:
MOV(tmp, PTR(jit_get_locus(src)), __QWORD);
MOV(tmp, PTR(src.locus), __QWORD);
return tmp;
case JIT_ADDR_REG:
jit_x86_get_copy(blob, tmp, src, slots);
Expand Down
44 changes: 13 additions & 31 deletions src/lower.c
Original file line number Diff line number Diff line change
Expand Up @@ -775,11 +775,7 @@ static vcode_type_t lower_signal_type(type_t type)

static vcode_reg_t lower_debug_locus(tree_t t)
{
ident_t unit;
ptrdiff_t offset;
tree_locus(t, &unit, &offset);

return emit_debug_locus(unit, offset);
return emit_debug_locus(tree_to_object(t));
}

static vcode_reg_t lower_wrap_with_new_bounds(lower_unit_t *lu,
Expand Down Expand Up @@ -13330,12 +13326,11 @@ typedef struct _unit_registry {
} unit_registry_t;

typedef struct {
lower_unit_t *parent;
emit_fn_t emit_fn;
lower_fn_t fn;
ident_t arena;
ptrdiff_t offset;
cover_data_t *cover;
lower_unit_t *parent;
emit_fn_t emit_fn;
lower_fn_t fn;
object_t *object;
cover_data_t *cover;
} deferred_unit_t;

unit_registry_t *unit_registry_new(void)
Expand Down Expand Up @@ -13443,7 +13438,7 @@ static void walk_dependency_cb(ident_t name, void *ctx)
case UNIT_DEFERRED:
{
deferred_unit_t *du = untag_pointer(ptr, deferred_unit_t);
if (du->offset >= 0)
if (arena_frozen(object_arena(du->object)))
return;

vu = unit_registry_get(ur, name);
Expand All @@ -13462,11 +13457,7 @@ static void walk_dependency_cb(ident_t name, void *ctx)
fatal_trace("invalid tagged pointer %p", ptr);
}

ident_t module;
ptrdiff_t offset;
vcode_unit_object(vu, &module, &offset);

if (offset >= 0)
if (arena_frozen(object_arena(vcode_unit_object(vu))))
return;

vcode_walk_dependencies(vu, walk_dependency_cb, ur);
Expand Down Expand Up @@ -13550,21 +13541,15 @@ vcode_unit_t unit_registry_get(unit_registry_t *ur, ident_t ident)
vcode_state_t state;
vcode_state_save(&state);

object_t *obj = object_from_locus(du->arena, du->offset,
lib_load_handler);

// This assertion fails in unit tests
// assert(du->offset >= 0 || !arena_frozen(object_arena(obj)));

vcode_unit_t context = du->parent ? du->parent->vunit : NULL;
vcode_unit_t vu = (*du->emit_fn)(ident, obj, context);
tree_t container = tree_from_object(obj);
vcode_unit_t vu = (*du->emit_fn)(ident, du->object, context);
tree_t container = tree_from_object(du->object);
lower_unit_t *lu = lower_unit_new(ur, du->parent, vu,
du->cover, container);

hash_put(ur->map, ident, tag_pointer(lu, UNIT_GENERATED));

(*du->fn)(lu, obj);
(*du->fn)(lu, du->object);

for (lower_unit_t *p = du->parent; p; p = p->parent) {
assert(p->deferred > 0);
Expand Down Expand Up @@ -13637,12 +13622,11 @@ void unit_registry_defer(unit_registry_t *ur, ident_t ident,
du->fn = fn;
du->parent = parent;
du->cover = cover;
du->object = object;

for (lower_unit_t *p = du->parent; p; p = p->parent)
p->deferred++;

object_locus(object, &du->arena, &du->offset);

hash_put(ur->map, ident, tag_pointer(du, UNIT_DEFERRED));
}
#ifdef DEBUG
Expand All @@ -13651,9 +13635,7 @@ void unit_registry_defer(unit_registry_t *ur, ident_t ident,
assert(du->emit_fn == emit_fn);
assert(du->fn == fn);
assert(du->cover == cover);

object_t *o = object_from_locus(du->arena, du->offset, lib_load_handler);
assert(o == object);
assert(du->object == object);
}
#endif
}
Loading

0 comments on commit 53b2448

Please sign in to comment.