From 2a4faa131cf688ef5b81abc88d3abffcdafff652 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 26 Aug 2008 15:15:15 -0700 Subject: [PATCH 1/2] Fixed crashing with the incremental allocation changes. Very long jumps are still a problem but at least now we assert. --- js/src/nanojit/LIR.cpp | 25 +++++++++++++++++++++---- js/src/nanojit/LIR.h | 4 ++++ js/src/nanojit/NativeAMD64.h | 7 ++++--- js/src/nanojit/Nativei386.cpp | 3 ++- 4 files changed, 31 insertions(+), 8 deletions(-) diff --git a/js/src/nanojit/LIR.cpp b/js/src/nanojit/LIR.cpp index f6d8cf9573e..948a787ac0a 100755 --- a/js/src/nanojit/LIR.cpp +++ b/js/src/nanojit/LIR.cpp @@ -391,12 +391,18 @@ namespace nanojit return l; } else { - ensureRoom(2); + #if defined NANOJIT_64BIT + const unsigned int extra = 1; + #else + const unsigned int extra = 0; + #endif + + ensureRoom(2 + extra); // write the pointer and instruction - l = _buf->next()+1; - *((LInsp*)(l-1)) = target; + l = _buf->next()+1+extra; + *((LInsp*)(l-1-extra)) = target; l->initOpcode(op); - _buf->commit(2); + _buf->commit(2+extra); return l; } } @@ -469,6 +475,15 @@ namespace nanojit break; case LIR_tramp: +#if defined NANOJIT_64BIT + NanoAssert(samepage(i, i-3)); + i -= 3; +#else + NanoAssert(samepage(i, i-2)); + i -= 2; +#endif + break; + case LIR_int: NanoAssert(samepage(i, i-2)); i -= 2; @@ -920,6 +935,8 @@ namespace nanojit { static const LOpcode k_callmap[] = { LIR_call, LIR_fcall, LIR_call, LIR_callh }; + NanoAssert(fid < CI_Max); + const CallInfo& ci = _functions[fid]; uint32_t argt = ci._argtypes; LOpcode op = k_callmap[argt & 3]; diff --git a/js/src/nanojit/LIR.h b/js/src/nanojit/LIR.h index ac11dbfa956..a9c45836570 100644 --- a/js/src/nanojit/LIR.h +++ b/js/src/nanojit/LIR.h @@ -243,7 +243,11 @@ namespace nanojit inline uint8_t imm8() const { return c.imm8a; } inline int16_t imm16() const { return i.imm16; } inline LIns* ref() const { +#if defined NANOJIT_64BIT + return (t.code & 1) ? (LIns*)this+t.imm24 : *(LIns**)(this-2); +#else return (t.code & 1) ? (LIns*)this+t.imm24 : *(LIns**)(this-1); +#endif } inline int32_t imm32() const { return *(int32_t*)(this-1); } inline uint8_t resv() const { return g.resv; } diff --git a/js/src/nanojit/NativeAMD64.h b/js/src/nanojit/NativeAMD64.h index 8183956d739..23b5bdda7d2 100644 --- a/js/src/nanojit/NativeAMD64.h +++ b/js/src/nanojit/NativeAMD64.h @@ -183,7 +183,7 @@ namespace nanojit _pageData = 0; \ _dblNegPtr = NULL; \ _negOnePtr = NULL; \ - int d = tt-_nIns; \ + intptr_t d = tt-_nIns; \ JMP_long_nochk_offset(d); \ } \ overrideProtect = _nIns; \ @@ -894,11 +894,12 @@ namespace nanojit #define JMP_long_placeholder() do {\ underrunProtect(5); \ - JMP_long_nochk_offset(0xffffffff); } while(0) + JMP_long_nochk_offset(-1); } 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 {\ verbose_only( NIns* next = _nIns; (void)next; ) \ + NanoAssert(o <= INT_MAX && o >= INT_MIN); \ IMM32((o)); \ *(--_nIns) = JMPc; \ asm_output1("jmp %lX",(ptrdiff_t)(next+(o))); } while(0) @@ -1116,9 +1117,9 @@ namespace nanojit } while (0) #define CALL(c) do { \ + underrunProtect(5); \ intptr_t offset = (c->_address) - ((intptr_t)_nIns); \ if (offset <= INT_MAX && offset >= INT_MIN) { \ - underrunProtect(5); \ IMM32( (uint32_t)offset ); \ *(--_nIns) = 0xE8; \ } else { \ diff --git a/js/src/nanojit/Nativei386.cpp b/js/src/nanojit/Nativei386.cpp index bd225b2b8e2..01d658393a6 100644 --- a/js/src/nanojit/Nativei386.cpp +++ b/js/src/nanojit/Nativei386.cpp @@ -285,7 +285,7 @@ namespace nanojit uint32_t fid = ins->fid(); const CallInfo* call = callInfoFor(fid); int n = 0; - + CALL(call); ArgSize sizes[10]; @@ -1218,6 +1218,7 @@ namespace nanojit NIns* 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; + NanoAssert(tt <= INT_MAX && tt >= INT_MIN); IMM32(tt); *(--_nIns) = JMPc; _nIns = save; From d7c7f1645b6fbd5cc8a635c23ab17e9920ef5e09 Mon Sep 17 00:00:00 2001 From: David Anderson Date: Tue, 26 Aug 2008 23:14:13 -0700 Subject: [PATCH 2/2] Improved AMD64 out-of-range jumping, some cases are still broken though. Fixed i386 build. --- js/src/nanojit/NativeAMD64.h | 43 ++++++++++++++++++++++------------- js/src/nanojit/Nativei386.cpp | 5 ++++ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/js/src/nanojit/NativeAMD64.h b/js/src/nanojit/NativeAMD64.h index 23b5bdda7d2..7243dbac914 100644 --- a/js/src/nanojit/NativeAMD64.h +++ b/js/src/nanojit/NativeAMD64.h @@ -141,9 +141,17 @@ namespace nanojit #define DECLARE_PLATFORM_REGALLOC() + #if !defined WIN64 + #define DECLARE_PLATFORM_ASSEMBLER_START() \ + const static Register argRegs[6], retRegs[2]; + #else + #define DECLARE_PLATFORM_ASSEMBLER_START() \ + const static Register argRegs[4], retRegs[2]; + #endif + #if !defined WIN64 #define DECLARE_PLATFORM_ASSEMBLER() \ - const static Register argRegs[6], retRegs[2]; \ + DECLARE_PLATFORM_ASSEMBLER_START() \ bool sse2; \ bool has_cmov; \ bool pad[1]; \ @@ -155,19 +163,6 @@ namespace nanojit NIns *_dblNegPtr; \ NIns *_negOnePtr; \ NIns *overrideProtect; - #else - #define DECLARE_PLATFORM_ASSEMBLER() \ - const static Register argRegs[4], retRegs[2]; \ - bool sse2; \ - bool has_cmov; \ - bool pad[1]; \ - void nativePageReset(); \ - void nativePageSetup(); \ - void asm_farg(LInsp); \ - void asm_qbinop(LInsp); \ - int32_t _pageData; \ - NIns *_dblNegPtr; \ - NIns *_negOnePtr; #endif #define swapptrs() { NIns* _tins = _nIns; _nIns=_nExitIns; _nExitIns=_tins; } @@ -184,7 +179,16 @@ namespace nanojit _dblNegPtr = NULL; \ _negOnePtr = NULL; \ intptr_t d = tt-_nIns; \ - JMP_long_nochk_offset(d); \ + if (d <= INT_MAX && d >= INT_MIN) { \ + JMP_long_nochk_offset(d); \ + } else { \ + /* Insert a 64-bit jump... */ \ + _nIns -= 8; \ + *(intptr_t *)_nIns = intptr_t(tt); \ + IMM32(0); \ + *(_nIns--) = 0x25; \ + *(_nIns--) = 0xFF; \ + } \ } \ overrideProtect = _nIns; \ } @@ -904,6 +908,14 @@ 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") #define JP(t) JCC(0x0A, t, "jp") @@ -1123,7 +1135,6 @@ namespace nanojit IMM32( (uint32_t)offset ); \ *(--_nIns) = 0xE8; \ } else { \ - underrunProtect(2); \ *(--_nIns) = 0xD0; \ *(--_nIns) = 0xFF; \ LDQi(RAX, c->_address); \ diff --git a/js/src/nanojit/Nativei386.cpp b/js/src/nanojit/Nativei386.cpp index 01d658393a6..6195c2e0924 100644 --- a/js/src/nanojit/Nativei386.cpp +++ b/js/src/nanojit/Nativei386.cpp @@ -1218,7 +1218,9 @@ namespace nanojit NIns* 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; @@ -1228,6 +1230,9 @@ namespace nanojit void Assembler::nativePageReset() { #if defined NANOJIT_AMD64 + /* We store some stuff at the bottom of the page. + * We reserve 8-bytes for long jumps just in case we need them. + */ _pageData = 0; _dblNegPtr = NULL; _negOnePtr = NULL;