optional path arg for •internal.HeapDump; STORE_JIT_MAP
This commit is contained in:
parent
b506b434a2
commit
1af9155425
1
.gitignore
vendored
1
.gitignore
vendored
@ -23,6 +23,7 @@ libcbqn.dylib
|
||||
CBQNHeapDump
|
||||
.cbqn_repl_history
|
||||
cbqn_repl.txt
|
||||
cbqn-jit.bqn
|
||||
|
||||
# test temporary files
|
||||
/test/ffi/ffiTest.o
|
||||
|
||||
@ -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.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.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.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 |
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#include "../utils/file.h"
|
||||
#include "../builtins.h"
|
||||
#include "../ns.h"
|
||||
#include "../utils/cstr.h"
|
||||
|
||||
B itype_c1(B t, B x) {
|
||||
B r;
|
||||
@ -314,8 +315,14 @@ B internalTemp_c2(B t, B w, B x) {
|
||||
}
|
||||
|
||||
B heapDump_c1(B t, B x) {
|
||||
cbqn_heapDump();
|
||||
return m_c32(0);
|
||||
if (!isArr(x)) {
|
||||
cbqn_heapDump(NULL);
|
||||
} else {
|
||||
char* s = toCStr(x);
|
||||
cbqn_heapDump(s);
|
||||
freeCStr(s);
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
B unshare_c1(B t, B x) {
|
||||
|
||||
@ -267,6 +267,9 @@ INS B i_RETD(Scope* sc) {
|
||||
FILE* perf_map;
|
||||
u32 perfid = 0;
|
||||
#endif
|
||||
#if STORE_JIT_MAP
|
||||
FILE* jit_map;
|
||||
#endif
|
||||
|
||||
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);
|
||||
@ -530,9 +533,7 @@ static void onJIT(Body* body, u8* binEx, u64 sz) {
|
||||
// printf("JIT %d:\n", perfid);
|
||||
// vm_printPos(body->comp, bcPos, -1);
|
||||
fprintf(perf_map, N64x" "N64x" JIT %d: BC@%u\n", (u64)binEx, sz, perfid++, bcPos);
|
||||
#if PERF_MAP_FLUSH
|
||||
fflush(perf_map);
|
||||
#endif
|
||||
fflush(perf_map);
|
||||
#endif
|
||||
#if WRITE_ASM
|
||||
write_asm(binEx, sz);
|
||||
@ -540,6 +541,31 @@ static void onJIT(Body* body, u8* binEx, u64 sz) {
|
||||
#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);
|
||||
static inline i32 maxi32(i32 a, i32 b) { return a>b?a:b; }
|
||||
Nvm_res m_nvm(Body* body) {
|
||||
@ -578,6 +604,12 @@ Nvm_res m_nvm(Body* body) {
|
||||
|
||||
#define CCALL(F) CALLi((u64)(F))
|
||||
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);
|
||||
i32 depth = 0;
|
||||
u32* bc = optRes.bc;
|
||||
@ -588,7 +620,11 @@ Nvm_res m_nvm(Body* body) {
|
||||
u32* s = bc;
|
||||
u32* n = nextBC(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;
|
||||
bool ret = false;
|
||||
#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_free();
|
||||
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};
|
||||
}
|
||||
B evalJIT(Body* b, Scope* sc, u8* ptr) { // doesn't consume
|
||||
|
||||
@ -562,7 +562,7 @@ B bqn_execFile(B path, B args) { // consumes both
|
||||
void before_exit(void);
|
||||
void bqn_exit(i32 code) {
|
||||
#ifdef DUMP_ON_EXIT
|
||||
cbqn_heapDump();
|
||||
cbqn_heapDump(NULL);
|
||||
#endif
|
||||
rtWrap_print();
|
||||
CTR_FOR(CTR_PRINT)
|
||||
|
||||
@ -431,8 +431,8 @@ static u8 types_val[] = {
|
||||
#undef F
|
||||
};
|
||||
|
||||
void cbqn_heapDump() {
|
||||
char* name = "CBQNHeapDump";
|
||||
void cbqn_heapDump(char* name0) {
|
||||
char* name = name0==NULL? "CBQNHeapDump" : name0;
|
||||
FILE* f = fopen(name, "w");
|
||||
if (f==NULL) {
|
||||
fprintf(stderr, "Failed to dump heap - could not open file for writing\n");
|
||||
@ -470,6 +470,6 @@ void cbqn_heapDump() {
|
||||
|
||||
mm_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);
|
||||
}
|
||||
|
||||
@ -29,4 +29,4 @@ void file_wBytes(FILE* file, B name, B x); // doesn't consume
|
||||
B path_list(B path); // consumes
|
||||
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
|
||||
void cbqn_heapDump(void);
|
||||
void cbqn_heapDump(char* name);
|
||||
|
||||
17
src/vm.c
17
src/vm.c
@ -25,9 +25,9 @@ char* bc_repr(u32 p) {
|
||||
#undef F
|
||||
}
|
||||
}
|
||||
void print_BC(u32* p, i32 w) {
|
||||
void print_BC(FILE* f, u32* p, i32 w) {
|
||||
char* str = bc_repr(*p);
|
||||
printf("%s", str);
|
||||
fprintf(f, "%s", str);
|
||||
u32* n = nextBC(p);
|
||||
p++;
|
||||
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);
|
||||
c>>= 4;
|
||||
} while(c);
|
||||
putchar(' ');
|
||||
for (i32 i = 0; i < clen; i++) putchar(buf[clen-i-1]);
|
||||
fputc(' ', f);
|
||||
for (i32 i = 0; i < clen; i++) fputc(buf[clen-i-1], f);
|
||||
len+= clen+1;
|
||||
}
|
||||
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) {
|
||||
print_BC(p, 10); putchar(10);
|
||||
print_BC(f, p, 10); fputc(10, f);
|
||||
if (*p == RETD || *p == RETN) return;
|
||||
p = nextBC(p);
|
||||
}
|
||||
@ -1357,8 +1357,7 @@ NOINLINE void vm_printPos(Comp* comp, i32 bcPos, i64 pos) {
|
||||
#endif
|
||||
if (CATCH) { freeThrown(); goto native_print; }
|
||||
|
||||
B s = emptyCVec();
|
||||
B msg = vm_fmtPoint(src, s, comp->path, cs, ce);
|
||||
B msg = vm_fmtPoint(src, emptyCVec(), comp->path, cs, ce);
|
||||
fprintsB(stderr, msg);
|
||||
dec(msg);
|
||||
fputc('\n', stderr);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user