diff --git a/src/core/stuff.c b/src/core/stuff.c index 3524abeb..1709baed 100644 --- a/src/core/stuff.c +++ b/src/core/stuff.c @@ -5,6 +5,16 @@ u64 allocB; // currently allocated number of bytes B bi_emptyHVec, bi_emptyIVec, bi_emptyCVec, bi_emptySVec; +NOINLINE TStack* tstack_ext(TStack* o, u32 elsz) { + usz ncap = o->cap*2; + TStack* n = (TStack*)mm_allocN(sizeof(TStack) + elsz*ncap, t_temp); + memcpy(n->data, o->data, o->cap*elsz); + n->cap = ncap; + n->size = o->size; + mm_free((Value*)o); + return n; +} + NOINLINE void arr_print(B x) { // should accept refc=0 arguments for debugging purposes ur r = rnk(x); BS2B xgetU = TI(x).getU; diff --git a/src/core/stuff.h b/src/core/stuff.h index 307541eb..7db06184 100644 --- a/src/core/stuff.h +++ b/src/core/stuff.h @@ -52,15 +52,7 @@ typedef struct TStack { #define TSADD(N,X) { if (N##_o->size==N##_o->cap) TSDBL(N); N[N##_o->size++] = X; } #define TSADDA(N,P,AM) { u64 n=AM; while(N##_o->size+n>N##_o->cap) TSDBL(N); memcpy(N+N##_o->size,P,n*N##_e); N##_o->size+= AM; } #define TSSIZE(N) (N##_o->size) -static NOINLINE TStack* tstack_ext(TStack* o, u32 elsz) { - usz ncap = o->cap*2; - TStack* n = (TStack*)mm_allocN(sizeof(TStack) + elsz*ncap, t_temp); - memcpy(n->data, o->data, o->cap*elsz); - n->cap = ncap; - n->size = o->size; - mm_free((Value*)o); - return n; -} +TStack* tstack_ext(TStack* o, u32 elsz); // shape mess diff --git a/src/jit/nvm.c b/src/jit/nvm.c index c1df5849..e09944bd 100644 --- a/src/jit/nvm.c +++ b/src/jit/nvm.c @@ -211,7 +211,7 @@ static u32 readBytes4(u8* d) { typedef B JITFn(B* cStack, Scope** pscs); static inline i32 maxi32(i32 a, i32 b) { return a>b?a:b; } u8* m_nvm(Body* body) { - TSALLOC(u8, bin, 64); + ALLOC_ASM(64); TSALLOC(u32, rel, 64); #define r_TMP 3 #define r_PSCS 14 @@ -222,7 +222,7 @@ u8* m_nvm(Body* body) { ASM(MOV, r_CS , REG_ARG0); ASM(MOV, r_PSCS, REG_ARG1); // #define CCALL(F) { IMM(r_TMP, F); ASM(CALL, r_TMP, -); } - #define CCALL(F) { if((u64)F < 1ULL<<31) { TSADD(rel, TSSIZE(bin)); ASM(CALLI, (u32)F, -); } else { IMM(r_TMP, F); ASM(CALL, r_TMP, -); } } + #define CCALL(F) { TSADD(rel, ASM_SIZE); ASM(CALLI, (u32)F, -); } u32* bc = body->bc; Block** blocks = body->blocks->a; i32 depth = 0; @@ -305,8 +305,8 @@ u8* m_nvm(Body* body) { ASM(POP, r_TMP, -); ASM_RAW(bin, RET); #undef CCALL - - u64 sz = TSSIZE(bin); + GET_ASM(); + u64 sz = ASM_SIZE; u8* binEx = nvm_alloc(sz); #if USE_PERF if (!perf_map) { @@ -330,7 +330,7 @@ u8* m_nvm(Body* body) { memcpy(ins+1, (u8[]){BYTES4(n)}, 4); } // write_asm(binEx, sz); - TSFREE(bin); + FREE_ASM(); TSFREE(rel); return binEx; } diff --git a/src/jit/x86_64.h b/src/jit/x86_64.h index 2e537911..aed4d9f2 100644 --- a/src/jit/x86_64.h +++ b/src/jit/x86_64.h @@ -16,6 +16,7 @@ ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #pragma once +#include "../core.h" // 16 integer registers: // 0 1 2 (0: not saved, 1: callee saves, 2: caller saves) @@ -33,6 +34,32 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. // . r11 x // . r12-r15 x + +#define ALLOC_ASM(N) TStack* b_o = (TStack*)mm_allocN(sizeof(TStack)+(N), t_temp); b_o->size=0; b_o->cap=(N); +#define GET_ASM() u8* bin = b_o->data; +#define AADD(P,N) b_o=asm_add(b_o, P, N) +#define ASM_SIZE (b_o->size) +#define FREE_ASM() mm_free((Value*)b_o); +static NOINLINE TStack* asm_addR(TStack* o, u8* data, u64 am) { + u64 osz = o->size; + u64 ncap = o->cap; + while (osz+am > ncap) ncap*= 2; + ALLOC_ASM(ncap); + memcpy(b_o->data, o->data, osz); + memcpy(b_o->data+osz, data, am); + b_o->size = osz+am; + mm_free((Value*)o); + return b_o; +} +static NOINLINE TStack* asm_add(TStack* o, u8* data, u64 am) { + u64 osz = o->size; + if (RARE(osz+am > o->cap)) return asm_addR(o, data, am); + o->size+= am; + memcpy(o->data+osz, data, am); + return o; +} + + typedef unsigned char U; typedef unsigned char UC; typedef unsigned char Reg; @@ -55,7 +82,7 @@ typedef unsigned short RegM; // Ignore leading 0x40 // TODO Doesn't drop 0xF2 0x40, etc. -#define ASM_RAW(A, OP) do { UC aa[] = OP; u8 off=aa[0]==0x40; TSADDA(A, aa+off, sizeof(aa)-off); } while(0) +#define ASM_RAW(A, OP) do { UC aa[] = OP; u8 off=aa[0]==0x40; AADD(aa+off, sizeof(aa)-off); } while(0) // Instructions #define A_0REG(O,I) ((((I)&7)<<3) + ((O)&7))