optional path arg for •internal.HeapDump; STORE_JIT_MAP

This commit is contained in:
dzaima 2023-02-23 23:53:02 +02:00
parent b506b434a2
commit 1af9155425
8 changed files with 68 additions and 21 deletions

1
.gitignore vendored
View File

@ -23,6 +23,7 @@ libcbqn.dylib
CBQNHeapDump CBQNHeapDump
.cbqn_repl_history .cbqn_repl_history
cbqn_repl.txt cbqn_repl.txt
cbqn-jit.bqn
# test temporary files # test temporary files
/test/ffi/ffiTest.o /test/ffi/ffiTest.o

View File

@ -105,7 +105,7 @@ Namespace of various internal functions. May change at any time.
| `•internal.Refc` | Reference count of the argument, if it's heap-allocated | | `•internal.Refc` | Reference count of the argument, if it's heap-allocated |
| `•internal.IsPure` | Whether the vm considers the argument pure (i.e. it can execute it safely for computing fills) | | `•internal.IsPure` | Whether the vm considers the argument pure (i.e. it can execute it safely for computing fills) |
| `•internal.Info` | General internal info about the object; a left argument of `1` gives more details | | `•internal.Info` | General internal info about the object; a left argument of `1` gives more details |
| `•internal.HeapDump` | Create a heap dump file | | `•internal.HeapDump` | Create a heap dump file; saves to `•wdpath`-relative path `𝕩` or `CBQNHeapDump` if `𝕩` isn't an array |
| `•internal.Squeeze` | Try to convert the argument to its most compact representation | | `•internal.Squeeze` | Try to convert the argument to its most compact representation |
| `•internal.DeepSqueeze` | Try to convert the argument and all its subarrays to its most compact representation; won't squeeze namespace fields | | `•internal.DeepSqueeze` | Try to convert the argument and all its subarrays to its most compact representation; won't squeeze namespace fields |
| `•internal.ListVariations` | List the possible type variations of the argument array | | `•internal.ListVariations` | List the possible type variations of the argument array |

View File

