[Rcpp-devel] USE_RINTERNALS and Rcpp
Romain Francois
romain at r-enthusiasts.com
Mon Sep 23 18:17:38 CEST 2013
Hi,
I would not do that kind of internal things with Rcpp. Instead put code
from this gist https://gist.github.com/romainfrancois/6672944 on a .c
file and go old school about it:
$ R CMD SHLIB size.c
$ Rscript -e "dyn.load('size.so'); siz <- function(.) .Call( 'siz', .) ;
siz(1:10); siz(siz); siz(letters) "
[1] 88
[1] 600
[1] 1496
Romain
Le 23/09/13 17:45, Hadley Wickham a écrit :
> Hi all,
>
> Is it possible to access the R internals api through Rcpp? For
> example, I want to right my own version of object.size() that's aimed
> at detecting memory leaks, so it needs to recursively include the size
> of environments. The objectsize C function needs to access R internals
> to get the size of various vectors (BYTE2VEC, INT2VEC etc) - is there
> a way to accomplish the same thing through Rcpp? (Source code for
> objectsize included below)
>
> Thanks!
>
> Hadley
>
>
> static R_size_t objectsize(SEXP s)
> {
> R_size_t cnt = 0, vcnt = 0;
> SEXP tmp, dup;
> Rboolean isVec = FALSE;
>
> switch (TYPEOF(s)) {
> case NILSXP:
> return(0);
> break;
> case SYMSXP:
> break;
> case LISTSXP:
> case LANGSXP:
> case BCODESXP:
> cnt += objectsize(TAG(s));
> cnt += objectsize(CAR(s));
> cnt += objectsize(CDR(s));
> break;
> case CLOSXP:
> cnt += objectsize(FORMALS(s));
> cnt += objectsize(BODY(s));
> /* no charge for the environment */
> break;
> case ENVSXP:
> case PROMSXP:
> case SPECIALSXP:
> case BUILTINSXP:
> break;
> case CHARSXP:
> vcnt = BYTE2VEC(length(s)+1);
> isVec = TRUE;
> break;
> case LGLSXP:
> case INTSXP:
> vcnt = INT2VEC(xlength(s));
> isVec = TRUE;
> break;
> case REALSXP:
> vcnt = FLOAT2VEC(xlength(s));
> isVec = TRUE;
> break;
> case CPLXSXP:
> vcnt = COMPLEX2VEC(xlength(s));
> isVec = TRUE;
> break;
> case STRSXP:
> vcnt = PTR2VEC(xlength(s));
> dup = csduplicated(s);
> for (R_xlen_t i = 0; i < xlength(s); i++) {
> tmp = STRING_ELT(s, i);
> if(tmp != NA_STRING && !LOGICAL(dup)[i])
> cnt += objectsize(tmp);
> }
> isVec = TRUE;
> break;
> case DOTSXP:
> case ANYSXP:
> /* we don't know about these */
> break;
> case VECSXP:
> case EXPRSXP:
> case WEAKREFSXP:
> /* Generic Vector Objects */
> vcnt = PTR2VEC(xlength(s));
> for (R_xlen_t i = 0; i < xlength(s); i++)
> cnt += objectsize(VECTOR_ELT(s, i));
> isVec = TRUE;
> break;
> case EXTPTRSXP:
> cnt += sizeof(void *); /* the actual pointer */
> cnt += objectsize(EXTPTR_PROT(s));
> cnt += objectsize(EXTPTR_TAG(s));
> break;
> case RAWSXP:
> vcnt = BYTE2VEC(xlength(s));
> isVec = TRUE;
> break;
> case S4SXP:
> /* Has TAG and ATRIB but no CAR nor CDR */
> cnt += objectsize(TAG(s));
> break;
> default:
> UNIMPLEMENTED_TYPE("object.size", s);
> }
> /* add in node space:
> we need to take into account the rounding up that goes on
> in the node classes. */
> if(isVec) {
> cnt += sizeof(SEXPREC_ALIGN);
> if (vcnt > 16) cnt += 8*vcnt;
> else if (vcnt > 8) cnt += 128;
> else if (vcnt > 6) cnt += 64;
> else if (vcnt > 4) cnt += 48;
> else if (vcnt > 2) cnt += 32;
> else if (vcnt > 1) cnt += 16;
> else if (vcnt > 0) cnt += 8;
> } else cnt += sizeof(SEXPREC);
> /* add in attributes: these are fake for CHARSXPs */
> if(TYPEOF(s) != CHARSXP) cnt += objectsize(ATTRIB(s));
> return(cnt);
> }
--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30
More information about the Rcpp-devel
mailing list