Incremental garbage collection

H. S. Teoh hsteoh at quickfur.ath.cx
Fri Jan 21 18:04:53 UTC 2022


On Fri, Jan 21, 2022 at 11:12:01AM +0000, Elronnd via Digitalmars-d wrote:
[...]
> void f(int** x) {
> 	*x = new int;
> }
> void g() {
> 	int** x = new int*;
> 	f(x);
> 	int* y;
> 	f(&y);
> }
> 
> and we want to add a generational gc, which barriers.  So naively we
> rewrite f as follows:
> 
> void f(int** x) {
> 	store_barrier(x, new int);
> }
> 
> This will involve overhead because we don't know if x is a gc pointer or
> not.  So instead, generate multiple definitions and rewrite callers:
> 
> void f_gc(int** x) {
> 	store_barrier(x, new int);
> }
> void f_nogc(int** x) {
> 	*x = new int; //no barrier!
> }
> void g() {
> 	int** x = new int*;
> 	f_gc(x);
> 	int* y;
> 	f_nogc(&y); //no overhead from passing stack object!
> }

So basically *every* function that receives pointers in some way (could
be implicitly via built-in slices, for example) will essentially be
implicitly templatized?  That will lead to a LOT of template bloat. I'm
not sure if this is a good idea.


> Of course this transformation is conservative: you will sometimes call
> f_gc with a non-gc pointer.  But I bet it works 99% of the time such
> that the runtime overhead is negligible in practice.

What we need is a working proof-of-concept implementation that we can
actually benchmark and compare with the current situation, so that we
can make decisions based on actual data. Otherwise, it's just your word
against mine and my word against yours, which gets us nowhere.


T

-- 
If blunt statements had a point, they wouldn't be blunt...


More information about the Digitalmars-d mailing list