diff options
Diffstat (limited to '')
-rw-r--r-- | src/lj_asm_x86.h | 11 |
1 files changed, 9 insertions, 2 deletions
diff --git a/src/lj_asm_x86.h b/src/lj_asm_x86.h index 146371c1..4d1c85b3 100644 --- a/src/lj_asm_x86.h +++ b/src/lj_asm_x86.h | |||
@@ -3072,6 +3072,7 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) | |||
3072 | MSize len = T->szmcode; | 3072 | MSize len = T->szmcode; |
3073 | MCode *px = exitstub_addr(J, exitno) - 6; | 3073 | MCode *px = exitstub_addr(J, exitno) - 6; |
3074 | MCode *pe = p+len-6; | 3074 | MCode *pe = p+len-6; |
3075 | MCode *pgc = NULL; | ||
3075 | #if LJ_GC64 | 3076 | #if LJ_GC64 |
3076 | uint32_t statei = (uint32_t)(GG_OFS(g.vmstate) - GG_OFS(dispatch)); | 3077 | uint32_t statei = (uint32_t)(GG_OFS(g.vmstate) - GG_OFS(dispatch)); |
3077 | #else | 3078 | #else |
@@ -3086,9 +3087,15 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target) | |||
3086 | break; | 3087 | break; |
3087 | } | 3088 | } |
3088 | lj_assertJ(p < pe, "instruction length decoder failed"); | 3089 | lj_assertJ(p < pe, "instruction length decoder failed"); |
3089 | for (; p < pe; p += asm_x86_inslen(p)) | 3090 | for (; p < pe; p += asm_x86_inslen(p)) { |
3090 | if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px) | 3091 | if ((*(uint16_t *)p & 0xf0ff) == 0x800f && p + *(int32_t *)(p+2) == px && |
3092 | p != pgc) { | ||
3091 | *(int32_t *)(p+2) = jmprel(J, p+6, target); | 3093 | *(int32_t *)(p+2) = jmprel(J, p+6, target); |
3094 | } else if (*p == XI_CALL && | ||
3095 | (void *)(p+5+*(int32_t *)(p+1)) == (void *)lj_gc_step_jit) { | ||
3096 | pgc = p+7; /* Do not patch GC check exit. */ | ||
3097 | } | ||
3098 | } | ||
3092 | lj_mcode_sync(T->mcode, T->mcode + T->szmcode); | 3099 | lj_mcode_sync(T->mcode, T->mcode + T->szmcode); |
3093 | lj_mcode_patch(J, mcarea, 1); | 3100 | lj_mcode_patch(J, mcarea, 1); |
3094 | } | 3101 | } |