Implemented side exits in the x64 backend, and merged in tamarin-redux changes (bug 514537, r=gal).

This commit is contained in:
David Anderson 2009-09-03 19:12:47 -07:00
parent ea4545c24a
commit 19e6272d43
5 changed files with 94 additions and 7 deletions

View File

@ -41,6 +41,18 @@
#ifndef __nanojit_Native__
#define __nanojit_Native__
// define PEDANTIC=1 to ignore specialized forms, force general forms
// for everything, far branches, extra page-linking, etc. This will
// flush out many corner cases.
#define PEDANTIC 0
#if PEDANTIC
# define UNLESS_PEDANTIC(...)
# define IF_PEDANTIC(...) __VA_ARGS__
#else
# define UNLESS_PEDANTIC(...) __VA_ARGS__
# define IF_PEDANTIC(...)
#endif
#ifdef NANOJIT_IA32
#include "Nativei386.h"
@ -50,8 +62,8 @@
#include "NativePpc.h"
#elif defined(NANOJIT_SPARC)
#include "NativeSparc.h"
#elif defined(NANOJIT_AMD64)
#include "NativeAMD64.h"
#elif defined(NANOJIT_X64)
#include "NativeX64.h"
#else
#error "unknown nanojit architecture"
#endif

View File

@ -243,6 +243,12 @@ namespace nanojit
emitrr(X64_movqr, d, s);
}
void Assembler::JMPl(NIns* target) {
NanoAssert(!target || isS32(target - _nIns));
underrunProtect(8); // must do this before calculating offset
emit32(X64_jmp, target ? target - _nIns : 0);
}
void Assembler::JMP(NIns *target) {
if (!target || isS32(target - _nIns)) {
underrunProtect(8); // must do this before calculating offset
@ -899,6 +905,10 @@ namespace nanojit
void Assembler::asm_ret(LIns *ins) {
genEpilogue();
// Restore RSP from RBP, undoing SUB(RSP,amt) in the prologue
MR(RSP,FP);
assignSavedRegs();
LIns *value = ins->oprnd1();
Register r = ins->isop(LIR_ret) ? RAX : XMM0;
@ -1166,12 +1176,10 @@ namespace nanojit
}
NIns* Assembler::genEpilogue() {
// mov rsp, rbp
// pop rbp
// ret
emit(X64_ret);
emitr(X64_popr, RBP);
MR(RSP, RBP);
return _nIns;
}
@ -1229,8 +1237,33 @@ namespace nanojit
#endif
}
void Assembler::nFragExit(LIns*) {
TODO(nFragExit);
void Assembler::nFragExit(LIns *guard) {
SideExit *exit = guard->record()->exit;
Fragment *frag = exit->target;
GuardRecord *lr = 0;
bool destKnown = (frag && frag->fragEntry);
// Generate jump to epilog and initialize lr.
// If the guard is LIR_xtbl, use a jump table with epilog in every entry
if (guard->isop(LIR_xtbl)) {
NanoAssert(!guard->isop(LIR_xtbl));
} else {
// If the guard already exists, use a simple jump.
if (destKnown) {
JMP(frag->fragEntry);
lr = 0;
} else { // target doesn't exist. Use 0 jump offset and patch later
if (!_epilogue)
_epilogue = genEpilogue();
lr = guard->record();
JMPl(_epilogue);
lr->jmp = _nIns;
}
}
MR(RSP, RBP);
// return value is GuardRecord*
emit_quad(RAX, uintptr_t(lr));
}
void Assembler::nInit(AvmCore*) {

View File

@ -58,6 +58,7 @@
namespace nanojit
{
const int NJ_LOG2_PAGE_SIZE = 12; // 4K
#define NJ_MAX_STACK_ENTRY 256
#define NJ_ALIGN_STACK 16
@ -315,6 +316,7 @@ namespace nanojit
void asm_qbinop(LIns*); \
void MR(Register, Register);\
void JMP(NIns*);\
void JMPl(NIns*);\
void emit(uint64_t op);\
void emit8(uint64_t op, int64_t val);\
void emit32(uint64_t op, int64_t val);\

View File

@ -54,7 +54,7 @@
#elif AVMPLUS_SPARC
#define NANOJIT_SPARC
#elif AVMPLUS_AMD64
#define NANOJIT_AMD64
#define NANOJIT_X64
#define NANOJIT_64BIT
#else
#error "unknown nanojit architecture"

View File

@ -0,0 +1,40 @@
// The Great Computer Language Shootout
// http://shootout.alioth.debian.org
//
// Contributed by Ian Osgood
var result = [];
function pad(n,width) {
var s = n.toString();
while (s.length < width) s = ' ' + s;
return s;
}
function primes(isPrime, n) {
var i, count = 0, m = 10000<<n, size = m+31>>5;
for (i=0; i<size; i++) isPrime[i] = 0xffffffff;
for (i=2; i<m; i++)
if (isPrime[i>>5] & 1<<(i&31)) {
for (var j=i+i; j<m; j+=i)
result.push(isPrime[j>>5] &= ~(1<<(j&31)));
count++;
}
}
function sieve() {
for (var i = 4; i <= 4; i++) {
var isPrime = new Array((10000<<i)+31>>5);
primes(isPrime, i);
}
}
sieve();
var ret = 0;
for (var i = 0; i < result.length; ++i)
ret += result[i];
assertEq(ret, -211235557404919)