[Feature: trunk] ObjectSpace.count_nodes

e$B!!$5$5$@$G$9!%e(B

e$B!!e(BObjectSpace.count_objects
e$B$H$$$&!$%*%V%8%'%/%H$N<oN`$r?t$($k%a%=%C%I$,e(B
e$B$"$j$^$9$,!$F1$8$h$&$Ke(B ObjectSpace.count_nodes
e$B$H$$$&$b$N$r2C$($k$N$O$Ie(B
e$B$&$G$7$g$&$+!%e(B

e$B!!$$$d!$;H$&$N$OB?J,e(B Ruby
e$B3+H/<T$@$1$N$h$&$J5$$b$9$k$N$G!$@5D>$I$&$+$J$!e(B
e$B$H$b;W$&$s$G$9$,!%e(B

slot e$B$rA4It=d$k!$e(B st_each

e$B$_$?$$$J%$%s%?!<%U%'!<%9$,$"$l$P!$e(B

e$B3HD%%i%$%V%i%j$H$7$F<BAu$9$k$3$H$bIT2DG=$8$c$J$/$J$k!$e(B

e$B$1$I!$%3!<%k%P%C%/%Y!<%9$@$HCY$$$+$b$J$"!%e(B

e$BMxMQNc!'e(B
e$B!!Nc$($Pe(B benchmark/bm_pentomino.rb e$B$r<B9T$9$k$H!$$J$s$+e(B node
e$B$,Bt;3=PMhe(B
e$B$F$$$k$N$,J,$+$k$Ne(B (*1)
e$B$G!$$J$<$@$m$&$+$H2r@O$9$k$3$H$,=PMh$^$9e(B (*2)e$B!%e(B

1:
http://www.atdot.net/fp_store/f.89p1lk/file.g.png
Xe$B<4$,;~4V!$:8e(BYe$B<4$,%
%V%8%'%/%H?t!$1&e(BYe$B<4$,e(BGCe$B2s?te(B
1e$BIC$4$H$N%5%s%W%j%s%0!%e(B
node e$B$N?t$,e(B GC e$B2s?t$K1F6A$7$F$$$k$3$H$,$o$+$ke(B

2:
http://www.atdot.net/fp_store/f.eio1lk/file.g.png
Xe$B<4$,;~4V!$e(BYe$B<4$,>CHqNL!&e(BGCe$B2s?te(B
1e$BIC$4$H$N%5%s%W%j%s%0!%e(B
e$B$[$!$e(BNODE_LITe$B$N@[email protected]?t$Ke(BGCe$B2s?t$,0MB8$7$F$$$k$3$H$,$o$+$k!%e(B
NODE_LIT e$B$O!$<B$Oe(B break
e$B;~$K%F%s%]%i%j%
%V%8%'%/%H$H$7$F@8@.$5$l$ke(B
e$B$s$@$1$I!$e(Bpentomino e$B$G$Oe(B break
e$B$rBt;3$9$k$N$G!$$3$&$$$&$3$H$K$J$k!$e(B
e$B$H$$$&$3$H$,$o$+$C$?!%e(B

e$BM>CL!'e(B

e$B$8$c$!!$e(Bbreak e$B$N<BAu$rJQ$($l$P@-G=$,8~>e$9$k$+$H$$$&$H!$e(B

GC

e$B$N<B9T;~4V$Oe(B1e$BICCfe(B0.1e$BIC$/$i$$$J$N$G!$e(B1e$B3d$N@-G=8~>e$,8+9~$a$k!$e(B

e$B$+$b$7$l$J$$!%e(B

+static VALUE
+count_nodes(int argc, VALUE *argv, VALUE os)
+{

  • rb_objspace_t *objspace = &rb_objspace;
  • size_t nodes[NODE_LAST];
  • size_t i;
  • VALUE hash;
  • if (rb_scan_args(argc, argv, “01”, &hash) == 1) {
  •    if (TYPE(hash) != T_HASH)
    
  •        rb_raise(rb_eTypeError, "non-hash given");
    
  • }
  • for (i = 0; i <= NODE_LAST; i++) {
  • nodes[i] = 0;
  • }
  • for (i = 0; i < heaps_used; i++) {
  •    RVALUE *p, *pend;
    
  •    p = heaps[i].slot; pend = p + heaps[i].limit;
    
  •    for (;p < pend; p++) {
    
  •        if (p->as.basic.flags && BUILTIN_TYPE(p) == T_NODE) {
    
  • nodes[nd_type((NODE *)p)]++;
  •        }
    
  • }
  • }
  • if (hash == Qnil) {
  •    hash = rb_hash_new();
    
  • }
  • else if (!RHASH_EMPTY_P(hash)) {
  •    st_foreach(RHASH_TBL(hash), set_zero, hash);
    
  • }
  • for (i=0; i<NODE_LAST; i++) {
  • if (nodes[i] != 0) {
  •  VALUE node;
    
  •  switch (i) {
    

+#define COUNT_NODE(n) case n: node = ID2SYM(rb_intern(#n)); break;

  • COUNT_NODE(NODE_METHOD);
  • COUNT_NODE(NODE_FBODY);
  • COUNT_NODE(NODE_CFUNC);
  • COUNT_NODE(NODE_SCOPE);
  • COUNT_NODE(NODE_BLOCK);
  • COUNT_NODE(NODE_IF);
  • COUNT_NODE(NODE_CASE);
  • COUNT_NODE(NODE_WHEN);
  • COUNT_NODE(NODE_OPT_N);
  • COUNT_NODE(NODE_WHILE);
  • COUNT_NODE(NODE_UNTIL);
  • COUNT_NODE(NODE_ITER);
  • COUNT_NODE(NODE_FOR);
  • COUNT_NODE(NODE_BREAK);
  • COUNT_NODE(NODE_NEXT);
  • COUNT_NODE(NODE_REDO);
  • COUNT_NODE(NODE_RETRY);
  • COUNT_NODE(NODE_BEGIN);
  • COUNT_NODE(NODE_RESCUE);
  • COUNT_NODE(NODE_RESBODY);
  • COUNT_NODE(NODE_ENSURE);
  • COUNT_NODE(NODE_AND);
  • COUNT_NODE(NODE_OR);
  • COUNT_NODE(NODE_MASGN);
  • COUNT_NODE(NODE_LASGN);
  • COUNT_NODE(NODE_DASGN);
  • COUNT_NODE(NODE_DASGN_CURR);
  • COUNT_NODE(NODE_GASGN);
  • COUNT_NODE(NODE_IASGN);
  • COUNT_NODE(NODE_IASGN2);
  • COUNT_NODE(NODE_CDECL);
  • COUNT_NODE(NODE_CVASGN);
  • COUNT_NODE(NODE_CVDECL);
  • COUNT_NODE(NODE_OP_ASGN1);
  • COUNT_NODE(NODE_OP_ASGN2);
  • COUNT_NODE(NODE_OP_ASGN_AND);
  • COUNT_NODE(NODE_OP_ASGN_OR);
  • COUNT_NODE(NODE_CALL);
  • COUNT_NODE(NODE_FCALL);
  • COUNT_NODE(NODE_VCALL);
  • COUNT_NODE(NODE_SUPER);
  • COUNT_NODE(NODE_ZSUPER);
  • COUNT_NODE(NODE_ARRAY);
  • COUNT_NODE(NODE_ZARRAY);
  • COUNT_NODE(NODE_VALUES);
  • COUNT_NODE(NODE_HASH);
  • COUNT_NODE(NODE_RETURN);
  • COUNT_NODE(NODE_YIELD);
  • COUNT_NODE(NODE_LVAR);
  • COUNT_NODE(NODE_DVAR);
  • COUNT_NODE(NODE_GVAR);
  • COUNT_NODE(NODE_IVAR);
  • COUNT_NODE(NODE_CONST);
  • COUNT_NODE(NODE_CVAR);
  • COUNT_NODE(NODE_NTH_REF);
  • COUNT_NODE(NODE_BACK_REF);
  • COUNT_NODE(NODE_MATCH);
  • COUNT_NODE(NODE_MATCH2);
  • COUNT_NODE(NODE_MATCH3);
  • COUNT_NODE(NODE_LIT);
  • COUNT_NODE(NODE_STR);
  • COUNT_NODE(NODE_DSTR);
  • COUNT_NODE(NODE_XSTR);
  • COUNT_NODE(NODE_DXSTR);
  • COUNT_NODE(NODE_EVSTR);
  • COUNT_NODE(NODE_DREGX);
  • COUNT_NODE(NODE_DREGX_ONCE);
  • COUNT_NODE(NODE_ARGS);
  • COUNT_NODE(NODE_ARGS_AUX);
  • COUNT_NODE(NODE_OPT_ARG);
  • COUNT_NODE(NODE_POSTARG);
  • COUNT_NODE(NODE_ARGSCAT);
  • COUNT_NODE(NODE_ARGSPUSH);
  • COUNT_NODE(NODE_SPLAT);
  • COUNT_NODE(NODE_TO_ARY);
  • COUNT_NODE(NODE_BLOCK_ARG);
  • COUNT_NODE(NODE_BLOCK_PASS);
  • COUNT_NODE(NODE_DEFN);
  • COUNT_NODE(NODE_DEFS);
  • COUNT_NODE(NODE_ALIAS);
  • COUNT_NODE(NODE_VALIAS);
  • COUNT_NODE(NODE_UNDEF);
  • COUNT_NODE(NODE_CLASS);
  • COUNT_NODE(NODE_MODULE);
  • COUNT_NODE(NODE_SCLASS);
  • COUNT_NODE(NODE_COLON2);
  • COUNT_NODE(NODE_COLON3);
  • COUNT_NODE(NODE_DOT2);
  • COUNT_NODE(NODE_DOT3);
  • COUNT_NODE(NODE_FLIP2);
  • COUNT_NODE(NODE_FLIP3);
  • COUNT_NODE(NODE_ATTRSET);
  • COUNT_NODE(NODE_SELF);
  • COUNT_NODE(NODE_NIL);
  • COUNT_NODE(NODE_TRUE);
  • COUNT_NODE(NODE_FALSE);
  • COUNT_NODE(NODE_ERRINFO);
  • COUNT_NODE(NODE_DEFINED);
  • COUNT_NODE(NODE_POSTEXE);
  • COUNT_NODE(NODE_ALLOCA);
  • COUNT_NODE(NODE_BMETHOD);
  • COUNT_NODE(NODE_MEMO);
  • COUNT_NODE(NODE_IFUNC);
  • COUNT_NODE(NODE_DSYM);
  • COUNT_NODE(NODE_ATTRASGN);
  • COUNT_NODE(NODE_PRELUDE);
  • COUNT_NODE(NODE_LAMBDA);
  • COUNT_NODE(NODE_OPTBLOCK);
    +#undef COUNT_NODE
  •    default: node = INT2FIX(nodes[i]);
    
  •  }
    
  •  rb_hash_aset(hash, node, SIZET2NUM(nodes[i]));
    
  • }
  • }
  • return hash;
    +}

e$B$^$D$b$He(B e$B$f$-$R$m$G$9e(B

In message “Re: [ruby-dev:38584] [Feature: trunk]
ObjectSpace.count_nodes”
on Thu, 11 Jun 2009 08:05:56 +0900, SASADA Koichi [email protected]
writes:

|e$B!!e(BObjectSpace.count_objects e$B$H$$$&!$%*%V%8%'%/%H$N<oN`$r?t$($k%a%=%C%I$,e(B
|e$B$"$j$^$9$,!$F1$8$h$&$Ke(B ObjectSpace.count_nodes e$B$H$$$&$b$N$r2C$($k$N$O$Ie(B
|e$B$&$G$7$g$&$+!%e(B
|
|e$B!!$$$d!$;H$&$N$OB?J,e(B Ruby e$B3+H/<T$@$1$N$h$&$J5$$b$9$k$N$G!$@5D>$I$&$+$J$!e(B
|e$B$H$b;W$&$s$G$9$,!%e(B

e$B!Ve(Bnodee$B$,B8:_$9$k!W$H$$$&$N$OFCDj$N<BAu$K0MB8$9$kOC$G$9$N$G!“e(B
e$B%a%=%C%I$H$7$FDI2C$9$k$N$O$I$&$+$H;W$$$^$9!#4X?t$rMQ0U$7$Fe(B
e$B$*$$$F!“3HD%%i%$%V%i%j$G%a%=%C%I$H$7$FEPO?$9$k$J$i$”$j$J$s$8$ce(B
e$B$J$$$+$J$”!#e(B