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 a5d7234
Show file tree
Hide file tree
Showing 18 changed files with 196 additions and 283 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
69 changes: 42 additions & 27 deletions src/jit/jit-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ typedef struct _jit {
unit_registry_t *registry;
} jit_t;

static void jit_transition(jit_t *j, jit_state_t from, jit_state_t to);

static void jit_oom_cb(mspace_t *m, size_t size)
{
diag_t *d = diag_new(DIAG_FATAL, NULL);
Expand Down Expand Up @@ -412,14 +414,19 @@ void jit_fill_irbuf(jit_func_t *f)
assert(f->irbuf == NULL);
assert(f->unit == NULL);

#ifndef USE_EMUTLS
const jit_state_t oldstate = jit_thread_local()->state;
jit_transition(f->jit, oldstate, JIT_COMPILING);
#endif

if (jit_fill_from_aot(f, f->jit->aotlib))
return;
goto done;

if (jit_fill_from_aot(f, f->jit->preloadlib))
return;
goto done;

if (f->jit->pack != NULL && jit_pack_fill(f->jit->pack, f->jit, f))
return;
goto done;

if (f->jit->registry != NULL) {
// Unit registry is not thread-safe
Expand All @@ -433,6 +440,11 @@ void jit_fill_irbuf(jit_func_t *f)
}

jit_irgen(f);

done:
#ifndef USE_EMUTLS
jit_transition(f->jit, JIT_COMPILING, oldstate);
#endif
}

jit_handle_t jit_compile(jit_t *j, ident_t name)
Expand Down Expand Up @@ -470,8 +482,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 @@ -576,16 +587,21 @@ jit_stack_trace_t *jit_stack_trace(void)

jit_frame_t *frame = stack->frames;
for (jit_anchor_t *a = thread->anchor; a; a = a->caller, frame++) {
frame->loc = LOC_INVALID;
frame->symbol = a->func->name;

#ifdef USE_EMUTLS
if (load_acquire(&a->func->state) == JIT_FUNC_COMPILING)
continue; // Cannot use jit_transition in jit_fill_irbuf
#endif

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;
frame->loc = frame->object->loc;

// Scan backwards to find the last debug info
assert(a->irpos < a->func->nirs);
frame->loc = frame->object ? frame->object->loc : LOC_INVALID;
for (jit_ir_t *ir = &(a->func->irbuf[a->irpos]);
ir >= a->func->irbuf; ir--) {
if (ir->op == J_DEBUG) {
Expand All @@ -595,8 +611,6 @@ jit_stack_trace_t *jit_stack_trace(void)
else if (ir->target)
break;
}

frame->symbol = a->func->name;
}

return stack;
Expand All @@ -610,8 +624,8 @@ static void jit_diag_cb(diag_t *d, void *arg)
diag_suppress(d, true);
return;
}
else if (unlikely(jit_thread_local()->state == JIT_IDLE))
fatal_trace("JIT diag callback called when idle");
else if (unlikely(jit_thread_local()->state != JIT_RUNNING))
fatal_trace("JIT diag callback called when not running");

jit_stack_trace_t *stack LOCAL = jit_stack_trace();

Expand All @@ -638,16 +652,24 @@ static void jit_transition(jit_t *j, jit_state_t from, jit_state_t to)

switch (to) {
case JIT_RUNNING:
if (from == JIT_IDLE) {
if (from != JIT_RUNNING) {
diag_add_hint_fn(jit_diag_cb, j);
thread->jit = j;
}
else
assert(thread->jit == j);
break;
case JIT_IDLE:
diag_remove_hint_fn(jit_diag_cb);
thread->jit = NULL;
if (from == JIT_RUNNING) {
diag_remove_hint_fn(jit_diag_cb);
thread->jit = NULL;
}
break;
case JIT_COMPILING:
if (from == JIT_RUNNING) {
diag_remove_hint_fn(jit_diag_cb);
thread->jit = NULL;
}
break;
}
}
Expand Down Expand Up @@ -796,8 +818,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 @@ -934,6 +955,7 @@ void jit_abort(void)

switch (thread->state) {
case JIT_IDLE:
case JIT_COMPILING:
fatal_exit(1);
break;
case JIT_RUNNING:
Expand Down Expand Up @@ -1020,8 +1042,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 +1412,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
9 changes: 4 additions & 5 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 All @@ -322,7 +321,8 @@ typedef struct _jit_anchor {

typedef enum {
JIT_IDLE,
JIT_RUNNING
JIT_RUNNING,
JIT_COMPILING,
} jit_state_t;

#if defined HAVE___BUILTIN_SETJMP && !defined __clang__
Expand Down Expand Up @@ -380,7 +380,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
Loading

0 comments on commit a5d7234

Please sign in to comment.