Re: GC safety and return values
Michael Sperber 27 Dec 2003 16:10 UTC
>>>>> "Tom" == Tom Lord <xxxxxx@emf.net> writes:
Tom> jimb is correct.
Right. I misunderstood him. Thanks for the clarifying example!
Tom> Consider the code:
Tom> scheme_value x;
Tom> [...]
Tom> GCPRO(&x);
Tom> [...]
Tom> z = SCHEME_CONS (x, y); /* XXX */
Tom> during execution of the the statement marked "XXX", the sequence
Tom> over time of operations may be:
Tom> thread 1: thread 2:
Tom> |
Tom> reg1 = x; - t
Tom> reg2 = y; - i
Tom> - trigger GC m
Tom> call SCHEME_CONS - e
Tom> (on return, - |
Tom> reg1 holds new pair) - V
Tom> - trigger GC
Tom> z = reg1 -
Tom> At the first GC, a stop-and-copy GC will want to modify the values
Tom> stored in x and y, but it won't find reg1 and reg2.
Tom> At the second GC, a stop-and-copy GC will want to modify the value
Tom> about to be stored in z, but it won't find reg1.
Tom> That is one reason why it isn't sufficient to make sure that protected
Tom> scheme values are always stored in GCPROtected locations -- you must
Tom> also make sure that, other than in the internals of the FFI
Tom> implementation, they are not stored anywhere else.
Tom> You can make that guarantee by not passing or returning those values
Tom> directly at all -- but instead passing and returning "handles" for
Tom> those values.
Tom> Jimb and I have each shown a technique (so now you have two available)
Tom> for always passing and returning handles: in jimb's approach, handles
Tom> are separately allocated objects; in my approach, handles are the
Tom> addresses of GCPROtected values. So you have either:
Tom> scheme_value_handle x = 0;
Tom> scheme_value_handle y = 0;
Tom> scheme_value_handle z = 0;
Tom> [....]
Tom> z = SCHEME_CONS (this_call, x, y);
Tom> /* caller frees any handles allocated above. */
Tom> or:
Tom> struct my_frame
Tom> {
Tom> scheme_value x;
Tom> scheme_value y;
Tom> scheme_value z;
Tom> } f;
Tom> GCPRO_FRAME (f);
Tom> [...]
Tom> SCHEME_CONS (&f.z, this_instance, &f.x, &f.y);
Tom> /* eventual GCUNPRO_FRAME needed */
Tom> (As I said elsewhere, I think that there are some performance and,
Tom> more importantly, GC-precision advantages to the second approach.)
Tom> Either approach also has advantages for single-threaded systems simply
Tom> because they both make it harder to make certain kinds of mistakes
Tom> that will lead to subtle and difficult-to-reproduce GC bugs.
Tom> -t
--
Cheers =8-} Mike
Friede, Völkerverständigung und überhaupt blabla