)erase; try to not oom on printing errors

This commit is contained in:
dzaima 2022-01-19 00:59:56 +02:00
parent 48e9e3d655
commit 3fb793526c
5 changed files with 53 additions and 23 deletions

View File

@ -204,6 +204,29 @@ int main(int argc, char* argv[]) {
}
heap_printInfo(sizes, types);
goto cont;
} else if (isCmd(cmdS, &cmdE, "erase ")) {
char* name = cmdE;
i64 len = strlen(name);
ScopeExt* e = gsc->ext;
if (e!=NULL) {
i32 am = e->varAm;
for (i32 i = 0; i < am; i++) {
B c = e->vars[i+am];
if (a(c)->ia != len) continue;
SGetU(c)
bool ok = true;
for (i32 j = 0; j < len; j++) ok&= o2cu(GetU(c, j))==name[j];
if (ok) {
B val = e->vars[i];
e->vars[i] = bi_noVar;
dec(val);
if (!gc_depth) gc_forceGC();
goto cont;
}
}
}
printf("No such variable found\n");
goto cont;
} else if (isCmd(cmdS, &cmdE, "vars")) {
B r = listVars(gsc);
if (q_N(r)) {

View File

@ -47,12 +47,16 @@ static void gc_tryFree(Value* v) {
v->type = t_freed;
ptr_inc(v); // required as otherwise the object may free itself while not done reading its own fields
TIi(t,freeO)(v);
ptr_dec(v);
tptr_dec(v, mm_free);
// Object may not be immediately freed if it's not a part of a cycle, but instead a descendant of one.
// It will be freed when the cycle is freed, and the t_freed type ensures it doesn't double-free itself
}
}
static void gc_freeFreed(Value* v) {
if (v->type==t_freed) mm_free(v);
}
static void gc_resetTag(Value* x) {
x->mmInfo&= 0x7F;
}
@ -73,6 +77,7 @@ void gc_forceGC() {
mm_forHeap(gc_resetTag);
gc_visitRoots();
mm_forHeap(gc_tryFree);
mm_forHeap(gc_freeFreed);
u64 endSize = mm_heapUsed();
#ifdef LOG_GC
fprintf(stderr, "GC kept "N64d"B from "N64d" objects, freed "N64d"B, including directly "N64d"B from "N64d" objects; took %.3fms\n", gc_visitBytes, gc_visitCount, startSize-endSize, gc_freedBytes, gc_freedCount, (nsTime()-start)/1e6);

View File

@ -36,13 +36,11 @@ FORCE_INLINE void BN(splitTo)(EmptyValue* c, i64 from, i64 to, bool notEqual) {
static NOINLINE void* BN(allocateMore)(i64 bucket, u8 type, i64 from, i64 to) {
u64 sz = BSZ(from);
if (mm_heapAlloc+sz >= mm_heapMax) {
if (sz>100000) thrOOM(); // if allocating a large thing, it may be possible to recover
printf("Heap size limit reached\n"); abort();
}
if (mm_heapAlloc+sz >= mm_heapMax) thrOOM();
mm_heapAlloc+= sz;
// gc_maybeGC();
EmptyValue* c = MMAP(sz);
if (c==MAP_FAILED) thrOOM();
#ifdef USE_VALGRIND
VALGRIND_MAKE_MEM_UNDEFINED(c, sz);
#endif
@ -51,7 +49,6 @@ static NOINLINE void* BN(allocateMore)(i64 bucket, u8 type, i64 from, i64 to) {
al = realloc(al, sizeof(AllocInfo)*alCap);
}
al[BN(alSize)++] = (AllocInfo){.p = (Value*)c, .sz = sz};
if (c==MAP_FAILED) { printf("Failed to allocate memory\n"); exit(1); }
c->type = t_empty;
c->mmInfo = from;
c->next = 0;

View File

@ -44,12 +44,12 @@ def broadcast{T, v & w256{T} & isintv{T, 64}} = emit{T, '_mm256_set1_epi64x',ext
def broadcast{T, v & w256{T} & eltype{T}==f64} = emit{T, '_mm256_set1_pd', v}
def broadcast{T, v & w256{T} & eltype{T}==f32} = emit{T, '_mm256_set1_ps', v}
def make{T,a,b,c,d & T==[4]f64} = emit{T,'_mm256_set_pd',d,c,b,a}
def make{T,a,b,c,d,e,f,g,h & T==[8]f32} = emit{T,'_mm256_set_ps',h,g,f,e,d,c,b,a}
def make{T,a,b,c,d & T==[4]i64} = emit{T,'_mm256_set_epi64x',ext{i64,d},ext{i64,c},ext{i64,b},ext{i64,a}}
def make{T,a,b,c,d,e,f,g,h & T==[8]i32} = emit{T,'_mm256_set_epi32',ext{i32,h},ext{i32,g},ext{i32,f},ext{i32,e},ext{i32,d},ext{i32,c},ext{i32,b},ext{i32,a}}
def make{T,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p & T==[16]i16} = emit{T,'_mm256_set_epi16', ext{i16,p},ext{i16,o},ext{i16,n},ext{i16,m},ext{i16,l},ext{i16,k},ext{i16,j},ext{i16,i},ext{i16,h},ext{i16,g},ext{i16,f},ext{i16,e},ext{i16,d},ext{i16,c},ext{i16,b},ext{i16,a}}
def make{T,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P & T==[32]i8} = emit{T,'_mm256_set_epi8', ext{i8,P},ext{i8,O},ext{i8,N},ext{i8,M},ext{i8,L},ext{i8,K},ext{i8,J},ext{i8,I},ext{i8,H},ext{i8,G},ext{i8,F},ext{i8,E},ext{i8,D},ext{i8,C},ext{i8,B},ext{i8,A}, ext{i8,p},ext{i8,o},ext{i8,n},ext{i8,m},ext{i8,l},ext{i8,k},ext{i8,j},ext{i8,i},ext{i8,h},ext{i8,g},ext{i8,f},ext{i8,e},ext{i8,d},ext{i8,c},ext{i8,b},ext{i8,a}}
def make{T==[4]f64,a,b,c,d} = emit{T,'_mm256_set_pd',d,c,b,a}
def make{T==[8]f32,a,b,c,d,e,f,g,h} = emit{T,'_mm256_set_ps',h,g,f,e,d,c,b,a}
def make{T==[4]i64,a,b,c,d} = emit{T,'_mm256_set_epi64x',ext{i64,d},ext{i64,c},ext{i64,b},ext{i64,a}}
def make{T==[8]i32,a,b,c,d,e,f,g,h} = emit{T,'_mm256_set_epi32',ext{i32,h},ext{i32,g},ext{i32,f},ext{i32,e},ext{i32,d},ext{i32,c},ext{i32,b},ext{i32,a}}
def make{T==[16]i16,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p} = emit{T,'_mm256_set_epi16', ext{i16,p},ext{i16,o},ext{i16,n},ext{i16,m},ext{i16,l},ext{i16,k},ext{i16,j},ext{i16,i},ext{i16,h},ext{i16,g},ext{i16,f},ext{i16,e},ext{i16,d},ext{i16,c},ext{i16,b},ext{i16,a}}
def make{T==[32]i8,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P} = emit{T,'_mm256_set_epi8', ext{i8,P},ext{i8,O},ext{i8,N},ext{i8,M},ext{i8,L},ext{i8,K},ext{i8,J},ext{i8,I},ext{i8,H},ext{i8,G},ext{i8,F},ext{i8,E},ext{i8,D},ext{i8,C},ext{i8,B},ext{i8,A}, ext{i8,p},ext{i8,o},ext{i8,n},ext{i8,m},ext{i8,l},ext{i8,k},ext{i8,j},ext{i8,i},ext{i8,h},ext{i8,g},ext{i8,f},ext{i8,e},ext{i8,d},ext{i8,c},ext{i8,b},ext{i8,a}}
def __xor{a:T, b:T & w256{T} & isintv{T}} = r_f2i{T, emit{[8]f32, '_mm256_xor_ps', r_i2f{a}, r_i2f{b}}}
def __and{a:T, b:T & w256{T} & isintv{T}} = r_f2i{T, emit{[8]f32, '_mm256_and_ps', r_i2f{a}, r_i2f{b}}}

View File

@ -1145,20 +1145,25 @@ NOINLINE void vm_printPos(Comp* comp, i32 bcPos, i64 pos) {
B inde = IGetU(comp->indices, 1); usz ce = o2s(IGetU(inde,bcPos))+1;
// printf(" bcPos=%d\n", bcPos); // in case the pretty error generator is broken
// printf(" inds:%d…%d\n", cs, ce);
// int start = pos==-1? 0 : printf(N64d": ", pos);
// usz srcL = a(src)->ia;
// SGetU(src)
// usz srcS = cs; while (srcS>0 && o2cu(GetU(src,srcS-1))!='\n') srcS--;
// usz srcE = srcS; while (srcE<srcL) { u32 chr = o2cu(GetU(src, srcE)); if(chr=='\n')break; printUTF8(chr); srcE++; }
// if (ce>srcE) ce = srcE;
// cs-= srcS; ce-= srcS;
// putchar('\n');
// for (i32 i = 0; i < cs+start; i++) putchar(' ');
// for (i32 i = cs; i < ce; i++) putchar('^');
// putchar('\n');
if (CATCH) { // want to try really hard to print errors
freeThrown();
int start = printf("at ");
usz srcL = a(src)->ia;
SGetU(src)
usz srcS = cs; while (srcS>0 && o2cu(GetU(src,srcS-1))!='\n') srcS--;
usz srcE = srcS; while (srcE<srcL) { u32 chr = o2cu(GetU(src, srcE)); if(chr=='\n')break; printUTF8(chr); srcE++; }
if (ce>srcE) ce = srcE;
cs-= srcS; ce-= srcS;
putchar('\n');
for (i32 i = 0; i < cs+start; i++) putchar(' ');
for (i32 i = cs; i < ce; i++) putchar('^');
putchar('\n');
return;
}
B s = emptyCVec();
printRaw(vm_fmtPoint(src, s, comp->path, cs, ce));
putchar('\n');
popCatch();
//print_BCStream((u32*)i32arr_ptr(comp->bc)+bcPos);
} else {
#ifdef DEBUG