Re: [q-lang-users] Libqint and the stability of qexps
Brought to you by:
agraef
From: Albert G. <Dr....@t-...> - 2006-06-06 08:57:23
|
John Cowan wrote: > I'm wondering whether the Q garbage collector sometimes moves temporary > values about. Given the rule "double X = [X, X];" in the current script, > if you pass the qexp corresponding to "double [1,2,3]" to qevalx(), > are the components of the list that is returned guaranteed to be > C-pointer-equal to the list that is passed in? This would seem to be > true a priori, but I'd like to have it confirmed. Yes, they are. Expressions are never copied, always shared. And the garbage collector will never move expressions around, it only adds them to the freelist when they become inaccessible. (You should however count a reference to all Q expressions you want to keep in Scheme data structures, see below). NB: There is a (rather obscure) secondary gc in the Q interpreter which is only enabled with the --gc option. This is the usual kind of stop-and-copy gc which serves the purpose of defragmenting the heap and returning inaccessible expression memory to the system between different evaluations, and is a relict from the ancient times when Q needed to run on systems with <=640K of main memory. ;-) However, this isn't enabled by default, not needed on modern systems, and you can't enable that feature via libqint anyway. (I will probably also remove that --gc option in the near future.) > This is important for my Scheme-to-Q connector, since I'd like to memoize > the expression (and all its parts) being evaluated so that the elements > of the Scheme-level list are EQ? to the Scheme-level argument to "double", > rather than being newly constructed on the Scheme side. However, if this > is not reliable, I'll have to provide newly constructed lists instead. > > (I'm assuming that the argument is being passed in is a temporary value.) Note that if you keep pointers to temporary Q expressions (i.e., with a reference count of 0) in your Scheme data structures then those expressions may well be garbage-collected at any time during an evaluation. E.g., suppose you have constructed a temporary expression X, use it to construct the application Y = cst () X, and then you evaluate Y. The refcount of X goes up to 1 when Y is constructed but then becomes zero again when cst () X is reduced to () and Y is gc'ed by qeval(), at which point X is gc'ed, too. Therefore, to avoid nasty surprises, you should always count a reference (qnewref) to Q expressions which are stored somewhere. When the expression is to be destroyed (because, say, the hosting Scheme object is destroyed) then you just call qfreeref() and the Q interpreter will do the right thing with it. (Of course, you can also keep such expressions in the Q interpreter's global environment, using qdef(). This will automatically count a new reference and free the reference when the variable is undefined again.) HTH, Albert -- Dr. Albert Gr"af Dept. of Music-Informatics, University of Mainz, Germany Email: Dr....@t-..., ag...@mu... WWW: http://www.musikinformatik.uni-mainz.de/ag |