mcode to mach

This commit is contained in:
2026-02-12 05:23:33 -06:00
parent 3a8a17ab60
commit e7a2f16004
9 changed files with 11 additions and 26 deletions

View File

@@ -2224,7 +2224,6 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
cJSON *nr_slots_j = cJSON_GetObjectItemCaseSensitive(fobj, "nr_slots");
int nr_slots = (int)cJSON_GetNumberValue(nr_slots_j);
*out_old_nr_slots = nr_slots;
return NULL; /* TEMP: disable compression to test */
if (nr_slots <= 255) return NULL;
int nr_args = (int)cJSON_GetNumberValue(
@@ -2237,8 +2236,9 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
int *last_ref = sys_malloc(nr_slots * sizeof(int));
for (int i = 0; i < nr_slots; i++) { first_ref[i] = -1; last_ref[i] = -1; }
/* Args are live for the whole function */
for (int i = 0; i < nr_args; i++) { first_ref[i] = 0; last_ref[i] = n; }
/* this + args are live for the whole function */
int pinned = 1 + nr_args;
for (int i = 0; i < pinned; i++) { first_ref[i] = 0; last_ref[i] = n; }
for (int i = 0; i < n; i++) {
cJSON *it = cJSON_GetArrayItem(instrs, i);
@@ -2310,7 +2310,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
/* Backward jump: extend registers that are live INTO the loop
(first_ref < loop start but used inside). Temporaries born
inside the loop body don't need extension — they are per-iteration. */
for (int s = nr_args; s < nr_slots; s++) {
for (int s = pinned; s < nr_slots; s++) {
if (first_ref[s] < 0) continue;
if (first_ref[s] >= tpos) continue; /* born inside loop — skip */
if (last_ref[s] < tpos) continue; /* dead before loop — skip */
@@ -2326,7 +2326,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
typedef struct { int slot, first, last; } SlotInfo;
int cnt = 0;
SlotInfo *sorted = sys_malloc(nr_slots * sizeof(SlotInfo));
for (int s = nr_args; s < nr_slots; s++)
for (int s = pinned; s < nr_slots; s++)
if (first_ref[s] >= 0)
sorted[cnt++] = (SlotInfo){s, first_ref[s], last_ref[s]};
@@ -2348,7 +2348,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
/* Free-register pool (min-heap would be ideal but a flat scan is fine) */
int *pool = sys_malloc(nr_slots * sizeof(int));
int pool_n = 0;
int next_phys = nr_args;
int next_phys = pinned;
typedef struct { int phys, last; } ActiveAlloc;
ActiveAlloc *active = sys_malloc(cnt * sizeof(ActiveAlloc));
@@ -2381,7 +2381,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
}
/* Compute new nr_slots */
int new_max = nr_args;
int new_max = pinned;
for (int s = 0; s < nr_slots; s++)
if (first_ref[s] >= 0 && remap[s] >= new_max)
new_max = remap[s] + 1;
@@ -2391,7 +2391,7 @@ static int *mcode_compress_regs(cJSON *fobj, int *out_old_nr_slots,
fprintf(stderr, " WARNING: %d live regs still exceeds 255\n", new_max);
/* Verify: check no two registers with overlapping live ranges share phys */
for (int a = nr_args; a < nr_slots; a++) {
for (int a = pinned; a < nr_slots; a++) {
if (first_ref[a] < 0) continue;
for (int b = a + 1; b < nr_slots; b++) {
if (first_ref[b] < 0) continue;
@@ -2846,9 +2846,9 @@ void verify_getup(MachCode *mc, const char *path) {
MachInstr32 instr = mc->instructions[i];
if (MACH_GET_OP(instr) == MACH_GETUP) {
int depth = MACH_GET_B(instr);
if (depth > 2)
fprintf(stderr, "VERIFY: bad GETUP at %s[%d]: depth=%d slot=%d dest=%d instr=0x%08x nr_slots=%d\n",
path, i, depth, MACH_GET_C(instr), MACH_GET_A(instr), instr, mc->nr_slots);
if (depth > 10)
fprintf(stderr, "VERIFY: suspicious GETUP at %s[%d]: depth=%d slot=%d dest=%d\n",
path, i, depth, MACH_GET_C(instr), MACH_GET_A(instr));
}
}
for (uint32_t i = 0; i < mc->func_count; i++) {
@@ -3309,16 +3309,6 @@ JSValue JS_RunMachBin(JSContext *ctx, const uint8_t *data, size_t size, JSValue
if (!mc)
return JS_ThrowSyntaxError(ctx, "failed to deserialize MACH bytecode");
fprintf(stderr, "DEBUG RunMachBin: mc=%p instr_count=%d cpool_count=%d func_count=%d nr_slots=%d\n",
(void*)mc, mc->instr_count, mc->cpool_count, mc->func_count, mc->nr_slots);
verify_getup(mc, "DESER_BOOT");
if (mc->instr_count > 0) {
fprintf(stderr, "DEBUG first 5 instrs:");
for (uint32_t i = 0; i < 5 && i < mc->instr_count; i++)
fprintf(stderr, " 0x%08x", mc->instructions[i]);
fprintf(stderr, "\n");
}
JSGCRef env_ref;
JS_PushGCRef(ctx, &env_ref);
env_ref.val = env;
@@ -3326,9 +3316,6 @@ JSValue JS_RunMachBin(JSContext *ctx, const uint8_t *data, size_t size, JSValue
JSCodeRegister *code = JS_LoadMachCode(ctx, mc, env_ref.val);
JS_FreeMachCode(mc);
fprintf(stderr, "DEBUG LoadMachCode: code=%p instr_count=%d cpool_count=%d func_count=%d\n",
(void*)code, code->instr_count, code->cpool_count, code->func_count);
JSValue result = JS_CallRegisterVM(ctx, code, ctx->global_obj, 0, NULL, env_ref.val, JS_NULL);
JS_PopGCRef(ctx, &env_ref);
return result;