Merge branch 'master' into v2.1
This commit is contained in:
@@ -2067,6 +2067,9 @@ static void asm_stack_restore(ASMState *as, SnapShot *snap)
|
||||
|
||||
/* -- GC handling --------------------------------------------------------- */
|
||||
|
||||
/* Marker to prevent patching the GC check exit. */
|
||||
#define PPC_NOPATCH_GC_CHECK PPCI_ORIS
|
||||
|
||||
/* Check GC threshold and do one or more GC steps. */
|
||||
static void asm_gc_check(ASMState *as)
|
||||
{
|
||||
@@ -2078,6 +2081,7 @@ static void asm_gc_check(ASMState *as)
|
||||
l_end = emit_label(as);
|
||||
/* Exit trace if in GCSatomic or GCSfinalize. Avoids syncing GC objects. */
|
||||
asm_guardcc(as, CC_NE); /* Assumes asm_snap_prep() already done. */
|
||||
*--as->mcp = PPC_NOPATCH_GC_CHECK;
|
||||
emit_ai(as, PPCI_CMPWI, RID_RET, 0);
|
||||
args[0] = ASMREF_TMP1; /* global_State *g */
|
||||
args[1] = ASMREF_TMP2; /* MSize steps */
|
||||
@@ -2217,7 +2221,7 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
|
||||
MCode *px = exitstub_trace_addr(T, exitno);
|
||||
MCode *cstart = NULL;
|
||||
MCode *mcarea = lj_mcode_patch(J, p, 0);
|
||||
int clearso = 0;
|
||||
int clearso = 0, patchlong = 1;
|
||||
for (; p < pe; p++) {
|
||||
/* Look for exitstub branch, try to replace with branch to target. */
|
||||
uint32_t ins = *p;
|
||||
@@ -2229,7 +2233,9 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
|
||||
delta -= sizeof(MCode);
|
||||
}
|
||||
/* Many, but not all short-range branches can be patched directly. */
|
||||
if (((delta + 0x8000) >> 16) == 0) {
|
||||
if (p[-1] == PPC_NOPATCH_GC_CHECK) {
|
||||
patchlong = 0;
|
||||
} else if (((delta + 0x8000) >> 16) == 0) {
|
||||
*p = (ins & 0xffdf0000u) | ((uint32_t)delta & 0xffffu) |
|
||||
((delta & 0x8000) * (PPCF_Y/0x8000));
|
||||
if (!cstart) cstart = p;
|
||||
@@ -2243,7 +2249,8 @@ void lj_asm_patchexit(jit_State *J, GCtrace *T, ExitNo exitno, MCode *target)
|
||||
if (!cstart) cstart = p;
|
||||
}
|
||||
}
|
||||
{ /* Always patch long-range branch in exit stub itself. */
|
||||
/* Always patch long-range branch in exit stub itself. Except, if we can't. */
|
||||
if (patchlong) {
|
||||
ptrdiff_t delta = (char *)target - (char *)px - clearso;
|
||||
lj_assertJ(((delta + 0x02000000) >> 26) == 0,
|
||||
"branch target out of range");
|
||||
|
||||
Reference in New Issue
Block a user