mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge again
This commit is contained in:
commit
b9bf10f53c
@ -424,6 +424,7 @@ js_CallTree(InterpState* state, Fragment* f)
|
||||
{
|
||||
union { NIns *code; GuardRecord* (FASTCALL *func)(InterpState*, Fragment*); } u;
|
||||
u.code = f->code();
|
||||
JS_ASSERT(u.code);
|
||||
return u.func(state, NULL);
|
||||
}
|
||||
|
||||
|
@ -79,9 +79,6 @@
|
||||
/* Max number of type mismatchs before we trash the tree. */
|
||||
#define MAX_MISMATCH 5
|
||||
|
||||
/* Max number of loop edges to follow. */
|
||||
#define MAX_OUTERLINE 0
|
||||
|
||||
/* Max native stack size. */
|
||||
#define MAX_NATIVE_STACK_SLOTS 1024
|
||||
|
||||
@ -660,6 +657,9 @@ mergeTypeMaps(uint8** partial, unsigned* plength, uint8* complete, unsigned clen
|
||||
*plength = clength;
|
||||
}
|
||||
|
||||
static void
|
||||
js_TrashTree(JSContext* cx, Fragment* f);
|
||||
|
||||
TraceRecorder::TraceRecorder(JSContext* cx, GuardRecord* _anchor, Fragment* _fragment,
|
||||
TreeInfo* ti, unsigned ngslots, uint8* globalTypeMap, uint8* stackTypeMap,
|
||||
GuardRecord* innermostNestedGuard)
|
||||
@ -677,7 +677,8 @@ TraceRecorder::TraceRecorder(JSContext* cx, GuardRecord* _anchor, Fragment* _fra
|
||||
this->loopEdgeCount = 0;
|
||||
JS_ASSERT(!_anchor || _anchor->calldepth == _fragment->calldepth);
|
||||
this->atoms = cx->fp->script->atomMap.vector;
|
||||
|
||||
this->trashTree = false;
|
||||
this->lastLoopEdge = NULL;
|
||||
|
||||
debug_only_v(printf("recording starting from %s:%u@%u\n", cx->fp->script->filename,
|
||||
js_PCToLineNumber(cx, cx->fp->script, cx->fp->regs->pc),
|
||||
@ -723,6 +724,8 @@ TraceRecorder::~TraceRecorder()
|
||||
JS_ASSERT(!fragment->root->vmprivate);
|
||||
delete treeInfo;
|
||||
}
|
||||
if (trashTree)
|
||||
js_TrashTree(cx, fragment->root);
|
||||
#ifdef DEBUG
|
||||
delete verbose_filter;
|
||||
#endif
|
||||
@ -750,11 +753,15 @@ TraceRecorder::getCallDepth() const
|
||||
}
|
||||
|
||||
|
||||
/* Determine whether we should outerline along a loop edge. */
|
||||
/* Determine whether we should unroll a loop (only do so at most once for every loop). */
|
||||
bool
|
||||
TraceRecorder::trackLoopEdges()
|
||||
{
|
||||
return loopEdgeCount++ < MAX_OUTERLINE;
|
||||
jsbytecode* pc = cx->fp->regs->pc;
|
||||
if (pc == lastLoopEdge)
|
||||
return false;
|
||||
lastLoopEdge = pc;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Determine the offset in the native global frame for a jsval we track */
|
||||
@ -1300,9 +1307,6 @@ struct FrameInfo {
|
||||
};
|
||||
};
|
||||
|
||||
static void
|
||||
js_TrashTree(JSContext* cx, Fragment* f);
|
||||
|
||||
/* Promote slots if necessary to match the called tree' type map and report error if thats
|
||||
impossible. */
|
||||
bool
|
||||
@ -1339,8 +1343,9 @@ TraceRecorder::adjustCallerTypes(Fragment* f)
|
||||
}
|
||||
++m;
|
||||
);
|
||||
JS_ASSERT(f == f->root);
|
||||
if (!ok)
|
||||
js_TrashTree(cx, f);
|
||||
trashTree = true;
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -1493,8 +1498,8 @@ TraceRecorder::verifyTypeStability()
|
||||
}
|
||||
++m
|
||||
);
|
||||
if (recompile)
|
||||
js_TrashTree(cx, fragment);
|
||||
if (recompile)
|
||||
trashTree = true;
|
||||
return !recompile;
|
||||
}
|
||||
|
||||
@ -1624,6 +1629,8 @@ TraceRecorder::emitTreeCall(Fragment* inner, GuardRecord* lr)
|
||||
/* Guard that we come out of the inner tree along the same side exit we came out when
|
||||
we called the inner tree at recording time. */
|
||||
guard(true, lir->ins2(LIR_eq, ret, lir->insImmPtr(lr)), NESTED_EXIT);
|
||||
/* Register us as a dependent tree of the inner tree. */
|
||||
((TreeInfo*)inner->vmprivate)->dependentTrees.addUnique(fragment->root);
|
||||
}
|
||||
|
||||
int
|
||||
@ -1713,14 +1720,21 @@ static void
|
||||
js_TrashTree(JSContext* cx, Fragment* f)
|
||||
{
|
||||
JS_ASSERT((!f->code()) == (!f->vmprivate));
|
||||
JS_ASSERT(f == f->root);
|
||||
if (!f->code())
|
||||
return;
|
||||
AUDIT(treesTrashed);
|
||||
debug_only_v(printf("Trashing tree info.\n");)
|
||||
Fragmento* fragmento = JS_TRACE_MONITOR(cx).fragmento;
|
||||
delete (TreeInfo*)f->vmprivate;
|
||||
TreeInfo* ti = (TreeInfo*)f->vmprivate;
|
||||
f->vmprivate = NULL;
|
||||
f->releaseCode(fragmento);
|
||||
Fragment** data = ti->dependentTrees.data();
|
||||
unsigned length = ti->dependentTrees.length();
|
||||
for (unsigned n = 0; n < length; ++n)
|
||||
js_TrashTree(cx, data[n]);
|
||||
delete ti;
|
||||
JS_ASSERT(!f->code() && !f->vmprivate);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
@ -2106,9 +2120,10 @@ js_ExecuteTree(JSContext* cx, Fragment** treep, uintN& inlineCallCount,
|
||||
JS_ASSERT(lr->guard->oprnd1()->oprnd2()->isconstp());
|
||||
lr = (GuardRecord*)lr->guard->oprnd1()->oprnd2()->constvalp();
|
||||
} while (lr->exit->exitType == NESTED_EXIT);
|
||||
|
||||
|
||||
/* We restored the nested frames, now we just need to deal with the innermost guard. */
|
||||
lr = state.nestedExit;
|
||||
JS_ASSERT(lr);
|
||||
}
|
||||
|
||||
/* sp_adj and ip_adj are relative to the tree we exit out of, not the tree we
|
||||
@ -3063,12 +3078,12 @@ TraceRecorder::box_jsval(jsval v, LIns*& v_ins)
|
||||
}
|
||||
switch (JSVAL_TAG(v)) {
|
||||
case JSVAL_BOOLEAN:
|
||||
v_ins = lir->ins2i(LIR_or, lir->ins2i(LIR_pilsh, v_ins, JSVAL_TAGBITS), JSVAL_BOOLEAN);
|
||||
v_ins = lir->ins2i(LIR_pior, lir->ins2i(LIR_pilsh, v_ins, JSVAL_TAGBITS), JSVAL_BOOLEAN);
|
||||
return true;
|
||||
case JSVAL_OBJECT:
|
||||
return true;
|
||||
case JSVAL_STRING:
|
||||
v_ins = lir->ins2(LIR_or, v_ins, INS_CONST(JSVAL_STRING));
|
||||
v_ins = lir->ins2(LIR_pior, v_ins, INS_CONST(JSVAL_STRING));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -3080,11 +3095,11 @@ TraceRecorder::unbox_jsval(jsval v, LIns*& v_ins)
|
||||
if (isNumber(v)) {
|
||||
// JSVAL_IS_NUMBER(v)
|
||||
guard(false,
|
||||
lir->ins_eq0(lir->ins2(LIR_or,
|
||||
lir->ins2(LIR_piand, v_ins, INS_CONSTPTR(JSVAL_INT)),
|
||||
lir->ins_eq0(lir->ins2(LIR_pior,
|
||||
lir->ins2(LIR_piand, v_ins, INS_CONST(JSVAL_INT)),
|
||||
lir->ins2i(LIR_eq,
|
||||
lir->ins2(LIR_piand, v_ins,
|
||||
INS_CONSTPTR(JSVAL_TAGMASK)),
|
||||
INS_CONST(JSVAL_TAGMASK)),
|
||||
JSVAL_DOUBLE))),
|
||||
MISMATCH_EXIT);
|
||||
v_ins = lir->insCall(F_UnboxDouble, &v_ins);
|
||||
@ -3094,7 +3109,7 @@ TraceRecorder::unbox_jsval(jsval v, LIns*& v_ins)
|
||||
case JSVAL_BOOLEAN:
|
||||
guard(true,
|
||||
lir->ins2i(LIR_eq,
|
||||
lir->ins2(LIR_piand, v_ins, INS_CONSTPTR(JSVAL_TAGMASK)),
|
||||
lir->ins2(LIR_piand, v_ins, INS_CONST(JSVAL_TAGMASK)),
|
||||
JSVAL_BOOLEAN),
|
||||
MISMATCH_EXIT);
|
||||
v_ins = lir->ins2i(LIR_ush, v_ins, JSVAL_TAGBITS);
|
||||
@ -3102,17 +3117,17 @@ TraceRecorder::unbox_jsval(jsval v, LIns*& v_ins)
|
||||
case JSVAL_OBJECT:
|
||||
guard(true,
|
||||
lir->ins2i(LIR_eq,
|
||||
lir->ins2(LIR_piand, v_ins, INS_CONSTPTR(JSVAL_TAGMASK)),
|
||||
lir->ins2(LIR_piand, v_ins, INS_CONST(JSVAL_TAGMASK)),
|
||||
JSVAL_OBJECT),
|
||||
MISMATCH_EXIT);
|
||||
return true;
|
||||
case JSVAL_STRING:
|
||||
guard(true,
|
||||
lir->ins2i(LIR_eq,
|
||||
lir->ins2(LIR_piand, v_ins, INS_CONSTPTR(JSVAL_TAGMASK)),
|
||||
lir->ins2(LIR_piand, v_ins, INS_CONST(JSVAL_TAGMASK)),
|
||||
JSVAL_STRING),
|
||||
MISMATCH_EXIT);
|
||||
v_ins = lir->ins2(LIR_piand, v_ins, INS_CONSTPTR(~JSVAL_TAGMASK));
|
||||
v_ins = lir->ins2(LIR_piand, v_ins, INS_CONST(~JSVAL_TAGMASK));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -3140,7 +3155,7 @@ TraceRecorder::guardClass(JSObject* obj, LIns* obj_ins, JSClass* clasp)
|
||||
return false;
|
||||
|
||||
LIns* class_ins = stobj_get_fslot(obj_ins, JSSLOT_CLASS);
|
||||
class_ins = lir->ins2(LIR_piand, class_ins, lir->insImmPtr((void*)~3));
|
||||
class_ins = lir->ins2(LIR_piand, class_ins, lir->insImm(~3));
|
||||
|
||||
char namebuf[32];
|
||||
JS_snprintf(namebuf, sizeof namebuf, "guard(class is %s)", clasp->name);
|
||||
|
@ -193,9 +193,10 @@ public:
|
||||
unsigned maxCallDepth;
|
||||
TypeMap stackTypeMap;
|
||||
unsigned mismatchCount;
|
||||
|
||||
Queue<nanojit::Fragment*> dependentTrees;
|
||||
|
||||
TreeInfo(nanojit::Fragment* _fragment) {
|
||||
fragment = _fragment;
|
||||
fragment = _fragment;
|
||||
}
|
||||
};
|
||||
|
||||
@ -228,6 +229,8 @@ class TraceRecorder {
|
||||
nanojit::LIns* rval_ins;
|
||||
nanojit::LIns* inner_sp_ins;
|
||||
nanojit::SideExit exit;
|
||||
bool trashTree;
|
||||
jsbytecode* lastLoopEdge;
|
||||
|
||||
bool isGlobal(jsval* p) const;
|
||||
ptrdiff_t nativeGlobalOffset(jsval* p) const;
|
||||
|
@ -1041,6 +1041,7 @@ namespace nanojit
|
||||
case LIR_qiadd:
|
||||
case LIR_qiand:
|
||||
case LIR_qilsh:
|
||||
case LIR_qior:
|
||||
{
|
||||
asm_qbinop(ins);
|
||||
break;
|
||||
|
@ -80,7 +80,7 @@ namespace nanojit
|
||||
/* 70-79 */ "70","71","72","73","74","stq","ldq","77","stqi","79",
|
||||
/* 80-89 */ "80","81","fcall","83","84","85","86","87","qiand","qiadd",
|
||||
/* 90-99 */ "90","91","92","93","qcmov","95","96","quad","98","99",
|
||||
/* 100-109 */ "fneg","fadd","fsub","fmul","fdiv","qjoin","i2f","u2f","108","qilsh",
|
||||
/* 100-109 */ "fneg","fadd","fsub","fmul","fdiv","qjoin","i2f","u2f","qior","qilsh",
|
||||
/* 110-119 */ "110","111","112","113","114","115","116","117","118","119",
|
||||
/* 120-127 */ "120","121","122","123","124","125","126","127"
|
||||
};
|
||||
@ -1656,6 +1656,7 @@ namespace nanojit
|
||||
case LIR_qiadd:
|
||||
case LIR_qiand:
|
||||
case LIR_qilsh:
|
||||
case LIR_qior:
|
||||
sprintf(s, "%s %s, %s", lirNames[op],
|
||||
formatRef(i->oprnd1()),
|
||||
formatRef(i->oprnd2()));
|
||||
|
@ -133,7 +133,8 @@ namespace nanojit
|
||||
|
||||
LIR_qjoin = 41 | LIR64,
|
||||
LIR_i2f = 42 | LIR64,
|
||||
LIR_u2f = 43 | LIR64
|
||||
LIR_u2f = 43 | LIR64,
|
||||
LIR_qior = 44 | LIR64
|
||||
};
|
||||
|
||||
#if defined NANOJIT_64BIT
|
||||
@ -142,12 +143,14 @@ namespace nanojit
|
||||
#define LIR_piand LIR_qiand
|
||||
#define LIR_pilsh LIR_qilsh
|
||||
#define LIR_pcmov LIR_qcmov
|
||||
#define LIR_pior LIR_qior
|
||||
#else
|
||||
#define LIR_ldp LIR_ld
|
||||
#define LIR_piadd LIR_add
|
||||
#define LIR_piand LIR_and
|
||||
#define LIR_pilsh LIR_lsh
|
||||
#define LIR_pcmov LIR_cmov
|
||||
#define LIR_pior LIR_or
|
||||
#endif
|
||||
|
||||
inline uint32_t argwords(uint32_t argc) {
|
||||
|
@ -175,9 +175,11 @@ namespace nanojit
|
||||
{ \
|
||||
NIns *tt = _nIns; \
|
||||
_nIns = pageAlloc(_inExit); \
|
||||
_pageData = 0; \
|
||||
_dblNegPtr = NULL; \
|
||||
_negOnePtr = NULL; \
|
||||
if (!_inExit) { \
|
||||
_pageData = 0; \
|
||||
_dblNegPtr = NULL; \
|
||||
_negOnePtr = NULL; \
|
||||
} \
|
||||
intptr_t d = tt-_nIns; \
|
||||
if (d <= INT_MAX && d >= INT_MIN) { \
|
||||
JMP_long_nochk_offset(d); \
|
||||
@ -185,9 +187,7 @@ namespace nanojit
|
||||
/* Insert a 64-bit jump... */ \
|
||||
_nIns -= 8; \
|
||||
*(intptr_t *)_nIns = intptr_t(tt); \
|
||||
IMM32(0); \
|
||||
*(_nIns--) = 0x25; \
|
||||
*(_nIns--) = 0xFF; \
|
||||
JMPm_nochk(0); \
|
||||
} \
|
||||
} \
|
||||
overrideProtect = _nIns; \
|
||||
@ -458,6 +458,12 @@ namespace nanojit
|
||||
} while(0)
|
||||
|
||||
|
||||
#define ORQ(l,r) do { \
|
||||
AMD64_PRIMQ(AMD64_OR_REG_RM, l, r); \
|
||||
asm_output2("or %s,%s",gpn(l),gpn(r)); \
|
||||
} while(0)
|
||||
|
||||
|
||||
#define SHRi(r,i) do { \
|
||||
if (i == 1) { \
|
||||
underrunProtect(3); \
|
||||
@ -487,6 +493,11 @@ namespace nanojit
|
||||
} while(0)
|
||||
|
||||
|
||||
#define ORQi(r,i) do { \
|
||||
AMD64_ALU(AMD64_OR_RAX, r, i, 1); \
|
||||
asm_output2("or %s,%d",gpn(r),i); \
|
||||
} while(0)
|
||||
|
||||
#define XORi(r,i) do { \
|
||||
AMD64_ALU(AMD64_XOR_RAX, r, i, 0); \
|
||||
asm_output2("xor %s,%d",gpn(r),i); \
|
||||
@ -852,23 +863,59 @@ namespace nanojit
|
||||
asm_output1("pop %s",gpn(r)); \
|
||||
} while(0)
|
||||
|
||||
#define JCC(o,t,n) do { \
|
||||
underrunProtect(6); \
|
||||
intptr_t tt = (intptr_t)t - (intptr_t)_nIns; \
|
||||
if (isS8(tt)) { \
|
||||
verbose_only( NIns* next = _nIns; (void)next; ) \
|
||||
_nIns -= 2; \
|
||||
_nIns[0] = (uint8_t) ( 0x70 | (o) ); \
|
||||
_nIns[1] = (uint8_t) (tt); \
|
||||
asm_output2("%s %lX",(n),(ptrdiff_t)(next+tt)); \
|
||||
} else { \
|
||||
verbose_only( NIns* next = _nIns; ) \
|
||||
IMM32(tt); \
|
||||
_nIns -= 2; \
|
||||
_nIns[0] = 0x0f; \
|
||||
_nIns[1] = (uint8_t) ( 0x80 | (o) ); \
|
||||
asm_output2("%s %lX",(n),(ptrdiff_t)(next+tt)); \
|
||||
} } while(0)
|
||||
#define JCC(o,t,n) do { \
|
||||
underrunProtect(6); \
|
||||
intptr_t tt = (intptr_t)t - (intptr_t)_nIns; \
|
||||
if (isS8(tt)) { \
|
||||
verbose_only( NIns* next = _nIns; (void)next; ) \
|
||||
_nIns -= 2; \
|
||||
_nIns[0] = (uint8_t) ( 0x70 | (o) ); \
|
||||
_nIns[1] = (uint8_t) (tt); \
|
||||
asm_output2("%s %lX",(n),(ptrdiff_t)(next+tt)); \
|
||||
} else if (tt <= INT_MAX && tt >= INT_MIN) { \
|
||||
verbose_only( NIns* next = _nIns; ) \
|
||||
IMM32(tt); \
|
||||
_nIns -= 2; \
|
||||
_nIns[0] = 0x0f; \
|
||||
_nIns[1] = (uint8_t) ( 0x80 | (o) ); \
|
||||
asm_output2("%s %lX",(n),(ptrdiff_t)(next+tt)); \
|
||||
} else { \
|
||||
underrunProtect(20); \
|
||||
NanoAssert(!_inExit); \
|
||||
/* We could now be in range, but assume we're not. */ \
|
||||
/* Note we generate the thunk forwards, and the */ \
|
||||
/* jcc to the thunk backwards. */ \
|
||||
uint8_t* base; \
|
||||
intptr_t offs; \
|
||||
base = (uint8_t *)((uintptr_t)_nIns & ~((uintptr_t)NJ_PAGE_SIZE-1)); \
|
||||
base += sizeof(PageHeader) + _pageData; \
|
||||
_pageData += 14; \
|
||||
*(base++) = 0xFF; \
|
||||
*(base++) = 0x25; \
|
||||
*(int *)base = 0; \
|
||||
base += 4; \
|
||||
*(intptr_t *)base = intptr_t(t); \
|
||||
offs = intptr_t(base-6) - intptr_t(_nIns); \
|
||||
NanoAssert(offs >= INT_MIN && offs <= INT_MAX); \
|
||||
if (isS8(offs)) { \
|
||||
_nIns -= 2; \
|
||||
_nIns[0] = uint8_t( 0x70 | (o) ); \
|
||||
_nIns[1] = uint8_t( (offs) ); \
|
||||
} else { \
|
||||
IMM32(offs); \
|
||||
_nIns -= 2; \
|
||||
_nIns[0] = 0x0f; \
|
||||
_nIns[1] = uint8_t( 0x80 | (o) ); \
|
||||
} \
|
||||
asm_output3("%s %d(rip) #%lX",n,offs,intptr_t(t)); \
|
||||
} \
|
||||
} while(0)
|
||||
|
||||
#define JMPm_nochk(rip) do { \
|
||||
IMM32(rip); \
|
||||
*(--_nIns) = 0x25; \
|
||||
*(--_nIns) = 0xFF; \
|
||||
} while (0)
|
||||
|
||||
#define JMP_long(t) do { \
|
||||
underrunProtect(5); \
|
||||
@ -876,17 +923,24 @@ namespace nanojit
|
||||
JMP_long_nochk_offset(tt); \
|
||||
} while(0)
|
||||
|
||||
#define JMP(t) do { \
|
||||
underrunProtect(5); \
|
||||
intptr_t tt = (intptr_t)t - (intptr_t)_nIns; \
|
||||
if (isS8(tt)) { \
|
||||
#define JMP(t) do { \
|
||||
underrunProtect(5); \
|
||||
intptr_t tt = (intptr_t)t - (intptr_t)_nIns; \
|
||||
if (isS8(tt)) { \
|
||||
verbose_only( NIns* next = _nIns; (void)next; ) \
|
||||
_nIns -= 2; \
|
||||
_nIns[0] = 0xeb; \
|
||||
_nIns[1] = (uint8_t) ( (tt)&0xff ); \
|
||||
asm_output1("jmp %lX",(ptrdiff_t)(next+tt)); \
|
||||
} else { \
|
||||
JMP_long_nochk_offset(tt); \
|
||||
_nIns -= 2; \
|
||||
_nIns[0] = 0xeb; \
|
||||
_nIns[1] = (uint8_t) ( (tt)&0xff ); \
|
||||
asm_output1("jmp %lX",(ptrdiff_t)(next+tt)); \
|
||||
} else { \
|
||||
if (tt >= INT_MIN && tt <= INT_MAX) { \
|
||||
JMP_long_nochk_offset(tt); \
|
||||
} else { \
|
||||
underrunProtect(14); \
|
||||
_nIns -= 8; \
|
||||
*(intptr_t *)_nIns = intptr_t(t); \
|
||||
JMPm_nochk(0); \
|
||||
} \
|
||||
} } while(0)
|
||||
|
||||
#define JMP_long_nochk(t) do { \
|
||||
@ -896,9 +950,11 @@ namespace nanojit
|
||||
|
||||
#define JMPc 0xe9
|
||||
|
||||
#define JMP_long_placeholder() do {\
|
||||
underrunProtect(5); \
|
||||
JMP_long_nochk_offset(-1); } while(0)
|
||||
#define JMP_long_placeholder() do { \
|
||||
underrunProtect(14); \
|
||||
IMM64(-1); \
|
||||
JMPm_nochk(0); \
|
||||
} while (0)
|
||||
|
||||
// this should only be used when you can guarantee there is enough room on the page
|
||||
#define JMP_long_nochk_offset(o) do {\
|
||||
@ -908,13 +964,11 @@ namespace nanojit
|
||||
*(--_nIns) = JMPc; \
|
||||
asm_output1("jmp %lX",(ptrdiff_t)(next+(o))); } while(0)
|
||||
|
||||
#if 0
|
||||
#define JMPr(r) do { \
|
||||
underrunProtect(2); \
|
||||
*(--_nIns) = AMD64_MODRM_REG(4, r); \
|
||||
*(--_nIns) = 0xFF; \
|
||||
} while (0)
|
||||
#endif
|
||||
|
||||
#define JE(t) JCC(0x04, t, "je")
|
||||
#define JNE(t) JCC(0x05, t, "jne")
|
||||
|
@ -173,8 +173,17 @@ namespace nanojit
|
||||
{
|
||||
// target doesn't exit yet. emit jump to epilog, and set up to patch later.
|
||||
lr = placeGuardRecord(guard);
|
||||
#if defined NANOJIT_AMD64
|
||||
/* 8 bytes for address, 4 for imm32, 2 for jmp */
|
||||
underrunProtect(14);
|
||||
_nIns -= 8;
|
||||
*(intptr_t *)_nIns = intptr_t(_epilogue);
|
||||
lr->jmp = _nIns;
|
||||
JMPm_nochk(0);
|
||||
#else
|
||||
JMP_long(_epilogue);
|
||||
lr->jmp = _nIns;
|
||||
#endif
|
||||
#if 0
|
||||
// @todo optimization ; is it worth it? It means we can remove the loop over outbound in Fragment.link()
|
||||
// for trees we need the patch entry on the incoming fragment so we can unhook it later if needed
|
||||
@ -363,11 +372,22 @@ namespace nanojit
|
||||
|
||||
void Assembler::nPatchBranch(NIns* branch, NIns* location)
|
||||
{
|
||||
uint32_t offset = location - branch;
|
||||
#if defined NANOJIT_IA32
|
||||
intptr_t offset = intptr_t(location) - intptr_t(branch);
|
||||
if (branch[0] == JMPc)
|
||||
*(uint32_t*)&branch[1] = offset - 5;
|
||||
else
|
||||
*(uint32_t*)&branch[2] = offset - 6;
|
||||
#else
|
||||
if (branch[0] == 0xFF && branch[1] == 0x25) {
|
||||
NIns *mem;
|
||||
|
||||
mem = &branch[6] + *(int32_t *)&branch[2];
|
||||
*(intptr_t *)mem = intptr_t(location);
|
||||
} else {
|
||||
NanoAssert(0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
RegisterMask Assembler::hint(LIns* i, RegisterMask allow)
|
||||
@ -1214,16 +1234,19 @@ namespace nanojit
|
||||
|
||||
NIns* Assembler::asm_adjustBranch(NIns* at, NIns* target)
|
||||
{
|
||||
NIns* was;
|
||||
#if defined NANOJIT_AMD64
|
||||
was = (NIns*)( *(intptr_t*)(at) );
|
||||
*(intptr_t *)(at) = intptr_t(target);
|
||||
#else
|
||||
NIns* save = _nIns;
|
||||
NIns* was = (NIns*)( (intptr_t)*(int32_t*)(at+1)+(intptr_t)(at+5) );
|
||||
was = (NIns*)( (intptr_t)*(int32_t*)(at+1)+(intptr_t)(at+5) );
|
||||
_nIns = at +5; // +5 is size of JMP
|
||||
intptr_t tt = (intptr_t)target - (intptr_t)_nIns;
|
||||
#if defined NANOJIT_AMD64
|
||||
NanoAssert(tt <= INT_MAX && tt >= INT_MIN);
|
||||
#endif
|
||||
IMM32(tt);
|
||||
*(--_nIns) = JMPc;
|
||||
_nIns = save;
|
||||
_nIns = save;
|
||||
#endif
|
||||
return was;
|
||||
}
|
||||
|
||||
@ -1281,6 +1304,8 @@ namespace nanojit
|
||||
ANDQi(rr, c);
|
||||
} else if (op == LIR_qilsh) {
|
||||
SHLQi(rr, c);
|
||||
} else if (op == LIR_qior) {
|
||||
ORQi(rr, c);
|
||||
}
|
||||
} else {
|
||||
Register rv;
|
||||
@ -1295,6 +1320,8 @@ namespace nanojit
|
||||
ADDQ(rr, rv);
|
||||
} else if (op == LIR_qiand) {
|
||||
ANDQ(rr, rv);
|
||||
} else if (op == LIR_qior) {
|
||||
ORQ(rr, rv);
|
||||
} else {
|
||||
NanoAssert(rhs->isconst());
|
||||
NanoAssert(false);
|
||||
|
Loading…
Reference in New Issue
Block a user