diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lj_trace.c | 15 |
1 files changed, 4 insertions, 11 deletions
diff --git a/src/lj_trace.c b/src/lj_trace.c index 144461b3..0e948e8d 100644 --- a/src/lj_trace.c +++ b/src/lj_trace.c | |||
@@ -222,14 +222,6 @@ static void trace_unpatch(jit_State *J, GCtrace *T) | |||
222 | bc_isret(op), "bad original bytecode %d", op); | 222 | bc_isret(op), "bad original bytecode %d", op); |
223 | *pc = T->startins; | 223 | *pc = T->startins; |
224 | break; | 224 | break; |
225 | case BC_JMP: | ||
226 | lj_assertJ(op == BC_ITERL, "bad original bytecode %d", op); | ||
227 | pc += bc_j(*pc)+2; | ||
228 | if (bc_op(*pc) == BC_JITERL) { | ||
229 | lj_assertJ(traceref(J, bc_d(*pc)) == T, "JITERL references other trace"); | ||
230 | *pc = T->startins; | ||
231 | } | ||
232 | break; | ||
233 | case BC_JFUNCF: | 225 | case BC_JFUNCF: |
234 | lj_assertJ(op == BC_FUNCF, "bad original bytecode %d", op); | 226 | lj_assertJ(op == BC_FUNCF, "bad original bytecode %d", op); |
235 | *pc = T->startins; | 227 | *pc = T->startins; |
@@ -245,18 +237,19 @@ static void trace_flushroot(jit_State *J, GCtrace *T) | |||
245 | GCproto *pt = &gcref(T->startpt)->pt; | 237 | GCproto *pt = &gcref(T->startpt)->pt; |
246 | lj_assertJ(T->root == 0, "not a root trace"); | 238 | lj_assertJ(T->root == 0, "not a root trace"); |
247 | lj_assertJ(pt != NULL, "trace has no prototype"); | 239 | lj_assertJ(pt != NULL, "trace has no prototype"); |
248 | /* First unpatch any modified bytecode. */ | ||
249 | trace_unpatch(J, T); | ||
250 | /* Unlink root trace from chain anchored in prototype. */ | 240 | /* Unlink root trace from chain anchored in prototype. */ |
251 | if (pt->trace == T->traceno) { /* Trace is first in chain. Easy. */ | 241 | if (pt->trace == T->traceno) { /* Trace is first in chain. Easy. */ |
252 | pt->trace = T->nextroot; | 242 | pt->trace = T->nextroot; |
243 | unpatch: | ||
244 | /* Unpatch modified bytecode only if the trace has not been flushed. */ | ||
245 | trace_unpatch(J, T); | ||
253 | } else if (pt->trace) { /* Otherwise search in chain of root traces. */ | 246 | } else if (pt->trace) { /* Otherwise search in chain of root traces. */ |
254 | GCtrace *T2 = traceref(J, pt->trace); | 247 | GCtrace *T2 = traceref(J, pt->trace); |
255 | if (T2) { | 248 | if (T2) { |
256 | for (; T2->nextroot; T2 = traceref(J, T2->nextroot)) | 249 | for (; T2->nextroot; T2 = traceref(J, T2->nextroot)) |
257 | if (T2->nextroot == T->traceno) { | 250 | if (T2->nextroot == T->traceno) { |
258 | T2->nextroot = T->nextroot; /* Unlink from chain. */ | 251 | T2->nextroot = T->nextroot; /* Unlink from chain. */ |
259 | break; | 252 | goto unpatch; |
260 | } | 253 | } |
261 | } | 254 | } |
262 | } | 255 | } |