aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar zinc <zinc@downsta.ir> 2026-10-15 06:15:36 +0330
committerGravatar zinc <zinc@downsta.ir> 2026-10-15 06:15:36 +0330
commit1db57f77e9c627bc9c00f9e2f827aa72b425b739 (patch)
tree63f72669aaab2b942ec03db1db9d2e69520eb6d5 /src
parenttodo: overnight prover/rcall/alloc status (diff)
find_replace: cover o3 function prologues on every backend
arm64, llvm and the region-interpreter rdrop path now watch the two prologue words the way the x86-64 jit already did, so icon.replace_function's lit+jmp patch retires a compiled callee (and clears fn_nat) instead of leaving a stale stub. three new icon regressions: repeated o3 replace, failed publication keeps the old entry, and a direct call after warming the region.
Diffstat (limited to 'src')
-rw-r--r--src/core/core.c51
1 files changed, 44 insertions, 7 deletions
diff --git a/src/core/core.c b/src/core/core.c
index 748c508..3133c55 100644
--- a/src/core/core.c
+++ b/src/core/core.c
@@ -4000,8 +4000,21 @@ static void rforget(Rg *R)
if ((unsigned)R->fn < (unsigned)code_words) fn_nat[R->fn].stub = 0;
R->nat = 0;
}
-static void rmark(Rg *R) { R->marked = 1; cinc(cov, R->lo, R->hi); }
-static void runmark(Rg *R) { cdec(cov, R->lo, R->hi); }
+static void rmark(Rg *R)
+{
+ R->marked = 1; cinc(cov, R->lo, R->hi);
+ /* cover the function prologue: icon.replace_function patches it with lit+jmp */
+ if ((unsigned)R->fn < (unsigned)code_words) {
+ cinc(cov, R->fn, R->fn + 2);
+ tab[R->fn] = 0;
+ if ((unsigned)(R->fn + 1) < (unsigned)code_words) tab[R->fn + 1] = 0;
+ }
+}
+static void runmark(Rg *R)
+{
+ cdec(cov, R->lo, R->hi);
+ if ((unsigned)R->fn < (unsigned)code_words) cdec(cov, R->fn, R->fn + 2);
+}
static int ralloc(Rg *R, RB *B)
{
int i, j, k, n = B->n;
@@ -5232,7 +5245,11 @@ static int rdrop(int a) /* a store landed on region code: drop those regions */
{
int j, hit = 0;
for (j = 0; j < nrg; j++)
- if (rgs[j]->lifted && rgs[j]->lo <= a && a < rgs[j]->hi) {
+ if (rgs[j]->lifted && ((rgs[j]->lo <= a && a < rgs[j]->hi) ||
+ ((unsigned)rgs[j]->fn < (unsigned)code_words && a >= rgs[j]->fn && a < rgs[j]->fn + 2))) {
+ /* prologue patch (icon.replace_function) retires the region; a body store only clears it */
+ if ((unsigned)rgs[j]->fn < (unsigned)code_words && a >= rgs[j]->fn && a < rgs[j]->fn + 2)
+ rgs[j]->dead = 1;
if (trace) fprintf(stderr, "o3: dropped %d..%d (a store to %d: %d)\n", rgs[j]->lo, rgs[j]->hi - 1, a, m[a]);
rclear(rgs[j]); hit = 1;
}
@@ -5346,8 +5363,16 @@ static void runmark(Rg *R)
}
#else
static void rforget(Rg *R) { (void)R; }
-static void rmark(Rg *R) { R->marked = 1; cinc(rcov, R->lo, R->hi); }
-static void runmark(Rg *R) { cdec(rcov, R->lo, R->hi); }
+static void rmark(Rg *R)
+{
+ R->marked = 1; cinc(rcov, R->lo, R->hi);
+ if ((unsigned)R->fn < (unsigned)code_words) cinc(rcov, R->fn, R->fn + 2);
+}
+static void runmark(Rg *R)
+{
+ cdec(rcov, R->lo, R->hi);
+ if ((unsigned)R->fn < (unsigned)code_words) cdec(rcov, R->fn, R->fn + 2);
+}
static void rcompile(Rg *R, int eager) { (void)R; (void)eager; }
#endif
#endif
@@ -5359,8 +5384,20 @@ static void rcompile(Rg *R, int eager) { (void)R; (void)eager; }
typedef Cell (*RFn)(Cell *mem, Cell *regs, int ent);
static VM_TLS int nregions;
static void rforget(Rg *R) { rt_queue(R->rt); R->rt = 0; R->nat = 0; R->dnat = 0; }
-static void rmark(Rg *R) { R->marked = 1; cinc(rcov, R->lo, R->hi); cinc(lcov, R->lo, R->hi); }
-static void runmark(Rg *R) { cdec(rcov, R->lo, R->hi); cdec(lcov, R->lo, R->hi); }
+static void rmark(Rg *R)
+{
+ R->marked = 1; cinc(rcov, R->lo, R->hi); cinc(lcov, R->lo, R->hi);
+ if ((unsigned)R->fn < (unsigned)code_words) {
+ cinc(rcov, R->fn, R->fn + 2); cinc(lcov, R->fn, R->fn + 2);
+ }
+}
+static void runmark(Rg *R)
+{
+ cdec(rcov, R->lo, R->hi); cdec(lcov, R->lo, R->hi);
+ if ((unsigned)R->fn < (unsigned)code_words) {
+ cdec(rcov, R->fn, R->fn + 2); cdec(lcov, R->fn, R->fn + 2);
+ }
+}
static LLVMValueRef as_f64(LLVMValueRef v, int fp) { return fp ? v : LLVMBuildBitCast(bd, v, f64t, ""); }
static LLVMValueRef as_i64(LLVMValueRef v, int fp) { return fp ? LLVMBuildBitCast(bd, v, i64t, "") : v; }
/* the variables go back to their frame slots. before a call from inside the