@ -2,6 +2,7 @@
#include "../utils/file.h" #include "../utils/file.h"
#include "../builtins.h" #include "../builtins.h"
#include "../ns.h" #include "../ns.h"
#include "../utils/cstr.h"
B itype_c1(B t, B x) { B itype_c1(B t, B x) {
B r; B r;
@ -314,8 +315,14 @@ B internalTemp_c2(B t, B w, B x) {
} }
B heapDump_c1(B t, B x) { B heapDump_c1(B t, B x) {
cbqn_heapDump(); if (!isArr(x)) {
return m_c32(0); cbqn_heapDump(NULL);
} else {
char* s = toCStr(x);
cbqn_heapDump(s);
freeCStr(s);
}
return x;
} }
B unshare_c1(B t, B x) { B unshare_c1(B t, B x) {

View File

@ -267,6 +267,9 @@ INS B i_RETD(Scope* sc) {
FILE* perf_map; FILE* perf_map;
u32 perfid = 0; u32 perfid = 0;
#endif #endif
#if STORE_JIT_MAP
FILE* jit_map;
#endif
static void* nvm_alloc(u64 sz) { static void* nvm_alloc(u64 sz) {
// void* r = mmap(NULL, sz, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_32BIT, -1, 0); // void* r = mmap(NULL, sz, PROT_EXEC|PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_32BIT, -1, 0);
@ -530,9 +533,7 @@ static void onJIT(Body* body, u8* binEx, u64 sz) {
// printf("JIT %d:\n", perfid); // printf("JIT %d:\n", perfid);
// vm_printPos(body->comp, bcPos, -1); // vm_printPos(body->comp, bcPos, -1);
fprintf(perf_map, N64x" "N64x" JIT %d: BC@%u\n", (u64)binEx, sz, perfid++, bcPos); fprintf(perf_map, N64x" "N64x" JIT %d: BC@%u\n", (u64)binEx, sz, perfid++, bcPos);
#if PERF_MAP_FLUSH fflush(perf_map);
fflush(perf_map);
#endif
#endif #endif
#if WRITE_ASM #if WRITE_ASM
write_asm(binEx, sz); write_asm(binEx, sz);
@ -540,6 +541,31 @@ static void onJIT(Body* body, u8* binEx, u64 sz) {
#endif #endif
} }
#if STORE_JIT_MAP
void print_BC(FILE* f, u32* p, i32 w);
static NOINLINE void print_jit_line(Body* body, usz* bc, usz bcpos) {
fprintf(jit_map, " ");
if (bc!=NULL) {
print_BC(jit_map, bc, 10);
fprintf(jit_map, " ");
}
fprintf(jit_map, "# %+d\n", (int)ASM_SIZE);
Comp* comp = body->bl->comp;
if (!q_N(comp->src) && !q_N(comp->indices)) {
fprintf(jit_map, " ");
B inds = IGetU(comp->indices, 0); usz cs = o2s(IGetU(inds,bcpos));
B inde = IGetU(comp->indices, 1); usz ce = o2s(IGetU(inde,bcpos))+1;
B msg = toC32Any(vm_fmtPoint(comp->src, emptyCVec(), comp->path, cs, ce));
u32* p = c32any_ptr(msg);
usz n = IA(msg);
for (ux i = 0; i < n; i++) {
if (p[i]=='\n') fprintf(jit_map, "\n ");
else fprintCodepoint(jit_map, p[i]);
}
fprintf(jit_map, "\n");
}
}
#endif
typedef B JITFn(B* cStack, Scope* sc); typedef B JITFn(B* cStack, Scope* sc);
static inline i32 maxi32(i32 a, i32 b) { return a>b?a:b; } static inline i32 maxi32(i32 a, i32 b) { return a>b?a:b; }
Nvm_res m_nvm(Body* body) { Nvm_res m_nvm(Body* body) {
@ -578,6 +604,12 @@ Nvm_res m_nvm(Body* body) {
#define CCALL(F) CALLi((u64)(F)) #define CCALL(F) CALLi((u64)(F))
u32* origBC = body->bc; u32* origBC = body->bc;
u32 bodyOff = origBC - (u32*)body->bl->bc;
#if STORE_JIT_MAP
if (!jit_map) jit_map = fopen("cbqn-jit.bqn", "wa");
fprintf(jit_map, "{\n");
print_jit_line(body, NULL, body->bl->map[bodyOff]);
#endif
OptRes optRes = opt(origBC); OptRes optRes = opt(origBC);
i32 depth = 0; i32 depth = 0;
u32* bc = optRes.bc; u32* bc = optRes.bc;
@ -588,7 +620,11 @@ Nvm_res m_nvm(Body* body) {
u32* s = bc; u32* s = bc;
u32* n = nextBC(bc); u32* n = nextBC(bc);
u32 bcpos = optRes.offset[s-optRes.bc]; u32 bcpos = optRes.offset[s-optRes.bc];
u32 bodyOff = origBC - (u32*)body->bl->bc; #if STORE_JIT_MAP
print_jit_line(body, s, body->bl->map[bcpos+bodyOff]);
#endif
u32* off = origBC + bcpos; u32* off = origBC + bcpos;
bool ret = false; bool ret = false;
#define L64 ({ u64 r = bc[0] | ((u64)bc[1])<<32; bc+= 2; r; }) #define L64 ({ u64 r = bc[0] | ((u64)bc[1])<<32; bc+= 2; r; })
@ -727,6 +763,10 @@ Nvm_res m_nvm(Body* body) {
asm_write(binEx, sz); asm_write(binEx, sz);
asm_free(); asm_free();
onJIT(body, binEx, sz); onJIT(body, binEx, sz);
#if STORE_JIT_MAP
fprintf(jit_map, " # start address: "N64d"\n}\n", ptr2u64(binEx));
fflush(jit_map);
#endif
return (Nvm_res){.p = binEx, .refs = optRes.refs}; return (Nvm_res){.p = binEx, .refs = optRes.refs};
} }
B evalJIT(Body* b, Scope* sc, u8* ptr) { // doesn't consume B evalJIT(Body* b, Scope* sc, u8* ptr) { // doesn't consume

View File

@ -562,7 +562,7 @@ B bqn_execFile(B path, B args) { // consumes both
void before_exit(void); void before_exit(void);
void bqn_exit(i32 code) { void bqn_exit(i32 code) {
#ifdef DUMP_ON_EXIT #ifdef DUMP_ON_EXIT
cbqn_heapDump(); cbqn_heapDump(NULL);
#endif #endif
rtWrap_print(); rtWrap_print();
CTR_FOR(CTR_PRINT) CTR_FOR(CTR_PRINT)

View File

@ -431,8 +431,8 @@ static u8 types_val[] = {
#undef F #undef F
}; };
void cbqn_heapDump() { void cbqn_heapDump(char* name0) {
char* name = "CBQNHeapDump"; char* name = name0==NULL? "CBQNHeapDump" : name0;
FILE* f = fopen(name, "w"); FILE* f = fopen(name, "w");
if (f==NULL) { if (f==NULL) {
fprintf(stderr, "Failed to dump heap - could not open file for writing\n"); fprintf(stderr, "Failed to dump heap - could not open file for writing\n");
@ -470,6 +470,6 @@ void cbqn_heapDump() {
mm_dumpHeap(f); mm_dumpHeap(f);
mmX_dumpHeap(f); mmX_dumpHeap(f);
fprintf(stderr, "Heap dumped to \"%s\"\n", name); if (name0==NULL) fprintf(stderr, "Heap dumped to \"%s\"\n", name);
fclose(f); fclose(f);
} }

View File

@ -29,4 +29,4 @@ void file_wBytes(FILE* file, B name, B x); // doesn't consume
B path_list(B path); // consumes B path_list(B path); // consumes
char path_type(B path); // consumes; errors only if path isn't a string char path_type(B path); // consumes; errors only if path isn't a string
B path_info(B path, i32 mode); // consumes; mode: 0:created 1:accessed 2:modified 3:size B path_info(B path, i32 mode); // consumes; mode: 0:created 1:accessed 2:modified 3:size
void cbqn_heapDump(void); void cbqn_heapDump(char* name);

View File

@ -25,9 +25,9 @@ char* bc_repr(u32 p) {
#undef F #undef F
} }
} }
void print_BC(u32* p, i32 w) { void print_BC(FILE* f, u32* p, i32 w) {
char* str = bc_repr(*p); char* str = bc_repr(*p);
printf("%s", str); fprintf(f, "%s", str);
u32* n = nextBC(p); u32* n = nextBC(p);
p++; p++;
i32 len = strlen(str); i32 len = strlen(str);
@ -39,16 +39,16 @@ void print_BC(u32* p, i32 w) {
buf[clen++] = (c&15)>9? 'A'+(c&15)-10 : '0'+(c&15); buf[clen++] = (c&15)>9? 'A'+(c&15)-10 : '0'+(c&15);
c>>= 4; c>>= 4;
} while(c); } while(c);
putchar(' '); fputc(' ', f);
for (i32 i = 0; i < clen; i++) putchar(buf[clen-i-1]); for (i32 i = 0; i < clen; i++) fputc(buf[clen-i-1], f);
len+= clen+1; len+= clen+1;
} }
len = w-len; len = w-len;
while(len-->0) putchar(' '); while(len-->0) fputc(' ', f);
} }
void print_BCStream(u32* p) { void print_BCStream(FILE* f, u32* p) {
while(true) { while(true) {
print_BC(p, 10); putchar(10); print_BC(f, p, 10); fputc(10, f);
if (*p == RETD || *p == RETN) return; if (*p == RETD || *p == RETN) return;
p = nextBC(p); p = nextBC(p);
} }
@ -1357,8 +1357,7 @@ NOINLINE void vm_printPos(Comp* comp, i32 bcPos, i64 pos) {
#endif #endif
if (CATCH) { freeThrown(); goto native_print; } if (CATCH) { freeThrown(); goto native_print; }
B s = emptyCVec(); B msg = vm_fmtPoint(src, emptyCVec(), comp->path, cs, ce);
B msg = vm_fmtPoint(src, s, comp->path, cs, ce);
fprintsB(stderr, msg); fprintsB(stderr, msg);
dec(msg); dec(msg);
fputc('\n', stderr); fputc('\n', stderr);