[Rcpp-devel] USE_RINTERNALS and Rcpp

Hadley Wickham h.wickham at gmail.com
Mon Sep 23 18:24:04 CEST 2013


Thanks!

There's no way to make this less fragile (i.e. by using Defn.h),
right? (Because Defn.h isn't "exported" by R)

Hadley

On Mon, Sep 23, 2013 at 11:17 AM, Romain Francois
<romain at r-enthusiasts.com> wrote:
> 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
>



-- 
Chief Scientist, RStudio
http://had.co.nz/


More information about the Rcpp-devel mailing list