Romain Francois
2010-Jan-02 10:07 UTC
[Rd] R_PreserveObject, R_ReleaseObject : reference counting needed ?
Hello, We are currently making lots of changes to Rcpp (see the open Rcpp mailing list if interested [1] in the details). We are now using [2] R_PreserveObject and R_ReleaseObject to manage garbage collection instead of the PROTECT/UNPROTECT dance. This seems to work well, but I was wondering if there was documentation about it. In particular, if we preserve the same SEXP twice (or more), should we implement some sort of reference counting ? Reading the source (below, from memory.c) I think not, but some confirmation would help. void R_PreserveObject(SEXP object) { R_PreciousList = CONS(object, R_PreciousList); } static SEXP RecursiveRelease(SEXP object, SEXP list) { if (!isNull(list)) { if (object == CAR(list)) return CDR(list); else CDR(list) = RecursiveRelease(object, CDR(list)); } return list; } void R_ReleaseObject(SEXP object) { R_PreciousList = RecursiveRelease(object, R_PreciousList); } I'd also be interested if there is some ideas on the relative efficiency of the preserve/release mechanism compared to PROTECT/UNPROTECT. Thanks, Romain [1] http://lists.r-forge.r-project.org/pipermail/rcpp-devel/ [2] http://r-forge.r-project.org/plugins/scmsvn/viewcvs.php/pkg/src/RObject.cpp?rev=255&root=rcpp&view=markup -- Romain Francois Professional R Enthusiast +33(0) 6 28 91 30 30 http://romainfrancois.blog.free.fr |- http://tr.im/IW9B : C++ exceptions at the R level |- http://tr.im/IlMh : CPP package: exposing C++ objects `- http://tr.im/HlX9 : new package : bibtex
Simon Urbanek
2010-Jan-02 17:01 UTC
[Rd] R_PreserveObject, R_ReleaseObject : reference counting needed ?
On Jan 2, 2010, at 5:07 AM, Romain Francois wrote:> Hello, > > We are currently making lots of changes to Rcpp (see the open Rcpp mailing list if interested [1] in the details). > > We are now using [2] R_PreserveObject and R_ReleaseObject to manage garbage collection instead of the PROTECT/UNPROTECT dance. This seems to work well, but I was wondering if there was documentation about it. >I don't think so - the only documentation is the comment in the source.> In particular, if we preserve the same SEXP twice (or more), should we implement some sort of reference counting ? >Preserve/Release are for managing objects that are supposed to survive past the call and are not tied to any other R object. PROTECT/UNPROTECT are for temporary preservation within a call. Although you're right that Preserve/Release is effectively implemented as a stack at the moment it is not stated explicitly anywhere (this goes all the way back to R 0.64 so chances are that only Ross can comment..). However, for practical purposes it would be potentially dangerous to have it work like a flag because you can simply never know whether the same object was not already registered by some other code.> Reading the source (below, from memory.c) I think not, but some confirmation would help. > > void R_PreserveObject(SEXP object) > { > R_PreciousList = CONS(object, R_PreciousList); > } > > static SEXP RecursiveRelease(SEXP object, SEXP list) > { > if (!isNull(list)) { > if (object == CAR(list)) > return CDR(list); > else > CDR(list) = RecursiveRelease(object, CDR(list)); > } > return list; > } > > void R_ReleaseObject(SEXP object) > { > R_PreciousList = RecursiveRelease(object, R_PreciousList); > } > > > I'd also be interested if there is some ideas on the relative efficiency of the preserve/release mechanism compared to PROTECT/UNPROTECT. >PROTECT/UNPROTECT is more efficient because all it does is a pointer assignment -- Preserve has to allocate new node and fill it with all parts. On release the extra node is still floating in the GC pool etc. Normally there is not really a question of choice - within a call you want to use PROTET/UNPROTECT and for anything else you simply cannot use it so you have to use Preserve/Release. As a side note Preserve/Release is merely a convenience call, it is often more efficient to simply assign the object to another object you have control of (which is all Preserve really does). Cheers, Simon
Maybe Matching Threads
- R-devel Digest, Vol 83, Issue 2
- Calling R_PreserveObject from embedded R
- A question about multiple(?) out of order ReleaseObject
- garbage collection, "preserved" variables, and different outcome depending on "--verbose" or not
- Big speedup in install.packages() by re-using connections