3,243 karma · joined July 25, 2017
Let’s look at the example from the docs:
SWL_GCArena gc = swl_gc_arena_new(<starting-capacity>);
int* foo = swl_gc_alloc(&gc, 5000, alignof(int), NULL);
int* bar = swl_gc_alloc(&gc, 16000, alignof(int), NULL);
int* baz = swl_gc_alloc(&gc, 3000, alignof(int), NULL);
// foo and baz are roots
SWL_GC_COLLECT(&gc, SWL_ROOT(foo), SWL_ROOT(baz));
// bar is gone, poof
If you try to access bar at the end you get a use after free. I am pretty sure if you tried to access foo again it would trigger the same problem, because it is a pointer directly to int and not an indirection. What happens if you pass a non-arena pointer to SWL_ROOT? What happens if you have multiple arenas and you mix and match them?There are many ways you could trivially shoot yourself in the foot in large program. It is a lot less “idiot-proof” than simple reference counting. The fact that you create each piece of memory and then have to manually pass it back to the root macro on each collection is very similar to the “malloc/free” dance we want to try and avoid.
The rooting issue is something I tried to tackle in my GC for rust[1]. Essentially making low level GC "idiot proof".
[1] https://coredumped.dev/2022/04/11/implementing-a-safe-garbag...
Wow. Does that mean that once the VC money dries up that will be the real cost of the products ($30-$90 a month)? That is much less accessible than $10.
function blob_contents(blob)
local len_out = ffi.new('unsigned int')
local contents = gc_borrows_from(blob, hb.hb_blob_get_data(blob, len_out))
local len = len_out[0];
return ffi.string(contents, len)
end
This would tell the GC that the data returned by `hb_blob_get_data` is borrowed from blob, and it can't collect `blob` until `contents` is also unreachable. How to implement that would be up to the runtime, but it seems reasonable to have a wrapper type that holds a traceable reference back to blob.I think the GraalVM approach of transforming the C into your own IR and then JITing that is another interesting approach. Essentially treat Java and C as one unified source and compile them together. That certainly takes more work and a very expressive IR, but it is another way to deal with the inefficiency at the API boundary.
Why would you want to avoid the branch predictor? All it can do is speedup your code.
[1] https://github.com/PlutoLang/Pluto/blob/main/src/ljumptabgcc...
[2] https://github.com/PlutoLang/Pluto/blob/main/src/ljumptab.h
https://github.com/rust-lang/rust/issues/107617#issuecomment...
Protein is really important for our diets. Many adults even in the first world are not getting enough of it. It's not some "luxury" macromolecule the we should just consume less of (like sugar). Most peoples diets (at least in the US) have too many carbs and sugars (plants) and not enough protein (meat). You can get the protein you need from plant based sources, but you have to be really intentional about it and work hard at it. Meat contains every nutrient your body needs besides vitamin C.