ref: e732a668e856a6eebd755eddbbc37f6b822f3217
parent: b81e574fb493d4354196d9e2a9adf8f76eab5e76
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Mon Nov 11 14:59:11 EST 2024
import from Julia: "fix a possible flisp memory bug", by Jeff Bezanson This is 1a81a4770cba7b078a28a52dfd5bb630977561c9 in Julia: "in very rare circumstances this could cause a closure to spill over the heap".
--- a/flisp.c
+++ b/flisp.c
@@ -287,7 +287,7 @@
assert(n > 0);
n = LLT_ALIGN(n, 2); // only allocate multiples of 2 words
- if(__unlikely((value_t*)FL(curheap) > ((value_t*)FL(lim))+2-n)){
+ if(__unlikely((value_t*)FL(curheap) > (value_t*)FL(lim)+2-n)){
gc(0);
while((value_t*)FL(curheap) > ((value_t*)FL(lim))+2-n)
gc(1);
@@ -521,8 +521,12 @@
}
FL(grew) = !FL(grew);
}
- if(FL(curheap) > FL(lim)) // all data was live
+ if(__unlikely((value_t*)FL(curheap) > (value_t*)FL(lim)-2)){
+ // all data was live; gc again and grow heap.
+ // but also always leave at least 4 words available, so a closure
+ // can be allocated without an extra check.
gc(0);
+ }
}
static void
@@ -1191,7 +1195,7 @@
}else{
PUSH(FL(stack)[bp]); // env has already been captured; share
}
- if(FL(curheap) > FL(lim)-2)
+ if(__unlikely((value_t*)FL(curheap) > (value_t*)FL(lim)-2))
gc(0);
pv = (value_t*)FL(curheap);
FL(curheap) += 4*sizeof(value_t);