diff --git a/src/main.c b/src/main.c index b25bf590..e5d97293 100644 --- a/src/main.c +++ b/src/main.c @@ -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)) { diff --git a/src/opt/gc.c b/src/opt/gc.c index d3b1521b..338327c6 100644 --- a/src/opt/gc.c +++ b/src/opt/gc.c @@ -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); diff --git a/src/opt/mm_buddyTemplate.c b/src/opt/mm_buddyTemplate.c index 81c87e8d..60ec858d 100644 --- a/src/opt/mm_buddyTemplate.c +++ b/src/opt/mm_buddyTemplate.c @@ -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; diff --git a/src/singeli/src/avx.singeli b/src/singeli/src/avx.singeli index bc0f7ceb..012cc181 100644 --- a/src/singeli/src/avx.singeli +++ b/src/singeli/src/avx.singeli @@ -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}}} diff --git a/src/vm.c b/src/vm.c index 86694f71..2b177e5c 100644 --- a/src/vm.c +++ b/src/vm.c @@ -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 (srcEsrcE) 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 (srcEsrcE) 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