diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/core.c | 51 |
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 |
