$BBh(B5$B>O(B $B%,!]%Y!<%8%3%l%/%7%g%s(B

$B%W%m%0%i%`$N

$BFMA3$@$,!"K\>O$r;O$a$k$K@hN)$A!"%W%m%0%i%`uBV$K$D(B $B$$$FM==,$r$7$F$*$3$&$H;W$&!#$3$N>O$G$O%3%s%T%e!<%?$NDc%l%Y%k$JItJ,$K$+(B $B$J$jF'$_9~$s$G$$$/$3$H$K$J$k$N$G!"$"$i$+$8$a$"$kDxEY$NCN<1$r;EF~$l$F$*(B $B$+$J$$$HB@EaBG$A$G$-$J$$$N$@!#$=$l$K$3$N8e$N>O$K$J$l$P$$$:$lI,MW$K$J$C(B $B$F$/$k!#$3$3$G0l2s$d$C$F$7$^$($P8e$,3Z$@!#(B

$B%;%0%a%s%H(B

$B0lHLE*$J(BC$B%W%m%0%i%`$G$O%a%b%j6u4V$NCf$K0J2<$NItJ,$r;}$D!#(B

  1. $B%F%-%9%HNN0h(B
  2. $B%9%?%F%#%C%/JQ?t$d%0%m!<%P%kJQ?t$NCV>l(B
  3. $B%^%7%s%9%?%C%/(B
  4. $B%R!<%W(B

$B%F%-%9%HNN0h$O%3!<%I$,CV$$$F$"$k$H$3$m!#FsHVL\$O8+$F$NDL$j!#%^%7%s%9%?%C(B $B%/$K$O4X?t$N0z?t$d%m!<%+%kJQ?t$,@Q$^$l$k!#%R!<%W$O(Bmalloc()$B$G3d$jEv$F$F(B $B$b$i$&$H$3$m$@!#(B

$B;0$D$a$N%^%7%s%9%?%C%/$K$D$$$F$b$&>/$7OC$=$&!#%^%7%s!V%9%?%C%/!W$H8@$&(B $B$/$i$$$@$+$iEvA3%9%?%C%/9=B$$r$7$F$$$k!#$D$^$j$I$s$I$s?7$7$$$b$N$r>e$K(B $B@Q$_=E$M$F$$$/!#int$B0l8D$J$I$N:Y$+(B $B$$C10L$G@Q$`$o$1$@$,!"O@M}E*$K8+$k$H$b$&>/$7Bg$-$$C10L$,$"$k!#$=$l$r(B $B%9%?%C%/%U%l!<%`!J(Bstack frame$B!K$H8@$&!#(B

$B%9%?%C%/%U%l!<%`$O0l$D$,4X?t8F$S=P$70l2s$KBP1~$7$F$$$k!#$D$^$j4X?t$r8F(B $B$V$H%9%?%C%/%U%l!<%`$r0l$D@Q$`!#(Breturn$B$9$k$H%9%?%C%/%U%l!<%`$r0l$D9_(B $B$m$9!#;W$$@Z$jC1=c2=$9$l$P%^%7%s%9%?%C%/$NMM;R$O?^(B1$B$N$h$&(B $B$K?^<($G$-$k!#(B

(macstack)
$B?^(B1: $B%^%7%s%9%?%C%/(B

$B$3$N?^$G$O%9%?%C%/$N@hC<$r!V>e!W$H=q$$$?$,!"%^%7%s%9%?%C(B $B%/$OI,$:$7$bDc0L%"%I%l%9$+$i9b0L%"%I%l%9$K?-$S$k$H$O8B$i$J$$!#Nc$($P(B x86$B%^%7%s$G$O%9%?%C%/$ODc0L%"%I%l%9$K8~$+$C$F?-$S$k!#(B

alloca()

malloc()$B$r;H$&$H%R!<%W>e$KG$0U$NBg$-$5$N%a%b%jNN0h$r$b$i$&$3$H$,$G$-$?!#(B alloca()$B$O$=$l$N%^%7%s%9%?%C%/HG$G$"$k!#$?$@$7(Bmalloc()$B$H0c$C$F(B alloca()$B$G3d$jEv$F$?%a%b%j$O2rJ|$7$J$/$F$$$$!#$"$k$$$O!"4X?t$N(Breturn$B$H(B $B$H$b$K2rJ|!V$5$l$F$7$^$&!W$H8@$C$?$[$&$,$$$$$@$m$&$+!#$@$+$i3d$jEv$F$?(B $BCM$r4X?t$NJV$jCM$K$7$?$j$9$k$3$H$O$G$-$J$$!#!V%m!<%+%kJQ?t$r;X$9%]%$%s(B $B%?$rJV$7$F$O$$$1$J$$!W$H$$$&$N$HF1$8$G$"$k!#(B

$B$3$3$^$G$O$$$$!#D9$5$r

$B$@$,@$$NCf$K$O%M%$%F%#%V$N(Balloca()$B$,$J$$4D6-$H$$$&$N$,$"$k!#$=$&$$$&>l(B $B9g$G$b(Balloca()$B$O;H$$$?$$$H;W$&?M$OB?$$$N$G!"F1$8F/$-$r$9$k4X?t$,(BC$B$G(B $B=q$$$F$"$C$?$j$9$k!#$?$@$3$N>l9g$O!V2rJ|$9$kI,MW$,$J$$!W$H$$$&FCD'$@$1(B $B$,e$K%a%b%j$r3d$jEv$F$F$/$l$k$H$O8B$i$J(B $B$$!#$H8@$&$+!"IaDL$Oalloca()$B$,

alloca()$B$r(BC$B$Gmalloc()$B$G%a%b%j$r3d$jEv$F$k!#$=$7$F(Balloca()$B$r8F$S=P$7$?4X?t$H(B $B3d$jEv$F$?%"%I%l%9$NAH$r%0%m!<%P%k$J%j%9%H$K3P$($5$;$F$*$/!#(B $B$"$H$Oalloca()$B$,8F$S=P$5$l$?$H$-$K$D$$$G$K$=$N%j%9%H$r%A%'%C%/$7!"(B $B4{$K=*N;$7$?4X?t$G3d$jEv$F$?%a%b%j$,$"$C$?$i(Bfree()$B$G2rJ|$9$l$P$$$$(B $B!J?^(B2$B!K!#(B

(calloca)
$B?^(B2: C$B$Galloca()$B$NF0$-(B

ruby$B$N(Bmissing/alloca.c$B$,$3$N%(%_%e%l!<%HHG(Balloca()$B$N

$B35MW(B

$B$3$3$+$i$,$h$&$d$/K\>O$N

GC$B$H$O(B

$B%*%V%8%'%/%H$OIaDL!"%a%b%j$N$&$($K$"$k!#EvA3$N5"7k$H$7$F!"%*%V%8%'%/%H$r(B $B$?$/$5$s:n$l$P%a%b%j$r$?$/$5$s;H$&!#%a%b%j$,L58B$K;H$($k$J$i2?$bLdBj(B $B$O$J$$$N$@$,!"8=/$76qBNE*$K8@$&$J$i$P!"(B malloc()$B$G$b$i$C$?%a%b%j$O(Bfree()$B$GJV$5$J$1$l$P$$$1$J$$!#(B

$B$7$+$7(Bmalloc()$B$H(Bfree()$B$N4IM}$rA4$F%W%m%0%i%^$K$d$i$;$k$H%W%m%0%i%^$O$H(B $B$F$bBgJQ$G$"$k!#FC$K%*%V%8%'%/%H;X8~%W%m%0%i%`$G$O%*%V%8%'%/%HF1;N$,Aj(B $B8_$K;2>H$7$"$C$F$$$F!"$I$N%?%$%_%s%0$G%a%b%j$r2rJ|$9$l$P$$$$$N$+$o$+$j(B $B$K$/$$!#(B

$B$=$3$G%,!<%Y!<%8%3%l%/%7%g%s$@!#(B $B%,!<%Y!<%8%3%l%/%7%g%s!J(Bgarbage collection$B!"0J2<(BGC$B!K$H$O!"(B $BI,MW$N$J$/$J$C$?(B $B%a%b%j$r<+F0E*$K8!=P$72rJ|$7$F$/$l$k5!G=$G$"$k!#(BGC$B$5$((B $B$"$l$P!V$$$D(Bfree()$B$7$?$i$$$$$s$@!

$B$H$3$m$G!"0JA02?$+$NK\$K!V;H$($k%a%b%j$,$3$^$.$l$K$J$C$F$$$k$N$r@0M}$9(B $B$k$N$,(BGC$B!W$H=q$$$F$"$C$?$N$r8+$?$3$H$,$"$k!#$3$l$O!V(B $B%3%s%Q%/%7%g%s!J(Bcompaction$B!K!W$H8@$&:n6H$@!#(B $B%3%s%Q%/%H$K$J$k$+$i%3%s%Q%/%7%g%s$G$"$k!#(B $B%3%s%Q%/%7%g%s$r$d$k$H%a%b%j%-%c%C%7%e$K%R%C%H$7$d$9$/$J$k$N$G%9%T!<%I(B $B%"%C%W$K$=$l$J$j$N8z2L$,$"$k$N$@$,!"$3$l$O(BGC$B$Nruby$B$N(BGC$B$b%3%s%Q%/%7%g%s$O$7$J$$!#(B

$B$G$O6qBNE*$K$I$s$J%7%9%F%`$G(BGC$B$,;H$($k$N$@$m$&$+!#(B C$B$d(BC++$B$G$O%"%I%*%s$H$7$F;H$($k(B Boehm GC\footnote{Boehm GC http://www.hpl.hp.com/personal/Hans_Boehm/gc}$B$H(B $B$$$&$b$N$,$"$k!#(B $B$^$?(BJava$B$d(BPerl$B!"(BPython$B!"(BC#$B!"(BEiffel$B$J$I:G6a$N8@8l$K$H$C$F$O(BGC$B$O(B $BI8=`AuHw$@!#$=$7$F$b$A$m$s(BRuby$B$K$b(BGC$B$,$"$k!#(B $BK\>O$G$O(Bruby$B$N(BGC$B$N>\:Y$rDI$C$F$$$3$&!#BP>]$H$J$k%U%!%$%k$O(Bgc.c$B$G$"$k!#(B

GC$B$H$O2?$r$9$k$3$H$+(B

GC$B$N%"%k%4%j%:%`$K$D$$$F@bL@$9$k$K$O$^$:!"!V(BGC$B$H$O2?$G$"$k$+!W$r(B $B@bL@$7$J$$$H$$$1$J$$!#$D$^$j!VI,MW$N$J$$%a%b%j!W$H$O$I$&$$$&>uBV$K(B $B$"$k%a%b%j$+!"$H$$$&$3$H$G$"$k!#(B

$BOC$r6qBNE*$K$9$k$?$a$K%*%V%8%'%/%H$H%j%s%/$@$1$K9=B$$rC1=c2=$7$h$&!#(B $B$D$^$j?^(B3$B$N$h$&$J>uBV$K$J$C$F$$$k!#(B

(objects)
$B?^(B3: $B%*%V%8%'%/%H(B

$B%0%m!<%P%kJQ?t$+$i;X$5$l$F$$$?$j!"8@8l$N%9%?%C%/>e$K$"$k%*%V%8%'%/%H$O(B $B$^$:!V3N

$B$3$l$r$b$&>/$7O@M}E*$K8@$&$H!"!V3N

(gcimage)
$B?^(B4: $BI,MW$J%*%V%8%'%/%H$HI,MW$G$J$$%*%V%8%'%/%H(B

$B@lLgMQ8l$@$H$3$N!V3N

$B%^!<%/(B&$B%9%$!<%W(B

GC$B$,:G=i$Kruby$B$N(BGC$B$b$3$N0l

$B%^!<%/(B&$B%9%$!<%W(BGC$B$N%$%a!<%8$O!VI,MW$J%*%V%8%'%/%H!W$NDj5A$K$+$J$j6a$$!#(B $B$^$:%k!<%H%*%V%8%'%/%H$K!V%^!<%/!W$rIU$1$k!#$=$7$F$3$l$r=PH/E@$H$7$F!"(B $B$=$3$+$iC)$l$k%*%V%8%'%/%H$KJRC<$+$i!V%^!<%/!W$r$D$1$F$$$/!#$3$NA4BN$,(B $B!V%^!<%/!W%U%'%$%:$@!#(B

$B$=$7$F$3$l0J>eC)$l$k%*%V%8%'%/%H$,$J$$!"$H$o$+$C$?$H$3$m$G%*%V%8%'%/%HN/$^$j$r(B $BA4It%A%'%C%/$7!"%^!<%/$N$D$$$F$$$J$$%*%V%8%'%/%H$rA4It2rJ|$9$k!J%9%$!<(B $B%W!K!#%9%$!<%W$O%^%$%s%9%$!<%Q$N(Bsweep$B!JA]=|$9$k!K$@!#(B

$BD9=j$OFsE@$G$"$k!#(B

$BC;=j$b$d$O$jFsE@!#(B

$B%(%G%#%?$N(BEmacs$B$r;H$C$F$$$k$H$H$-$I$-!V(BGarbage collecting...$B!W$H=P$F(B $BH?1~$,A4$/$J$/$J$k$3$H$,$"$k$N$@$,!"$=$N$H$-$K(BGC$B$r$d$C$F$$$k$N$G$"$k!#(B $B$3$l$OFsE@L\$NC;=j$,%b%m$K=P$kNc$@!#$?$@$7$3$NE@$O%"%k%4%j%:%`$rJQ$($k(B $B$3$H$G2~A1$G$-$k!J%$%s%/%j%a%s%?%k(BGC$B$H8@$&!K!#(B

$B%9%H%C%W(B&$B%3%T!<(B

$B%9%H%C%W(B&$B%3%T!<(BGC$B$O%^!<%/(B&$B%9%$!<%W(BGC$B$NJQ7A$G$"$k!#$^$:%*%V%8%'%/%HNN0h(B $B$rJ#?tMQ0U$9$k!#$3$3$G$OOC$rC1=c$K$9$k$?$a$KNN0h(BA$B$H(BB$B$NFs$D$H$7$h$&!#$=(B $B$7$FJRJ}$K!V(Bactive$B!W%^!<%/$rIU$1$F$*$-!"%*%V%8%'%/%H$r@8@.$9$k$H$-$O(B active$B$J$[$&$K$@$1:n$k!J?^(B5$B!K!#(B

(stop2)
$B?^(B5: $B%9%H%C%W(B&$B%3%T!

$B$$$6(BGC$B$,H/F0$7$?$i!"%^!<%/(B&$B%9%$!<%W$HF1$8$h$&$K%k!<%H$+$iC)$k!#$7$+$7(B $B%^!<%/$NBe$o$j$K%*%V%8%'%/%H<+BN$r$b$&0l$D$NNN0h$K0\F0$7$F$7$^$&(B $B!J?^(B6$B!K!#%j%s%/$rA4$FC)$j=*$($?$i(BA$B$K;D$C$?%*%V%8%'%/%H$O

(stop3)
$B?^(B6: $B%9%H%C%W(B&$B%3%T!

$B%9%H%C%W(B&$B%3%T!<(BGC$B$ND9=j$b$^$?FsE@$"$k!#(B

$BC;=j$bFsE@$@!#(B

$B@$$NCf$&$^$$$3$H$P$+$j$G$O$J$$$h$&$@!#(B

$B%j%U%!%l%s%9%+%&%s%H(B

$B%j%U%!%l%s%9%+%&%s%H$O$3$l$^$G$N$b$N$H$O>/$70c$$!"E~C#%A%'%C%/$r(B $B%3!<%I$N$"$A$3$A$KJ,;6$5$;$k$h$&$K$J$C$F$$$k!#(B

$B$^$:%*%V%8%'%/%H0l$D0l$D$K@0?t$N%+%&%s%?$rIU$1$k!#JQ?t$dG[Ns7PM3$G;2>H(B $B$9$k$H$-$O;2>H$9$k%*%V%8%'%/%H$N%+%&%s%?$rA}$d$9!#;2>H$9$k$N$r$d$a$?$i(B $BF1;~$K%+%&%s%?$r8:$i$9!#$=$l$G%+%&%s%?$,(B0$B$K$J$C$?$i2rJ|$9$k!#$=$l$,(B $B%j%U%!%l%s%9%+%&%s%H$H$$$&J}<0$G$"$k!J?^(B7$B!K!#(B

(refcnt)
$B?^(B7: $B%j%U%!%l%s%9%+%&%s%H(B

$B$3$NJ}<0$bD9=j$,FsE@!#(B

$B$=$7$FC;=j$bFsE@$@!#(B

$BFsE@L\$K$D$$$F2r@b$7$F$*$3$&!#%5%$%/%k!J(Bcycle$B!K$H$O(B $B?^(B8$B$N$h$&$K;2>H4X78$,=[4D$7$F$$$k>uBV$N$3$H$@!#(B $B$3$&$J$C$F$7$^$&$H%+%&%s%?$,8:$i$J$/$J$j!"@dBP$K2rJ|$5$l$J$/$J$k!#(B

(cycle)
$B?^(B8: $B%5%$%/%k(B

$B$A$J$_$K:G?7$N(BPython$B!J(B2.2$B!K$O%j%U%!%l%s%9%+%&%s%H(BGC$B$r;H$C$F$$$k$N$@$,(B $B%5%$%/%k$b2rJ|$G$-$k!#$7$+$7$=$l$O%j%U%!%l%s%9%+%&%s%H<+BN$NNO$G$O$J$/!"(B $B$H$-$I$-%^!<%/(B&$B%9%$!<%W(BGC$B$r$d$C$F%A%'%C%/$7$F$$$k$+$i$@!#(B

$B%*%V%8%'%/%H$N4IM}(B

ruby$B$N(BGC$B$O(BRuby$B%*%V%8%'%/%H$N$_$,BP>]$@!#$7$+$b(Bruby$B$,@8@.$7(B $B4IM}$7$F$$$k%*%V%8%'%/%H$G$J$$$H$$$1$J$$!#5U$K8@$&$H%f!<%6$,(B $B>!ruby$B$,2TF/Cf$@$m$&$H%a%b%j%j!<%/$r5/$3$9!#(B

void not_ok()
{
    malloc(1024);  /* $B%a%b%j$r$b$i$C$F$O

$B$7$+$70J2<$N4X?t$O%a%b%j%j!<%/$r5/$3$5$J$$!#(B

void this_is_ok()
{
    rb_ary_new();  /* Ruby$B$NG[Ns$r:n$C$F$O

rb_ary_new()$B$O$=$NCf$G(Bruby$B$N@5<0%$%s%?!<%U%'%$%9$r;H$C$F%a(B $B%b%j$r3d$jEv$F$k$N$G(Bruby$B$N(BGC$B$N4IM}2<$K$"$j!"(Bruby$B$,LLE]$r(B $B8+$F$/$l$k!#(B

struct RVALUE

$B%*%V%8%'%/%H$NFixnum Symbol nil true false$B$J$I$O(B $BNc30$@$,!"$7$D$3$/$J$k$N$G$=$l$O$$$A$$$A=q$+$J$$!#(B

$Bo$K$=$N6&MQBN$r2p$7$F07$&$h$&$K$J$C$F$$$k!#$=$N6&MQ(B $BBN$N@k8@$,$3$l$@!#(B

$B"'(BRVALUE

 211  typedef struct RVALUE {
 212      union {
 213          struct {
 214              unsigned long flags;   /* $B;H$o$l$F$$$J$$$H$-$O%<%m(B */
 215              struct RVALUE *next;
 216          } free;
 217          struct RBasic  basic;
 218          struct RObject object;
 219          struct RClass  klass;
 220          struct RFloat  flonum;
 221          struct RString string;
 222          struct RArray  array;
 223          struct RRegexp regexp;
 224          struct RHash   hash;
 225          struct RData   data;
 226          struct RStruct rstruct;
 227          struct RBignum bignum;
 228          struct RFile   file;
 229          struct RNode   node;
 230          struct RMatch  match;
 231          struct RVarmap varmap;
 232          struct SCOPE   scope;
 233      } as;
 234  } RVALUE;

(gc.c)

struct RVALUE$B$OMWAG$,0l$D$@$1$N9=B$BN$@!#(Bunion$B$rD>@\;H$o$J$$$N$O%G%P%C(B $B%0$d>-Mh$N3HD%$N$H$-$K4JC1$K%a%s%P$rA}$d$;$k$h$&$K$9$k$?$a$@$=$&$G$"$k!#(B

$B$^$:$O6&MQBN$N:G=i$NMWAG(Bfree.flags$B$KCmL\$7$h$&!#%3%a%s%H$K$O!V;H$o$l$F(B $B$$$J$$$H$-$O%<%m!W$H=q$$$F$"$k$,K\Ev$@$m$&$+!#$^$@;H$C$F$$$k%*%V%8%'%/(B $B%H$N(Bfree.flags$B$,6vA3(B0$B$K$J$k$3$H$O$J$$$N$@$m$&$+!#(B

$BBh(B2$B>O!X%*%V%8%'%/%H!Y$G8+$?$h$&$K!"A4$F$N%*%V%8%'%/%H9=B$BN$O(B struct RBasic$B$r:G=i$NMWAG$K;}$D!#$@$+$i6&MQBN$N$I$NMWAG$+$i%"%/%;%9$7$F$b(B obj->as.free.flags$B$O(Bobj->as.basic.flags$B$H=q$/$N$HF1$8$3$H$@!#$=$7$F(B $B%*%V%8%'%/%H$OI,$:%U%i%0$K9=B$BN7?%U%i%0!J(BT_STRING$B$J$I!K$r;}$A!"$7$+(B $B$b$=$N%U%i%0$OA4$F(B0$B0J30$J$N$G!"!V@8$-$F$$$k!W%*%V%8%'%/%H$N%U%i%0$,6v(B $BA3(B0$B$K$J$k$3$H$O$J$$!#$D$^$j%U%i%0$r(B0$B$K$9$k$3$H$G!V;`$K!W%*%V%8%'%/%H$r(B $BI=$9$N$OI,MW==J,$@$H3N$+$a$i$l$k!#(B

$B%*%V%8%'%/%H%R!<%W(B

$BA4$F$N%*%V%8%'%/%H9=B$BN$N$?$a$N%a%b%j$O%0%m!<%P%kJQ?t(B heaps$B$K$^$H$a$i$l$F$$$k!#0J2<$3$l$r%*%V%8%'%/%H%R!<%W$H8F$\$&!#(B

$B"'%*%V%8%'%/%H%R!<%W(B

 239  #define HEAPS_INCREMENT 10
 240  static RVALUE **heaps;
 241  static int heaps_length = 0;
 242  static int heaps_used   = 0;
 243
 244  #define HEAP_MIN_SLOTS 10000
 245  static int *heaps_limits;
 246  static int heap_slots = HEAP_MIN_SLOTS;

(gc.c)

heaps$B$O(Bstruct RVALUE$B$NG[Ns$NG[Ns$@!#(BheapS$B$@$+$i!"F~$C$F$$$kG[Ns(B $B0lK\0lK\$,(Bheap$B$@$m$&!#(Bheap$B$NMWAG0l$D0l$D$O(Bslot$B$G$"$k(B $B!J?^(B9$B!K!#(B

(heapitems)
$B?^(B9: heaps$B!"(Bheap$B!"(Bslot

heaps$B$ND9$5$O(Bheaps_length$B$G2DJQ!#$=$N$&$Aheaps_used$B!#(Bheap$B0lK\$ND9$5$OBP1~$9$k(Bheaps_limits[index]$B$K(B $BF~$C$F$$$k!#$D$^$j%*%V%8%'%/%H%R!<%W$N9=B$$O?^(B10$B$N$h$&$K$J$k(B $B$@$m$&!#(B

(heaps)
$B?^(B10: $B%a%b%j>e$KE83+$5$l$?(Bheaps$B$N35G0?^(B

$B$3$N9=B$$K$OI,A3@-$,$"$k!#Nc$($PA4$F$N9=B$BN$r0l$D$NG[Ns$KG[CV$9$k$H(B $B%a%b%j6u4V$O:G$b%3%s%Q%/%H$K$J$k$,!"%"%I%l%9$,JQ$o$C$F$7$^$&62$l$,$"$k(B $B$N$G(Brealloc()$B$G$-$J$$!#(BVALUE$B$OC1$J$k%]%$%s%?$@$+$i$@!#(B

$B$H$"$k(BJava$B$NVALUE$B$KAjEv$9$k$b$N$,%"%I%l%9$G$O$J$/$F%*%V%8%'%/(B $B%H$N%$%s%G%C%/%9$G!"%]%$%s%?%F!<%V%k$r7PM3$7$Fl9g$O(B $B%*%V%8%'%/%H%"%/%;%9$N$?$S$KG[Ns$N%$%s%G%/%7%s%0$,F~$k$N$GB?>/(B $B%Q%U%)!<%^%s%9$OMn$A$k!#(B

$B0lJ}(BRVALUE$B$X$N%]%$%s%?!J$D$^$j(BVALUE$B!K$N0ll9g$O$I$&$@$m(B $B$&$+!#$3$l$O0l8+$&$^$/$$$-$=$&$@$,!"(BGC$B$N$H$-$K:$$C$F$7$^$&!#$H$$$&$N$b!"(B $B$3$l$+$i>\$7$/=q$/$H$*$j!"(Bruby$B$N(BGC$B$G$O!V(BVALUE$B!J(BRVALUE$B$X$N%]%$%s%?!K$i(B $B$7$$!W@0?t$rCN$kI,MW$,$"$k$+$i$@!#A4$F$N(BRVALUE$B$,$F$s$G%P%i%P%i$N%"%I%l(B $B%9$KG[CV$5$l$F$$$k$H!"A4$F$N(BRVALUE$B$N%"%I%l%9$H!V%]%$%s%?$+$b$7$l$J$$!W(B $B@0?tA4$F$r$=$l$>$lHf3S$7$J$1$l$P$$$1$J$$!#$3$l$G$O(BGC$B$NB.EY$O(B O(n^2) $B0J(B $B>e$N%*!<%@!<$K$J$j!"MFG'$G$-$J$$!#(B

$B0J>e$N>r7o$+$i!"%*%V%8%'%/%H%R!<%W$O$"$kDxEY%"%I%l%9$K$^$H$^$j$,$"$j!"(B $B$7$+$b0LCV$HAmNL$O@)8B$5$l$J$$$h$&$J9=B$$K$9$k$N$,$h$$$H$$$&$o$1$@!#(B

freelist

$B;H$o$l$F$$$J$$(BRVALUE$B$O(Bfreelist$B$+$i;O$^$k%j%s%/(B $B%j%9%H$K0lK\$K$D$J$,$l$F4IM}$5$l$k!#(BRVALUE$B$N(Bas.free.next$B$O$=$N$?$a(B $B$K;H$&%j%s%/$@!#(B

$B"'(Bfreelist

 236  static RVALUE *freelist = 0;

(gc.c)

add_heap()

$B%G!<%?9=B$$,$o$+$C$?$H$3$m$G%R!<%W$rDI2C$9$k4X?t(Badd_heap()$B$rFI$s$G$_$h(B $B$&!#$3$N4X?t$O$d$?$i$HK\6Z0J30$N5-=R$,$&$k$5$$$N$G!"%(%i!<=hM}$d%-%c%9(B $B%H$r>J$$$F4JC1$K$7$?$b$N$r8+$;$k!#(B

$B"'(Badd_heap()$B!J4JLsHG!K(B

static void
add_heap()
{
    RVALUE *p, *pend;

    /* $BI,MW$J$i(Bheaps$B$r$N$P$9(B */
    if (heaps_used == heaps_length) {
        heaps_length += HEAPS_INCREMENT;
        heaps        = realloc(heaps,        heaps_length * sizeof(RVALUE*));
        heaps_limits = realloc(heaps_limits, heaps_length * sizeof(int));
    }

    /* heap$B$r0l$DA}$d$9(B */
    p = heaps[heaps_used] = malloc(sizeof(RVALUE) * heap_slots);
    heaps_limits[heaps_used] = heap_slots;
    pend = p + heap_slots;
    if (lomem == 0 || lomem > p) lomem = p;
    if (himem < pend) himem = pend;
    heaps_used++;
    heap_slots *= 1.8;

    /* $B3d$jEv$F$?(BRVALUE$B$r(Bfreelist$B$K$D$J$0(B */
    while (p < pend) {
        p->as.free.flags = 0;
        p->as.free.next = freelist;
        freelist = p;
        p++;
    }
}

$B0J2<$NE@$r3NG'$7$F$*$$$F$[$7$$!#(B

  • heap$B$ND9$5$O(Bheap_slots
  • $B$=$N(Bheap_slots$B$O(Bheap$B$,0l$DA}$($k$4$H$K(B1.8$BG\$K$J$C$F$$$/(B
  • heaps[i]$B$ND9$5!J%R!<%W@8@.;~$N(Bheap_slots$B$NCM!K$O(Bheaps_limits[i]$B$K3JG<$5$l$F$$$k(B

$B$^$?(Blomem$B$H(Bhimem$B$rJQ99$7$F$$$k$N$b$3$N4X?t$@$1$J$N$G!"$3$N4X?t$@$1$+$i(B $B;EAH$_$,M}2r$G$-$k!#$3$NJQ?t$K$O%*%V%8%'%/%H%R!<%W$N:G2<0L%"%I%l%9$H(B $B:G>e0L%"%I%l%9$,F~$C$F$$$k$N$G$"$k!#$3$NCM$O$"$H$G!V(BVALUE$B$C$]$$!W@0?t$r(B $BH=CG$9$k$H$-$K;H$&!#(B

rb_newobj()

$B0J>e$NE@$rAm9g$7$F9M$($l$P%*%V%8%'%/%H$r@8@.$9$kJ}K!$O$9$0$K$o$+$k!#(B freelist$B$K$D$J$,$l$F$$$k(BRVALUE$B$,$"$l$P$=$l$r;H$$!"$J$1$l$P(BGC$B$9$k$+!"(B $B%R!<%W$rA}$d$;$P$h$$!#%*%V%8%'%/%H@8@.$r9T$&4X?t(Brb_newobj()$B$rFI$s$G(B $B3N$+$a$F$_$h$&!#(B

$B"'(Brb_newobj()

 297  VALUE
 298  rb_newobj()
 299  {
 300      VALUE obj;
 301
 302      if (!freelist) rb_gc();
 303
 304      obj = (VALUE)freelist;
 305      freelist = freelist->as.free.next;
 306      MEMZERO((void*)obj, RVALUE, 1);
 307      return obj;
 308  }

(gc.c)

freelist$B$,(B0$B!"$D$^$jM>$j$N9=B$BN$,$J$$$J$i(BGC$B$r5/F0$7$FNN0h$r:n$k!#(B $B$b$70l$D$b%*%V%8%'%/%H$r2s<}$G$-$J$/$F$b!"(Brb_gc()$B$NCf$G?7$7$$(B $BNN0h$r3d$jEv$F$F$/$l$k$N$GLdBj$J$$!#$=$7$F(Bfreelist$B$+$i9=B$BN$r(B $B0l$DMEMZERO()$B$G(B0$B$r=

$B%^!<%/(B

$B@bL@$7$?$H$*$j!"(Bruby$B$N(BGC$B$O%^!<%/(B&$B%9%$!<%W$G$"$k!#%^!<%/$H$O6qBNE*$K$O(B FL_MARK$B%U%i%0$r%;%C%H$9$k$3$H$@!#;H$o$l$F$$$k(BVALUE$B$rC5$7$F$O(B FL_MARK$B$r%;%C%H$7!"$3$l$GA4ItD4$Y$?$H;W$C$?$i%*%V%8%'%/%H%R!<%W$r8+$F!"(B FL_MARK$B$,%;%C%H$5$l$F$$$J$$%*%V%8%'%/%H$r2rJ|$9$l$P$$$$!#(B

rb_gc_mark()

rb_gc_mark()$B$O%*%V%8%'%/%H$r:F5"E*$K%^!<%/$9$k4X?t$G$"$k!#(B

$B"'(Brb_gc_mark()

 573  void
 574  rb_gc_mark(ptr)
 575      VALUE ptr;
 576  {
 577      int ret;
 578      register RVALUE *obj = RANY(ptr);
 579
 580      if (rb_special_const_p(ptr)) return; /* special const not marked */
 581      if (obj->as.basic.flags == 0) return;       /* free cell */
 582      if (obj->as.basic.flags & FL_MARK) return;  /* already marked */
 583
 584      obj->as.basic.flags |= FL_MARK;
 585
 586      CHECK_STACK(ret);
 587      if (ret) {
 588          if (!mark_stack_overflow) {
 589              if (mark_stack_ptr - mark_stack < MARK_STACK_MAX) {
 590                  *mark_stack_ptr = ptr;
 591                  mark_stack_ptr++;
 592              }
 593              else {
 594                  mark_stack_overflow = 1;
 595              }
 596          }
 597      }
 598      else {
 599          rb_gc_mark_children(ptr);
 600      }
 601  }

(gc.c)

$B$^$:(BRANY()$B$NDj5A$O$3$&$@!#FC$K$?$$$7$?$b$N$G$O$J$$!#(B

$B"'(BRANY()

 295  #define RANY(o) ((RVALUE*)(o))

(gc.c)

$B:G=i$K%]%$%s%?$G$J$$$b$N$d4{$K2rJ|$7$?%*%V%8%'%/%H$N%A%'%C%/!"(B $B%^!<%/$5$l$?%*%V%8%'%/%H$N:F5"%A%'%C%/$,$"$j!"(B

obj->as.basic.flags |= FL_MARK;

$B$G(Bobj$B!J$D$^$j4X?t$N0z?t(Bptr$B!K$,%^!<%/$5$l$k!#(B $B$=$&$7$?$iobj$B$+$i=P$F$$$k;2>H$rC)$C$F%^!<%/$9$kHV$G$"$k!#(B rb_gc_mark_children()$B$,$=$l$@!#(B

$B$=$NB>$N!"(BCHECK_STACK()$B$+$i;O$^$C$F$$$m$$$m$H=q$$$F$"$k$N$O%^%7%s%9%?%C(B $B%/0n$l$rKI$0$?$a$N;E3]$1$G$"$k!#(Brb_gc_mark()$B$O:F5"8F$S=P$7$r;H$C$F%*%V(B $B%8%'%/%H$r%^!<%/$9$k$?$a!"Bg$-$J%*%V%8%'%/%H%/%i%9%?$,$"$k$H%^%7%s%9%?%C(B $B%/$ND9$5$,B-$j$J$/$J$k$3$H$,$"$k!#$=$3$G%9%?%C%/$,0n$l$=$&$@$C$?$i:F5"(B $B$rCf;_$7$F%*%V%8%'%/%H$r%0%m!<%P%k$J%j%9%H$K@Q$s$G$*$-!"$"$H$+$i$b$&0l(B $BEY%^!<%/$7$J$*$9$h$&$K$7$F$$$k$N$@!#(B $B$3$N%3!<%I$OK\6Z$G$O$J$$$N$G>JN,$9$k!#(B

rb_gc_mark_children()

$B$5$F!"(Brb_gc_mark_children()$B$@$,!"(B $BFbIt$N7?$r$R$?$9$iJB$Y$FCOF;$K%^!<%/$7$F$$$k$@$1$J$N$GD9$$$&$($K(B $BLLGr$/$J$$!#$3$3$G$OC1=c$JNs5sItJ,$O>JN,$7$F:\$;$k!#(B

$B"'(Brb_gc_mark_children()

 603  void
 604  rb_gc_mark_children(ptr)
 605      VALUE ptr;
 606  {
 607      register RVALUE *obj = RANY(ptr);
 608
 609      if (FL_TEST(obj, FL_EXIVAR)) {
 610          rb_mark_generic_ivar((VALUE)obj);
 611      }
 612
 613      switch (obj->as.basic.flags & T_MASK) {
 614        case T_NIL:
 615        case T_FIXNUM:
 616          rb_bug("rb_gc_mark() called for broken object");
 617          break;
 618
 619        case T_NODE:
 620          mark_source_filename(obj->as.node.nd_file);
 621          switch (nd_type(obj)) {
 622            case NODE_IF:         /* 1,2,3 */
 623            case NODE_FOR:
 624            case NODE_ITER:
                /* $B!D!D!D!D>JN,!D!D!D!D(B */
 749          }
 750          return;   /* basic.klass$B$O%^!<%/$7$J$/$F$h$$(B */
 751      }
 752
 753      rb_gc_mark(obj->as.basic.klass);
 754      switch (obj->as.basic.flags & T_MASK) {
 755        case T_ICLASS:
 756        case T_CLASS:
 757        case T_MODULE:
 758          rb_gc_mark(obj->as.klass.super);
 759          rb_mark_tbl(obj->as.klass.m_tbl);
 760          rb_mark_tbl(obj->as.klass.iv_tbl);
 761          break;
 762
 763        case T_ARRAY:
 764          if (FL_TEST(obj, ELTS_SHARED)) {
 765              rb_gc_mark(obj->as.array.aux.shared);
 766          }
 767          else {
 768              long i, len = obj->as.array.len;
 769              VALUE *ptr = obj->as.array.ptr;
 770
 771              for (i=0; i < len; i++) {
 772                  rb_gc_mark(*ptr++);
 773              }
 774          }
 775          break;

            /* $B!D!D!D!D>JN,!D!D!D!D(B */

 837        default:
 838          rb_bug("rb_gc_mark(): unknown data type 0x%x(0x%x) %s",
 839                 obj->as.basic.flags & T_MASK, obj,
 840                 is_pointer_to_heap(obj) ? "corrupted object"
                                             : "non object");
 841      }
 842  }

(gc.c)

rb_gc_mark()$B$r:F5"8F$S=P$7$7$F$$$k$J!"$H$$$&$3$H$@$13NG'$7$F$b$i$($P(B $B$=$l$G$h$$!#>JN,$7$?ItJ,$K$O(BNODE$B$H(BT_xxxx$B$,$=$l$>$lNs5s$5$l$F$$$k!#(B NODE$B$N$3$H$OBhFsIt$G>R2p$9$k!#(B

$B$=$l$H(BT_DATA$B!J3HD%%i%$%V%i%j$K;H$&9=B$BN!K$N%^!<%/$NItJ,$@$1$O3NG'$7$?(B $B$$$3$H$,$"$k$N$G8+$F$*$3$&!#$3$N%3!<%I$OFs$D$a$N(Bswitch$BJ8$+$iH4?h$7$?!#(B

$B"'(Brb_gc_mark_children()$B!](BT_DATA

 789        case T_DATA:
 790          if (obj->as.data.dmark) (*obj->as.data.dmark)(DATA_PTR(obj));
 791          break;

(gc.c)

$B$3$3$O(Brb_gc_mark()$B$d$=$NN`;w$N4X?t$G$O$J$/!"%f!<%6$+$i$b$i$C$?4X?t(B dmark$B$r;H$C$F$$$k!#$=$NCf$G$O$b$A$m$s(Brb_gc_mark()$B$J$j$J$s$J$j$r;H(B $B$&$@$m$&$,!";H$o$J$$$3$H$b$"$j$&$k!#Nc$($P6KC<$J>l9g$G8@$&$H!"%f!<%6(B $BDj5A$N%*%V%8%'%/%H$K(BVALUE$B$,F~$C$F$$$J$$$J$i%^!<%/$9$kI,MW$O$J$$$@$m$&!#(B

rb_gc()

$B$3$3$^$G$G%*%V%8%'%/%HC10L$NOC$O:Q$s$@$N$G!"$3$3$+$i$OA4BN$rE}3m$9$k4X?t(B rb_gc()$B$r8+$F$$$/$3$H$K$9$k!#$3$3$G%^!<%/$7$F$$$k$N$,!VI,MW$@$H$$$&$3$H$,(B $BL@$i$+$KJ,$+$C$F$$$k%*%V%8%'%/%H!W$D$^$j!V(BGC$B$N%k!<%H!W$@!#(B

$B"'(Brb_gc()

1110  void
1111  rb_gc()
1112  {
1113      struct gc_list *list;
1114      struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug??  */
1115      jmp_buf save_regs_gc_mark;
1116      SET_STACK_END;
1117
1118      if (dont_gc || during_gc) {
1119          if (!freelist) {
1120              add_heap();
1121          }
1122          return;
1123      }

          /* $B!D!DA4$F$N%k!<%H$r%^!<%/$9$k!D!D(B */

1183      gc_sweep();
1184  }

(gc.c)

$B%^!<%/$9$Y$-%k!<%H$O$3$N8e$G=gHV$K8+$;$F$$$/$,!"0lE@$@$1?($l$F$*$3$&!#(B

ruby$B$G$O(BCPU$B$N%l%8%9%?$d%^%7%s%9%?%C%/$b%k!<%H$H$9$k!#(B $B$=$l$O$D$^$j(BC$B$N%m!<%+%kJQ?t$d0z?t$b>!

static int
f(void)
{
    VALUE arr = rb_ary_new();

    /* $B!D!D$$$m$$$m$9$k!D!D(B */
}

$B$H$$$&$h$&$K!"$?$@JQ?t$KF~$l$F$*$/$@$1$G$=$N%*%V%8%'%/%H$OJ]8n$5$l$k$N(B $B$@!#$3$l$O(Bruby$B$N(BGC$B$NHs>o$KBg$-$JFCD'$G$"$k!#$3$N5!G=$,$"$k$+$i$3$=(B ruby$B$N3HD%%i%$%V%i%j$O0[MM$K=q$-0W$/$J$C$F$$$k$N$@!#(B

$B$?$@$7$b$A$m$s%9%?%C%/$KCV$+$l$F$$$k$N$O(BVALUE$B$P$+$j$G$O$J$$!#2?$N4X78$b(B $B$J$$CM$b$?$/$5$sB8:_$9$k!#$=$N$"$?$j$r$I$&$d$C$F2r7h$7$F$$$k$N$+$,(BGC$B$N(B $B

Ruby$B%9%?%C%/(B

$B:G=i$O%$%s%?%W%j%?$,;H$C$F$$$k!J(Bruby$B$N!K%9%?%C%/%U%l!<%`$r(B $B%^!<%/$9$k!#Bh;0It$^$G9T$1$P$3$l$,2?

$B"'(BRuby$B%9%?%C%/$N%^!<%/(B

1130      /* mark frame stack */
1131      for (frame = ruby_frame; frame; frame = frame->prev) {
1132          rb_gc_mark_frame(frame);
1133          if (frame->tmp) {
1134              struct FRAME *tmp = frame->tmp;
1135              while (tmp) {
1136                  rb_gc_mark_frame(tmp);
1137                  tmp = tmp->prev;
1138              }
1139          }
1140      }
1141      rb_gc_mark((VALUE)ruby_class);
1142      rb_gc_mark((VALUE)ruby_scope);
1143      rb_gc_mark((VALUE)ruby_dyna_vars);

(gc.c)

ruby_frame ruby_class ruby_scope ruby_dyna_vars$B$,$=$l$>$lI>2A4o$N(B $B%9%?%C%/$N@hF,$r;X$9JQ?t$G!"$=$l$>$l$=$N;~E@$G$N%U%l!<%`!"%/%i%9%9%3!<%W!"(B $B%m!<%+%kJQ?t%9%3!<%W!"%V%m%C%/%m!<%+%kJQ?t$rJ];}$7$F$$$k!#(B

$B%l%8%9%?(B

$B

$B"'%l%8%9%?$N%^!<%/(B

1148      FLUSH_REGISTER_WINDOWS;
1149      /* $B$3$3$GA4$F$N%l%8%9%?$,(Bjmp_buf$B$KJ]B8$5$l$J$1$l$P$J$i$J$$(B */
1150      setjmp(save_regs_gc_mark);
1151      mark_locations_array((VALUE*)save_regs_gc_mark,
                               sizeof(save_regs_gc_mark) / sizeof(VALUE *));

(gc.c)

FLUSH_REGISTER_WINDOWS$B$OFC

setjmp()$B$OK\Ev$O1s3V%8%c%s%W$N$?$a$N4X?t$J$N$@$1$I!"(B $B$=$NI{:nMQ$H$7$F0z?t!J(Bjmp_buf$B7?$NJQ?t!K$K%l%8%9%?$NFbMF$r(B $BJ]B8$9$k$h$&$K$J$C$F$$$k!#(B $B$=$l$rMxMQ$7$F%l%8%9%?$NCf?H$r%^!<%/$7$h$&$H$$$&$o$1$@!#(B $B$3$N$"$?$j$O$+$J$jN"5;$C$]$$!#(B

$B$?$@$7(Bdjgpp$B$H(BHuman68k$B$@$1$OFCJL07$$$5$l$F$$$k!#(B djgpp$B$H$$$&$N$O(BDOS$BMQ$N(Bgcc$B4D6-!#(B Human68k$B$O%7%c!<%W$N(BX680x0$B%7%j!<%:$N(BOS$B$@!#(B $B$3$NFs$D$N4D6-$G$ODL>o$N(Bsetjmp()$B$G$OA4$F$N%l%8%9%?$,=q$-$3$^$l$J$$$h(B $B$&$G!"(Bsetjmp()$B$r0J2<$N$h$&$K%$%s%i%$%s%"%;%s%V%i$G:FDj5A$7$FL@<(E*$K%l%8%9%?$r=q$-=P$7(B $B$F$$$k!#(B

$B"'%*%j%8%J%kHG(Bsetjmp

1072  #ifdef __GNUC__
1073  #if defined(__human68k__) || defined(DJGPP)
1074  #if defined(__human68k__)
1075  typedef unsigned long rb_jmp_buf[8];
1076  __asm__ (".even\n\                   2$B%P%$%H%"%i%$%s%a%s%H(B
1077  _rb_setjmp:\n\                       $B4X?t(Brb_setjmp()$B$N%i%Y%k(B
1078          move.l  4(sp),a0\n\          $BBh0l0z?t$r%l%8%9%?(Ba0$B$K%m!<%I(B
1079          movem.l d3-d7/a3-a5,(a0)\n\  a0$B$N;X$9@h$K%l%8%9%?$r%3%T!<(B
1080          moveq.l #0,d0\n\             d0$B$K(B0$B$r%;%C%H!JJV$jCM!K(B
1081          rts");                       return
1082  #ifdef setjmp
1083  #undef setjmp
1084  #endif
1085  #else
1086  #if defined(DJGPP)
1087  typedef unsigned long rb_jmp_buf[6];
1088  __asm__ (".align 4\n\                4$B%P%$%H%"%i%$%s%a%s%H$r;X<((B
1089  _rb_setjmp:\n\                       $B4X?t(Brb_setjmp()$B$N%i%Y%k(B
1090          pushl   %ebp\n\              ebp$B$r%9%?%C%/$K%W%C%7%e(B
1091          movl    %esp,%ebp\n\         $B%9%?%C%/%]%$%s%?$r(Bebp$B$K%;%C%H(B
1092          movl    8(%ebp),%ebp\n\      $BBh0l0z?t$r=&$$(Bebp$B$K%;%C%H(B
1093          movl    %eax,(%ebp)\n\       $B0J2


$B%"%i%$%s%a%s%H!J(Balignment$B!K$H$$$&$N$O%a%b%j$KJQ?t$rCV$/$H$-$N(B $B@)Ls$N$3$H$@!#(B $BNc$($P(B32$B%S%C%H%^%7%s$G$OIaDL(Bint$B$O(B32$B%S%C%H$@$,!"%a%b%j$N$I(B $B$3$+$i$G$b(B32$B%S%C%H

$B$^$?(Bdjgpp$B$d(BHuman68k$B$N(Bcc$B$G$O%3%s%Q%$%i$,4X?tL>$N@hF,$K%"%s%@!<%i%$%s$r(B $BIU$1$k5,Ls$,$"$k$h$&$@!#$@$+$i%"%;%s%V%i$G(BC$B$N4X?t$r=q$/$H$-$O<+J,$G@h(B $BF,$K%"%s%@!<%i%$%s!J(B_$B!K$rIU$1$J$1$l$P$J$i$J$$!#$3$N%?%$%W$N5,Ls$O%i%$(B $B%V%i%j4X?t$HL>A0$,=EJ#$7$J$$$h$&$K$9$k$?$a$N9)IW$@!#(BUNIX$B$G$b>/$7A0$^$G$O(B $B%"%s%@!<%i%$%s$rIU$1$F$$$?$=$&$@$,:#$O$[$\$J$/$J$C$F$$$k!#(B

$B$5$F$3$3$^$G$G%l%8%9%?$NCf?H$r(Bjmp_buf$B$K=q$-$@$;$?$N$G!"(B $B

$B"'%l%8%9%?$N%^!<%/!J:F7G!K(B

1151      mark_locations_array((VALUE*)save_regs_gc_mark,
                               sizeof(save_regs_gc_mark) / sizeof(VALUE *));

(gc.c)

mark_locations_array()$B$H$$$&$N$,=i$a$F=P$F$-$?!#(B $B$3$l$OJL9`L\$H$7$F8+$F$*$3$&!#(B

mark_locations_array()

$B"'(Bmark_locations_array()

 500  static void
 501  mark_locations_array(x, n)
 502      register VALUE *x;
 503      register long n;
 504  {
 505      while (n--) {
 506          if (is_pointer_to_heap((void *)*x)) {
 507              rb_gc_mark(*x);
 508          }
 509          x++;
 510      }
 511  }

(gc.c)

$B$3$N4X?t$OG[Ns$r$^$H$a$F%^!<%/$9$k$?$a$N4X?t$J$N$@$,!"$3$l$^$G$N%^!<%/(B $B4X?t$H$O>/$70c$&!#$3$l$^$G$O3NVALUE$B$,$"$k!J%*%V%8%'%/%H$r;X$9%]%$(B $B%s%?$@!K$H$o$+$C$F$$$k>l=j$r%^!<%/$7$F$-$?!#$7$+$7:#EY%^!<%/$7$h$&$H$7(B $B$F$$$k$N$O%l%8%9%?NN0h$G!"$3$3$K$O(BVALUE$B0J30$N$b$N$,$"$k$3$H$b==J,9M$((B $B$i$l$k!#$=$3$G!"$^$:$=$N?tCM$,(BVALUE$B$G$"$k$+!J%]%$%s%?$G$"$k$+!K$I$&$+(B $BD4$Y$F$_$F!"$=$l$i$7$/8+$($k$J$i$PA4$F%]%$%s%?$H$7$F07$&$3$H$K$9$k!#(B $B$3$N$h$&$J

$B$G$OVALUE$B$C$]$$$+$I$&$+!W$rD4$Y$k4X?t(B is_pointer_to_heap()$B$r8+$h$&!#(B

is_pointer_to_heap()

$B"'(Bis_pointer_to_heap()

 480  static inline int
 481  is_pointer_to_heap(ptr)
 482      void *ptr;
 483  {
 484      register RVALUE *p = RANY(ptr);
 485      register RVALUE *heap_org;
 486      register long i;
 487
 488      if (p < lomem || p > himem) return Qfalse;
 489
 490      /* p$B$,%]%$%s%?$G$"$k2DG=@-$,$"$k$+D4$Y$k(B */
 491      for (i=0; i < heaps_used; i++) {
 492          heap_org = heaps[i];
 493          if (heap_org <= p && p < heap_org + heaps_limits[i] &&
 494              ((((char*)p)-((char*)heap_org))%sizeof(RVALUE)) == 0)
 495              return Qtrue;
 496      }
 497      return Qfalse;
 498  }

(gc.c)

$B4JC1$K@bL@$9$k$H

  1. RVALUE$B$,$"$k%"%I%l%9$N:G2eC<$N4V$K$"$k$+D4$Y$k(B
  2. $B3F%R!<%W$NHO0OFb$K$"$k$+$I$&$+D4$Y$k(B
  3. $B$=$N?tCM$,(BRVALUE$B$N@hF,$r;X$7$F$$$k$+$I$&$+3N$+$a$k(B

$B$3$N$h$&$J;EAH$_$J$N$G!"4V0c$C$FK\Ev$O(BVALUE$B$G$J$$CM$r(BVALUE$B$H(B $B07$C$F$7$^$&$3$H$bEvA3$"$k!#$7$+$7>/$J$/$H$b;H$C$F$$$k(B VALUE$B$r8+IU$1$i$l$J$$$3$H$O$J$$!#(B $B$=$l$b$3$l$@$1$N%F%9%H$r$7$F$$$l$P0U?^E*$G$J$$(B $B8B$j$=$&$=$&(BVALUE$B$G$J$$CM$r=&$&$3$H$O$J$$$H;W$o$l$k$N$G!"(BGC$B$G(B $BF@$i$l$kMxE@$r9M$($l$P==J,$KBE6($G$-$k!#$H$$$&$o$1$@!#(B

$B%l%8%9%?%&%#%s%I%&(B

$B:G8e$K8e2s$7$K$7$F$*$$$?(BFLUSH_REGISTER_WINDOWS()$B$K$D$$$F!#(B

$B%l%8%9%?%&%#%s%I%&!J(Bregister windows$B!K$H$O%^%7%s%9%?%C%/$N0lIt$r(BCPU$B$N(B $BCf$KCV$$$F$*$/$3$H$,$G$-$k5!9=$G$"$k!#$h$&$9$k$KMQES$r9J$C$?%-%c%C%7%e(B $B$@!#:G6a$O(BSparc$B%"!<%-%F%/%A%c$K$7$+B8:_$7$J$$!#%l%8%9%?%&%#%s%I%&$K$b(B VALUE$B$,F~$C$F$$$k2DG=@-$,$"$k$N$G!"$3$l$bA0$b$C$F%a%b%j$KMn$H$7$F$*$/(B $BI,MW$,$"$k!#(B

$B%^%/%m$NCf?H$O$3$s$J46$8$@!#(B

$B"'(BFLUSH_REGISTER_WINDOWS

 125  #if defined(sparc) || defined(__sparc__)
 126  # if defined(linux) || defined(__linux__)
 127  #define FLUSH_REGISTER_WINDOWS  asm("ta  0x83")
 128  # else /* Solaris, not sparc linux */
 129  #define FLUSH_REGISTER_WINDOWS  asm("ta  0x03")
 130  # endif
 131  #else /* Not a sparc */
 132  #define FLUSH_REGISTER_WINDOWS
 133  #endif

(defines.h)

asm(...)$B$OKd$a9~$_(B $B%"%;%s%V%i$@!#$?$@$7%"%;%s%V%i$H$O8@$C$F$b$3$N(Bta$B$H$$$&L?Na$O(B $BFC8"L?Na$N(B $B%3!<%k!"$D$^$j(BCPU$B$G$J$/(BOS$B$N8F$S=P$7$G$"$k!#$@$+$i$3$=(BOS$B$4$H$KL?Na$,(B $B0c$&$N$@!#$J$*!"%3%a%s%H$K$O(BLinux$B$H(BSolaris$B$7$+=q$$$F$$$J$$$,

$B$=$l$H!"(BSparc$B$G$J$$>l9g$O$=$b$=$b%U%i%C%7%e$9$kI,MW$,$J$$$N$G!"(B FLUSH_REGISTER_WINDOWS$B$rL5$HDj5A$7$F$$$k!#$3$N$h$&$J!"(B $B%^%/%m$rL5$K4T$9

$B%^%7%s%9%?%C%/(B

$B$G$O$^$?(Brb_gc()$B$NB3$-$KLa$m$&!#:#EY$O%^%7%s%9%?%C%/$KCV$+$l$?(B VALUE$B$r%^!<%/$9$k!#(B

$B"'%^%7%s%9%?%C%/$N%^!<%/(B

1152      rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END);
1153  #if defined(__human68k__)
1154      rb_gc_mark_locations((VALUE*)((char*)rb_gc_stack_start + 2),
1155                           (VALUE*)((char*)STACK_END + 2));
1156  #endif

(gc.c)

rb_gc_stack_start$B$,%9%?%C%/$N3+;O%"%I%l%9!J%9%?%C%/$NKvHx!K$G(B STACK_END$B$,=*N;%"%I%l%9!J@hCrb_gc_mark_locations()$B$,

rb_gc_mark_locations()$B$,Fs2s$"$k$N$O%9%?%C%/$,(B4$B%P%$%H%"%i%$%s%a%s%H$G(B $B$J$$%"!<%-%F%/%A%c$X$NBP:v$G$"$k!#(Brb_gc_mark_locations()$B$O(B sizeof(VALUE)$BC10L$G%^!<%/$r;n$9$N$G!"(B2$B%P%$%H%"%i%$%s%a%s%H$N4D6-$@$H$&(B $B$^$/%^!<%/$G$-$J$$$3$H$,$"$k!#$=$3$G(B2$B%P%$%H%:%i$7$F$b$&0lEY%^!<%/$9$k(B $B$o$1$@!#(B

$B$G$O(Brb_gc_stack_start$B!"(BSTACK_END$B!"(Brb_gc_mark_locations()$B$N(B $B;0$D$r=gHV$K8+$F$$$3$&!#(B

Init_stack()

$B:G=i$O(Brb_gc_stack_start$B$@!#$3$NJQ?t$O(BInit_stack()$BCf$G$@$1%;%C%H$5(B $B$l$k!#(BInit_$B$H$$$&L>A0$+$iA[A|$,$D$/$+$b$7$l$J$$$,!"$3$N4X?t$O(Bruby$B%$%s(B $B%?%W%j%?$N=i4|2=$N;~E@$G8F$P$l$k!#(B

$B"'(BInit_stack()

1193  void
1194  Init_stack(addr)
1195      VALUE *addr;
1196  {
1197  #if defined(__human68k__)
1198      extern void *_SEND;
1199      rb_gc_stack_start = _SEND;
1200  #else
1201      VALUE start;
1202
1203      if (!addr) addr = &start;
1204      rb_gc_stack_start = addr;
1205  #endif
1206  #ifdef HAVE_GETRLIMIT
1207      {
1208          struct rlimit rlim;
1209
1210          if (getrlimit(RLIMIT_STACK, &rlim) == 0) {
1211              double space = (double)rlim.rlim_cur*0.2;
1212
1213              if (space > 1024*1024) space = 1024*1024;
1214              STACK_LEVEL_MAX = (rlim.rlim_cur - space) / sizeof(VALUE);
1215          }
1216      }
1217  #endif
1218  }

(gc.c)

$B=EMW$J$N$O??$sCf$NItJ,$@$1$@!#$D$^$jE,Ev$K%m!<%+%kJQ?t!J%9%?%C%/$K3NJ]$5$l$k!K$rDj5A$7$F$=$N%"(B $B%I%l%9$r(Brb_gc_stack_start$B$H$9$k!#(B__human68k__$B$N%3!<%I$K$"$k(B _SEND$B$H$$$&$N$O%3%s%Q%$%i$N%i%$%V%i%j$+%7%9%F%`$,Dj5A$7$?JQ?t$@$m$&!#(B $BEvA3(BStack END$B$NN,$G$"$m$&$HA[A|$G$-$k!#(B

$B0lJ}$=$N$"$H$N(BHAVE_GETRLIMIT$B$G$/$/$C$F$"$k%3!<%I$G$O%9%?%C%/$ND9$5$r(B $BD4$Y$F%4%K%g%4%K%g$H$d$C$F$$$k$h$&$@!#$3$l$b(Brb_gc_mark_children()$B$G$N(B $B%9%?%C%/0n$lKI;_$N0l4S$G$"$k!#L5;k$7$F$$$$!#(B

STACK_END

$BSTACK_END$B$r8+$k!#(B

$B"'(BSTACK_END

 345  #ifdef C_ALLOCA
 346  # define SET_STACK_END VALUE stack_end; alloca(0);
 347  # define STACK_END (&stack_end)
 348  #else
 349  # if defined(__GNUC__) && defined(USE_BUILTIN_FRAME_ADDRESS)
 350  #  define SET_STACK_END  VALUE *stack_end = __builtin_frame_address(0)
 351  # else
 352  #  define SET_STACK_END  VALUE *stack_end = alloca(1)
 353  # endif
 354  # define STACK_END (stack_end)
 355  #endif

(gc.c)

SET_STACK_END$B$,;0DL$j$"$k$N$G!"$^$:0lHV2<$N>l9g$+$i!#(Balloca()$B$O%9%?%C(B $B%/$N@hC<$KNN0h$r3d$jEv$F$FJV$9$N$G!"$=$NJV$jCM$H%9%?%C%/$N@hC<%"%I%l%9(B $B$O$+$J$j6a$$$O$:$@!#$=$3$G(Balloca()$B$NJV$jCM$G%9%?%C%/@hC<$N6a;w$H$9$k!#(B

$Be$r8+$h$&!#%^%/%m(BC_ALLOCA$B$,Dj5A$5$l$F$$$k>l9g$O(B alloca()$B$,%M%$%F%#%V$GDj5A$5$l$F$J$$!D!D$D$^$j!"8_494X?t$,(BC$B$GDj5A$5$l(B $B$F$$$k$3$H$r<($9!#$=$N>l9g$O(Balloca()$B$OFbIt$G(Bmalloc()$B$G%a%b%j$r3NJ]$7$F(B $B$$$k$N$G$"$C$?!#$=$l$G$O%9%?%C%/$N0LCV$rstack_end$B!K$,(B $B%9%?%C%/$N@hC<$K6a$$$HH=CG$7$F$=$N%"%I%l%9$r;H$&!J(B&stack_end$B!K!#(B

$B$^$?$3$N%3!<%I$K$O!"2?$K;H$C$F$$$k$N$+$h$/$o$+$i$J$$(Balloca(0)$B$bF~$C$F(B $B$$$k!#$3$l$O(BC$B$GDj5A$7$?(Balloca()$B$N@N$+$i$N;EMM$G!"$$$i$J$$NN0h$r%A%'%C(B $B%/$7$F2rJ|$7$F$M!"$H$$$&0UL#$G$"$k!#$A$g$&$I(BGC$B$r$d$C$F$$$k$+$i(B alloca()$B$N3d$jEv$F$?J,$b0l=o$K2rJ|$7$F$d$m$&$H$$$&$o$1$@!#$7$+$7$=$l(B $B$J$i$=$l$G$3$s$J$H$3$m$KJ6$l$3$^$5$:JL$N%^%/%m$KF~$l$F$*$$$?$[$&$,$$$$(B $B$H;W$&$N$@$,!D!D!#(B

$B$=$7$F:G8e$K??$sCf$N>l9g!"(B__builtin_frame_address()$B$K$D$$$F!#(B __GNUC__$B$O(Bgcc$B!J(BGNU$B$N(BC$B%3%s%Q%$%i!K$GDj5A$5$l$k%7%s%\%k$G$"$k!#(B $B$=$l$r;H$C$F8BDj$7$F$$$k$N$@$+$i!"(B $B$3$l$O(Bgcc$BAH$_9~$_$N3HD%L?Na$@!#(B__builtin_frame_address(n)$B$G(B n $B8DA0$N(B $B%9%?%C%/%U%l!<%`$N%"%I%l%9$,__builtin_frame_address(0)$B$J$i(B $B8=:_$N%U%l!<%`$N%"%I%l%9$@!#(B

rb_gc_mark_locations()

$B:G8e$Orb_gc_mark_locations()$B$G$"$k!#(B

$B"'(Brb_gc_mark_locations()

 513  void
 514  rb_gc_mark_locations(start, end)
 515      VALUE *start, *end;
 516  {
 517      VALUE *tmp;
 518      long n;
 519
 520      if (start > end) {
 521          tmp = start;
 522          start = end;
 523          end = tmp;
 524      }
 525      n = end - start + 1;
 526      mark_locations_array(start,n);
 527  }

(gc.c)

$B4pK\E*$K$ONN0h$r%^!<%/$9$k4X?t(Bmark_locations_array()$B$KG$$;$l$P$h$$!#(B $B$3$N4X?t$,$d$k$N$O0z?t$r$&$^$/D4@a$9$k$3$H$G$"$k!#$3$N$h$&$JD4@0$,(B $BI,MW$K$J$k$N$O!"%^%7%s%9%?%C%/$,?-$S$kJ}8~$,7h$^$C$F$$$J$$$+$i$@!#(B $BDc0L%"%I%l%9$K?-$S$k>l9g$O(Bend$B$N$[$&$,>.$5$$$7!"9b0L%"%I%l%9$K?-$S$k(B $B>l9g$O(Bstart$B$N$[$&$,>.$5$$!#$@$+$i%"%I%l%9$N>.$5$$$[$&$,(Bstart$B$K$J$k(B $B$h$&$K$3$3$GB7$($k$N$@!#(B

$B$=$NB>$N%k!<%H%*%V%8%'%/%H(B

$B:G8e$K%$%s%?%W%j%?AH$_$3$_$N(BVALUE$B%3%s%F%J$r%^!<%/$9$k!#(B

$B"'$=$NB>$N%k!<%H(B

1159      /* $BEPO?$5$l$F$$$k%0%m!<%P%kJQ?t$r%^!<%/(B */
1160      for (list = global_List; list; list = list->next) {
1161          rb_gc_mark(*list->varptr);
1162      }
1163      rb_mark_end_proc();
1164      rb_gc_mark_global_tbl();
1165
1166      rb_mark_tbl(rb_class_tbl);
1167      rb_gc_mark_trap_list();
1168
1169      /* true$B!"(Bfalse$B$J$I$N%$%s%9%?%s%9JQ?t$,$"$l$P$=$l$r%^!<%/(B */
1170      rb_mark_generic_ivar_tbl();
1171
          /* ruby$B$N%Q!<%5$G;H$&JQ?t$r%^!<%/!J%Q!<%9Cf$N$_!K(B */
1172      rb_gc_mark_parser();

(gc.c)

C$B$N%0%m!<%P%kJQ?t$K(BVALUE$B$rF~$l$k>l9g$O(Brb_gc_register_address()$B$G(B $B$=$N%"%I%l%9$r%f!<%6$KEPO?$7$F$b$i$&$3$H$K$J$C$F$$$k!#(Bglobal_List$B$K(B $B$=$l$,J]B8$5$l$F$$$k$N$G!"A4It%^!<%/$9$k!#(B

rb_mark_end_proc()$B$O(BRuby$B$N(BEND$BJ8$J$I$GEPO?$7$?!"(B $B%W%m%0%i%`$N=*N;;~$KEND$BJ8$O07$o$J$$!K!#(B

rb_gc_mark_global_tbl()$B$O%0%m!<%P%kJQ?t$N%F!<%V%k(Brb_global_tbl$B$N(B $B%^!<%/!JO!XJQ?t$HDj?t!Y;2>H!K!#(B

rb_mark_tbl(rb_class_tbl)$B$OA0>O$G$d$C$?(Brb_class_tbl$B$N%^!<%/!#(B

rb_gc_mark_trap_list()$B$O(BRuby$B$N4X?t%a%=%C%I(Btrap$B$GEPO?$7$?(B $B

rb_mark_generic_ivar_tbl()$B$O(Btrue$B$J$I$NHs%]%$%s%?(BVALUE$B$N$?$a$K(B $BMQ0U$5$l$?%$%s%9%?%s%9JQ?t%F!<%V%k$r%^!<%/$9$k!#(B

rb_gc_mark_parser()$B$O%Q!<%5$N%;%^%s%F%#%C%/%9%?%C%/$r%^!<%/$9$k(B $B!J%;%^%s%F%#%C%/%9%?%C%/$K$D$$$F$OBhFsIt$r;2>H!K!#(B

$B$3$3$^$G$G%^!<%/%U%'%$%:$O=*$o$j$@!#(B

$B%9%$!<%W(B

NODE$B$NFCJL07$$(B

$B%9%$!<%W%U%'%$%:$O%^!<%/$5$l$F$$$J$$%*%V%8%'%/%H$rC5$7$F2rJ|$7$F$$$/:n(B $B6H$@!#$7$+$7!"$A$g$C$HM}M3$,$"$C$F(BT_NODE$B7?$N%*%V%8%'%/%H$@$1$OFCJL07$$(B $B$5$l$F$$$k!#

$B"'(Bgc_sweep()$BKAF,(B

 846  static void
 847  gc_sweep()
 848  {
 849      RVALUE *p, *pend, *final_list;
 850      int freed = 0;
 851      int i, used = heaps_used;
 852
 853      if (ruby_in_compile && ruby_parser_stack_on_heap()) {
 854          /* yacc$B$N%9%?%C%/$,%^%7%s%9%?%C%/>e$K$J$$>l9g$O(B
 855             $B%Q!<%9Cf$O(BNODE$B$r2s<}$7$F$O$J$i$J$$(B */
 856          for (i = 0; i < used; i++) {
 857              p = heaps[i]; pend = p + heaps_limits[i];
 858              while (p < pend) {
 859                  if (!(p->as.basic.flags & FL_MARK) &&
                                          BUILTIN_TYPE(p) == T_NODE)
 860                      rb_gc_mark((VALUE)p);
 861                  p++;
 862              }
 863          }
 864      }

(gc.c)

NODE$B$O%Q!<%5$G%W%m%0%i%`$rI=8=$9$k$?$a$K;H$&%*%V%8%'%/%H$@!#(BNODE$B$O%3%s(B $B%Q%$%kCf$K$O(Byacc$B$H$$$&%D!<%k$NMQ0U$9$k%9%?%C%/$KCV$+$l$k$N$@$,!"$=$N%9(B $B%?%C%/$O%^%7%s%9%?%C%/>e$K$"$k$H$O8B$i$J$$!#6qBNE*$K8@$&$H!"(B ruby_parser_stack_on_heap()$B$,56$@$H%^%7%s%9%?%C%/>e$K$J$$$3$H$r<($9!#(B $B$9$k$H$=$N>l9g$O@[email protected]$N(BNODE$B$,$&$C$+$j2s<}$5$l$F$7$^$&4m81$,$"$k$N$G!"(B $B%3%s%Q%$%kCf!J(Bruby_in_compile$B!K$O(BT_NODE$B7?$N%*%V%8%'%/%H$rL5>r7o$K(B $B%^!<%/$7$F!"2s<}$5$l$J$$$h$&$K$9$k$N$G$"$k!#(B

$B%U%!%$%J%i%$%6(B

$B$3$3$^$GMh$?$i%^!<%/$5$l$F$$$J$$%*%V%8%'%/%H$OA4$F2rJ|$G$-$k$h$&$K$J$k!#(B $B$,!"2rJ|A0$K$b$&0l;E;v$7$J$1$l$P$J$i$J$$!#(BRuby$B$G$O%*%V%8%'%/%H$N2rJ|$r(B $B%U%C%/$G$-$k$h$&$K$J$C$F$$$k$N$G!"$3$l$r8F$VI,MW$,$"$k!#$3$N%U%C%/$r(B $B%U%!%$%J%i%$%6!J(Bfinalizer$B!K$H8@$&!#(B

$B"'(Bgc_sweep()$BCfHW(B

 869      freelist = 0;
 870      final_list = deferred_final_list;
 871      deferred_final_list = 0;
 872      for (i = 0; i < used; i++) {
 873          int n = 0;
 874
 875          p = heaps[i]; pend = p + heaps_limits[i];
 876          while (p < pend) {
 877              if (!(p->as.basic.flags & FL_MARK)) {
 878  (A)             if (p->as.basic.flags) {
 879                      obj_free((VALUE)p);
 880                  }
 881  (B)             if (need_call_final && FL_TEST(p, FL_FINALIZE)) {
 882                      p->as.free.flags = FL_MARK; /* $B%^!<%/$5$l$?$^$^;D$k(B */
 883                      p->as.free.next = final_list;
 884                      final_list = p;
 885                  }
 886                  else {
 887                      p->as.free.flags = 0;
 888                      p->as.free.next = freelist;
 889                      freelist = p;
 890                  }
 891                  n++;
 892              }
 893  (C)         else if (RBASIC(p)->flags == FL_MARK) {
 894                  /* $B%U%!%$%J%i%$%:$,I,MW$J%*%V%8%'%/%H!#(B */
 895                  /* $B2?$b$7$J$$$GJ|$C$F$*$/(B */
 896              }
 897              else {
 898                  RBASIC(p)->flags &= ~FL_MARK;
 899              }
 900              p++;
 901          }
 902          freed += n;
 903      }
 904      if (freed < FREE_MIN) {
 905          add_heap();
 906      }
 907      during_gc = 0;

(gc.c)

$B%*%V%8%'%/%H%R!<%W$rC<$+$iA4$F8+$F$f$-!"(BFL_MARK$B%U%i%0$,N)$C$F$$$J$+$C(B $B$?$i(Bobj_free()$B$G2rJ|$9$k!J(BA$B!K!#(Bobj_free()$B$G$ONc$($PJ8;zNs%*%V%8%'%/%H$,(B $B;H$&(Bchar[]$B$dG[Ns%*%V%8%'%/%H$,;H$&(BVALUE[]$B$r2rJ|$9$k$@$1$G!"(B RVALUE$B9=B$BN$r2rJ|$7$?$j$O$J$$$7!"(Bbasic.flags$B$bA4$/$$$8$i$J$$!#$@(B $B$+$i(Bobj_free()$B$r8F$s$@$"$H$K$=$N9=B$BN$rA`:n$7$F$bMn$A$k?4G[$O$J$$!#(B

$B%*%V%8%'%/%H$r2rJ|$7$?$"$H!"(BFL_FINALIZE$B%U%i%0$K$h$C$FJ,4t$9$k!J(BB$B!K!#(B FL_FINALIZE$B$,N)$C$F$$$?$i$=$N%*%V%8%'%/%H$KBP$7$F%U%!%$%J%i%$%6$,Dj5A(B $B$5$l$F$$$k$N$G(Bfinal_list$B$K!"N)$C$F$$$J$+$C$?$i$9$0$K(Bfreelist$B$KDI2C$9(B $B$k!#$^$?%U%!%$%J%i%$%:$9$k$H$-$O(Bbasic.flags$B$r(BFL_MARK$B$K$9$k!#$3$l$G9=B$(B $BBN7?%U%i%0!J(BT_STRING$B$J$I!K$,%/%j%"$5$l$k$N$G!"@8$-$F$$$k%*%V%8%'%/%H$H(B $B6hJL$,IU$/!#(B

$B$"$H$O$^$H$a$F%U%!%$%J%i%$%6$r]$H$J$C$?%*%V%8%'%/%H$O4{$K;`$s$G$$$k$3$H$KCm(B $B0U$7$h$&!#$D$^$j%U%!%$%J%i%$%6

$B"'(Bgc_sweep()$B;D$j(B

 910      if (final_list) {
 911          RVALUE *tmp;
 912
 913          if (rb_prohibit_interrupt || ruby_in_compile) {
 914              deferred_final_list = final_list;
 915              return;
 916          }
 917
 918          for (p = final_list; p; p = tmp) {
 919              tmp = p->as.free.next;
 920              run_final((VALUE)p);
 921              p->as.free.flags = 0;
 922              p->as.free.next = freelist;
 923              freelist = p;
 924          }
 925      }
 926  }

(gc.c)

$B8eH>$N(Bfor$B$,%a%$%s$N%U%!%$%J%i%$%::n6H$@!#A0H>$N(Bif$B$OMM!9$JM}M3$K$h$j(B Ruby$B%W%m%0%i%`$Kl9g$@!#$3$3$G%U%!%$%J%i%$%:$rCY$i$;$?(B $B%*%V%8%'%/%H$O@hDx$N%j%9%H$N7PO)!J(BC$B!K$K=P$F$/$k!#(B

rb_gc_force_recycle()

$B:G8e$K>/$70c$&OC$r$7$h$&!#$3$3$^$G$O(Bruby$B$N%,!<%Y!<%8%3%l%/%?$,%*%V%8%'%/%H$r2s<}$9$k(B $B$+$7$J$$$+7h$a$F$$$?$,!"%f!<%6$+$iL@<(E*$K2s<}$5$;$k$3$H$b$G$-$k!#$=(B $B$l$,(Brb_gc_force_recycle()$B$G$"$k!#(B

$B"'(Brb_gc_force_recycle()

 928  void
 929  rb_gc_force_recycle(p)
 930      VALUE p;
 931  {
 932      RANY(p)->as.free.flags = 0;
 933      RANY(p)->as.free.next = freelist;
 934      freelist = RANY(p);
 935  }

(gc.c)

$B;EAH$_$O$?$$$7$?$3$H$O$J$$$,!"BhFsIt!&Bh;0It$G2?EY$+=P2q$&$3$H$K$J$k$N$G(B $B>R2p$7$F$*$$$?!#(B

$B9M;!(B

$BNN0h$N2rJ|(B

$B8D!9$N%*%V%8%'%/%H$G3d$j$"$F$?NN0h!"Nc$($P(BString$B$N(Bchar[]$B$J$I!"$O%9%$!<(B $B%W%U%'%$%:$NCf$G2rJ|$5$l$F$$$?$,!"(BRVALUE$B9=B$BN<+BN$r2rJ|$9$k%3!<%I$O=P(B $B$F$3$J$+$C$?!#$^$?%*%V%8%'%/%H%R!<%W$G$b;H$C$F$$$k9=B$BN$N?t$N4IM}$J$I(B $B$O$d$C$F$$$J$$!#$H$$$&$3$H$O!"(Bruby$B$N%*%V%8%'%/%HNN0h$O0lEY3d$jEv$F$?$i(B $B@dBP$K2rJ|$5$l$J$$$N$@!#(B

$BNc$($PI.$r;H$o$J$/(B $B$J$C$?$H$7$F$b$:$C$H(B40M$B%P%$%H@jM-$7B3$1$k!#I.

$B$?$@$7(Bfree()$B$9$l$P%a%b%j;HMQNL$,8:$k$H$b8B$i$J$$$3$H$K$ON10U$9$Y$-$G$"(B $B$k!#%a%b%j$r(BOS$B$KJV$5$J$$8B$j%W%m%;%9$N%a%b%j;HMQNL$O8:$i$J$$!#$=$7$F(B malloc()$B$Nfree()$B$7$F$b%a%b%j$,(BOS$B$KJV$5$l$J$$$3$H$O$h$/(B $B$"$k!#(B

$B!D!D$H=q$$$F$$$?$N$@$,!"$J$s$HK\=q$NDy@Z4V:]$K(BRVALUE$B$,2rJ|$5$l$k$h$&$K(B $B$J$C$F$7$^$C$?!#E:IU(BCD-ROM$B$K$O:G?7HG$N(Bruby$B$bF~$C$F$$$k$+$i(Bdiff$B$7$F(B $B8+$F$_$F$[$7$$!#!D!D$J$s$F9s$$%*%A$@!#(B

$B@$BeJL(BGC

$B%^!<%/(B&$B%9%$!<%W$K$O!V%*%V%8%'%/%HNN0hA4BN$r:GDc$G$b0lEY$J$a$kI,MW$,(B $B$"$k!W$H$$$&

$B@$BeJL(BGC$B$N4pAC$K$J$k$N$O!V$[$H$s$I$N%*%V%8%'%/%H$Oo$KD9$$$+(B $BHs>o$KC;$$$+$N$I$A$i$+$G$"$k!W$H$$$&7P83B'$@!#$3$NE@$O<+J,$N=q$/%W%m(B $B%0%i%`$N$3$H$r$A$g$C$H9M$($F$_$l$PG

$B$5$F!"$3$N5,B'$rF'$^$($F9M$($F$_$k$H!VD9@8$-$9$k%*%V%8%'%/%H$OKh2sKh2s(B $B%^!<%/$7$F%9%$!<%W$7$J$/$F$b$$$$$8$c$J$$$+!W$H$$$&H/A[$,=P$F$/$k!#$3$N(B $B%*%V%8%'%/%H$OD9@8$-$@$J!"$H;W$C$?$i!"FCJL07$$$K$7$F(BGC$BBP>]$+$i30$;$P$$(B $B$$$N$@!#$9$k$H%^!<%/$K$7$F$b%9%$!<%W$K$7$F$b%*%V%8%'%/%H$N?t$r05E]E*$K(B $B8:$i$9$3$H$,$G$-$k!#Nc$($PFCDj$N(BGC$B$N%?%$%_%s%0$GD9@8$-$7$F$$$k%*%V%8%'(B $B%/%H$,H>J,$r@j$a$F$$$k$H$9$l$PBP>]%*%V%8%'%/%H?t$OH>J,$K$J$k!#(B

$B$?$@0l$DLdBj$,$"$k!#@$BeJL(BGC$B$O%*%V%8%'%/%H$r0\F0$G$-$J$$$HHs>o$K$d$j$K(B $B$/$$$N$@!#$J$<$+$H$$$&$H!"D9@8$-$9$k%*%V%8%'%/%H$O@hDx=q$$$?$H$*$j!VFC(B $BJL07$$!W$7$J$$$H$$$1$J$$$+$i$G$"$k!#@$BeJL(BGC$B$O07$&%*%V%8%'%/%H$r8:$i$7(B $B$F%3%9%H$r2<$2$k$o$1$@$+$i!"$3$NFs$D$N@$Be$K$"$k%*%V%8%'%/%H$r$-$C$A$j(B $BJ,N`$7$F$*$+$J$$$H7k6I$N$H$3$mN>J}$rBP>]$K$9$k$N$HJQ$o$i$J$/$J$C$F$7$^(B $B$&!#$^$?$5$i$K(Bruby$B$N(BGC$B$O(Bconservative GC$B$G$"$k$+$i!"(B is_pointer_to_heap()$B$,F0$/$h$&$K$b:n$i$J$1$l$P$J$i$J$$!#$3$l$,Fq$7$$!#(B

$B$=$3$G$I$&$d$C$F$3$NLdBj$r2r7h$9$k$+$@$,!D!DLZ;3???M$5$s$Nruby$B$N$?$a$N@$BeJL(BGC$B$Ndoc/generational-gc.html$B$r$^$:;2>H$N$3$H(B}$B!#(B

$B$G$O@bL@$KF~$k!#@bL@$,$7$d$9$$$h$&$K!"(B $BD9@8$-$9$k%*%V%8%'%/%H$r!V5l@$Be%*%V%8%'%/%H!W!"(B $BC;$$

$B:G=i$K!":GBg$NLdBj$G$"$k5l@$Be%*%V%8%'%/%H$NFCJL07$$$K$D$$$F!#$3$NE@$O(B $B?7@$Be$N%*%V%8%'%/%H$@$1$r(Bnewlist$B$H$$$&%j%s%/%j%9%H$K$D$J$0$3$H$G2r7h(B $B$7$F$$$k!#$^$?$3$N%j%9%H$O(BRVALUE$B$NMWAG$rA}$d$9$3$H$G

$BBhFs$K!"5l@$Be$N%*%V%8%'%/%H$r8+IU$1$kJ}K!$K$D$$$F!#$3$l$O$H$F$b4JC1$G!"(B newlist$B$G(BGC$B$5$l$J$+$C$?$b$N$r(Bnewlist$B$+$i30$9$@$1$@!#$D$^$j0l2s(BGC$B$r@8$-(B $B;D$k$H5l@$Be$N%*%V%8%'%/%H$H$7$F07$o$l$k!#(B

$BBh;0$K!"5l@$Be$+$i?7@$Be$X$N;2>H$r8!=P$9$kJ}K!$K$D$$$F!#@$BeJL(BGC$B$G$O!"(B $B8@$C$F$_$l$P!"5l@$Be$N%*%V%8%'%/%H$K$O%^!<%/$,IU$-$C$Q$J$7$N>uBV$K$J$k(B $B$o$1$@!#$7$+$75l@$Be$+$i?7@$Be$X%j%s%/$,=P$F$$$k>l9g!"$=$N?7@$Be$N(B $B%*%V%8%'%/%H$K$O%^!<%/$,IU$+$J$/$J$k!J?^(B11$B!K!#(B

(gengc)
$B?^(B11: $B@$Be$r1[$($?;2>H(B

$B$3$l$G$O$^$:$$$N$G!"5l@$Be$N%*%V%8%'%/%H$+$i?7@$Be$N%*%V%8%'%/%H$r;2>H(B $B$7$?$i$=$N=V4V$K$=$N?7@$Be$N%*%V%8%'%/%H$O(B $B5l@$Be$K$J$i$J$1$l$P$$$1$J$$!#$=$3$G%i%$%V%i%j$r=$@5$7!"$3$&$$$&(B $B;2>H$,5/$3$k2DG=@-$N$"$k$H$3$m$K$R$?$9$i%A%'%C%/$rF~$l$k$h$&$K$7$F$$$k!#(B

$B;EAH$_$N35MW$O0J>e$G$"$k!#$3$N%Q%C%A$OEv=i(Bruby 1.7$B$KHA4%A%'%C%/!W$N%3%9%H$,8z$$$F$$$k$N$G$O$J$$$+!"(B $B$H$$$&?dB,$b$J$5$l$F$$$k$,!">\$7$$860x$O$^$@$h$/$o$+$C$F$$$J$$!#(B

$B%3%s%Q%/%7%g%s(B

ruby$B$N(BGC$B$G%3%s%Q%/%7%g%s$O$G$-$k$@$m$&$+!#(Bruby$B$N(BVALUE$B$O(B $B9=B$BN$X$ND>%](B $B%$%s%?$G$"$k$+$i!"%3%s%Q%/%7%g%s$7$F9=B$BN$N%"%I%l%9$,JQ$o$C$?$i!"(B $B0\F0$7$?9=B$BN$r;X$7$F$$$k(BVALUE$B$rA4$F=q$-49$($J$$$H$$$1$J$$!#(B

$B$H$3$m$,(Bruby$B$N(BGC$B$O(Bconservative GC$B$J$N$G!V$=$l$,K\Ev$K(BVALUE$B$+$I$&$+$o$+(B $B$i$J$$>l9g!W$,$"$j$&$k!#$=$l$J$N$K$=$NCM$r=q$-49$($F$7$^$C$?$i!"$b$7(B VALUE$B$G$J$+$C$?$H$-$K$O$H$s$G$b$J$$$3$H$K$J$k!#%3%s%Q%/%7%g%s$H(B conservative GC$B$O$H$F$bAj@-$,0-$$$N$@!#(B

$B$@$,$J$s$H$+$7$FBP:v$r9M$($F$_$h$&!#$^$:(BVALUE$B$r%]%$%s%?$G$J$/(B $B%*%V%8%'%/%H(BID$B$K(B $B$9$kJ}K!$,9M$($i$l$k!J?^(B12$B!K!#(BVALUE$B$H9=B$BN$N4V$K0l(B $BKg4V@\AX$r64$`J}K!$@!#$3$l$J$i(BVALUE$B$r=q$-49$($:$K:Q$`$N$G0B?4$7$F9=(B $BB$BN$r0\F0$G$-$k!#$@$,$=$NBe=~$H$7$F%"%/%;%9B.EY$OCY$/$J$k$7!"3HD%%i%$(B $B%V%i%j$N8_49@-$b$J$/$J$k!#(B

(objid)
$B?^(B12: $B%*%V%8%'%/%H(BID$B7PM3$G$N;2>H(B

$B$=$3$GVALUE$B$G$"$k!W%]%$%s%?!V$@$1!W$+$i(B $B;X$5$l$F$$$k9=B$BN$K8BDj$7$F0\F0$9$k$H$$$&is_pointer_to_heap()$B$,??$K$J$k%*%V%8%'%/%H$O$=$&$?$/$5$s$O$J$$(B $B$+$i!"$+$J$j$N3NN($G%*%V%8%'%/%H9=B$BN$r0\F0$G$-$k$3$H$K$J$k!#(B

(mostcopy)
$B?^(B13: Mostly-copying garbage collection

$B$5$i$K$5$i$K!"$b$79=B$BN$,0\F0$G$-$k$H$$$&$3$H$K$J$l$P!"(B $BF1;~$K@$BeJL(BGC$B$N

GC$BBP:v$N(Bvolatile

$B%9%?%C%/>e$N(BVALUE$B$O(BGC$B$,LLE]$r8+$F$/$l$k$H=q$$$?!#$=$l$J$i$P(B $B%m!<%+%kJQ?t$H$7$F(BVALUE$B$rCV$$$F$*$1$P$=$N(BVALUE$B$O3NC$($F$7$^$&$3$H$,$"$k!#(B $BNc$($Pl9g$O>C$($k2DG=@-$,$"$k!#(B

VALUE str;
str = rb_str_new2("...");
printf("%s\n", RSTRING(str)->ptr);

$B$3$N%3!<%I$G$O(Bstr$B<+BN$K%"%/%;%9$7$F$$$J$$$N$G!"%3%s%Q%$%i$K$h$C$F$O(B str->ptr$B$@$1%a%b%j$K;D$7$F(Bstr$B$O>C$7$F$7$^$&$3$H$,$"$k!#$=$&$9$k$H(B str$B$,2s<}$5$l$FMn$A$k!#$3$&$$$&;~$O;EJ}$,$J$$$N$G!"(B

volatile VALUE str;

$B$H$9$k!#(Bvolatile$B$O(BC$B$NM=Ls8l$G!"$3$NJQ?t$K4X$9$k:GE,2=$r6X;_$9$k(B $B8z2L$,$"$k!#(BRuby$B4X78$N%3!<%I$G(Bvolatile$B$,IU$$$F$$$?$i$^$:4V0c$$$J$/(B GC$BBP:v$H;W$C$F$h$$!#(BK&R$B$rFI$s$@$H$-$O!V$3$s$J$b$N2?$K;H$&$s$@$m$&!W(B $B$H;W$C$F$$$?$N$@$,!"$^$5$+(Bruby$B$G$3$s$J$KBgNL$K8+$k$3$H$K$J$k$H$O(B $B;W$o$J$+$C$?!#(B

$B$7$+$7$3$&$$$&$H$3$m$r8+$k$H(Bconservative GC$B$N!V%f!<%6$,(BGC$B$r5$$K$7$J$/(B $B$F$$$$!W$H$$$&kp$$J86g$b$"$^$jEv$F$K$J$i$J$$$h$&$G$"$k!#0l;~$O(B $B!V(BKSM$B$H$$$&(BScheme$B$N(BGC$B$O(Bvolatile$B$,I,MW$J$$$i$7$$!W(B $B$H$$$&OC$b$"$C$?$N$@$,!"(B $B%"%k%4%j%:%`$K7j$,$"$C$F7k6I(Bruby$B$K$OE,MQ$G$-$J$$$h$&$@!#(B

$B5/F0$N%?%$%_%s%0(B

gc.c$BFbIt(B

GC$B$,5/F0$9$k$N$O$I$s$J$H$-$@$m$&$+!#(B gc.c$B$NFbIt$G$O(Brb_gc()$B$r8F$s$G$$$k$H$3$m$O;08D=j$"$k!#(B

  • ruby_xmalloc()
  • ruby_xrealloc()
  • rb_newobj()

ruby_xmalloc()$B$H(Bruby_xrealloc()$B$N>l9g$O%a%b%j3d$jEv$F$K<:GT$7$?$H$-$@!#(B $B$=$3$G(BGC$B$9$l$P%a%b%j$,2rJ|$5$l$F$^$?;H$($k%9%Z!<%9$,$G$-$k$+$b$7$l$J$$!#(B rb_newobj()$B$b>u67$O;w$F$$$F!"(Bfreelist$B$,6u$K$J$C$?$H$-$K5/F0$9$k!#(B

$B%$%s%?%W%j%?Fb(B

gc.c$B0J30$G$b%$%s%?%W%j%?Fb$G(Brb_gc()$B$r8F$s$G$$$k$H$3$m$,2?$+=j$+$"$k!#(B

$B$^$:(Bio.c$B$H(Bdir.c$B$G!"%U%!%$%k%G%#%9%/%j%W%?$,B-$j$J$/$F3+$1$J$+$C$?$H$-(B $B$K(BGC$B$r5/F0$9$k!#(BIO$B%*%V%8%'%/%H$,(BGC$B$5$l$l$P%U%!%$%k$,%/%m!<%:$5$l$F(B $B%U%!%$%k%G%#%9%/%j%W%?$,6u$/$+$b$7$l$J$$!"$H$$$&L\O@8+$+$i$@!#(B

ruby.c$B$G$O%U%!%$%k$r%m!<%I$7$?$"$H$G(Brb_gc()$B$9$k$3$H$,$"$k!#%9%$!<%W$N(B $B$H$3$m$G=q$$$?$H$*$j!"%3%s%Q%$%kCf$K(BNODE$B$r(BGC$B$G$-$J$$$N$rJd$&$?$a$G$"$k!#(B

$B%*%V%8%'%/%H$N@8@.(B

GC$B$NOC$,=*$o$C$F(BRuby$B%*%V%8%'%/%H$N@8@.$+$i2rJ|$^$G$r07$($k$h$&$K(B $B$J$C$?$N$G!"$3$3$G%*%V%8%'%/%H$N@8@.$K$D$$$F$NOC$r$7$F$*$3$&!#$3$l$O(B GC$B$H$O$"$^$j4X78$J$/!"$`$7$mA0>O$G$d$C$?%/%i%9$NOC$K>/$74X$C$F$/$k!#(B

$B%"%m%1!<%7%g%s%U%l!<%`%o!<%/(B

$B$3$l$^$G2?EY$b%*%V%8%'%/%H$r@8@.$7$F$-$?!#Nc$($P$3$s$JJ}K!$,$"$k!#(B

class C
end
C.new()

$B$3$N$H$-(BC.new$B$O$I$&$d$C$F%*%V%8%'%/%H$r@8@.$7$F$$$k$N$@$m$&$+!#(B

$B$^$:(BC.new$B$OClass#new$B$G$"$k!#$=$N

$B"'(Brb_class_new_instance()

 725  VALUE
 726  rb_class_new_instance(argc, argv, klass)
 727      int argc;
 728      VALUE *argv;
 729      VALUE klass;
 730  {
 731      VALUE obj;
 732
 733      obj = rb_obj_alloc(klass);
 734      rb_obj_call_init(obj, argc, argv);
 735
 736      return obj;
 737  }

(object.c)

rb_obj_alloc()$B$O(Bklass$B$KBP$7$F(Ballocate$B$H$$$&%a%=%C%I$r8F$V!#$D$^(B $B$j$$$^@bL@$7$F$$$kNc$J$i$P(BC.allocate$B$r8F$V!#(B $B$=$N%G%U%)%k%H$O(BClass#allocate$B$G!"$=$N$^$?rb_class_allocate_instance()$B$G$"$k!#(B

$B"'(Brb_class_allocate_instance()

 708  static VALUE
 709  rb_class_allocate_instance(klass)
 710      VALUE klass;
 711  {
 712      if (FL_TEST(klass, FL_SINGLETON)) {
 713          rb_raise(rb_eTypeError,
                       "can't create instance of virtual class");
 714      }
 715      if (rb_frame_last_func() != alloc) {
 716          return rb_obj_alloc(klass);
 717      }
 718      else {
 719          NEWOBJ(obj, struct RObject);
 720          OBJSETUP(obj, klass, T_OBJECT);
 721          return (VALUE)obj;
 722      }
 723  }

(object.c)

$B:G8e$N;09T0J30$O5$$K$7$J$/$F$$$$!#$3$N(BNEWOBJ()$B$H(BOBJSETUP()$B$O$3$l$^$G(B $B$b2?2s$+=P$F$-$?!"(BRuby$B$N%*%V%8%'%/%H$r:n$k$H$-$N%$%G%#%*%`$G$"$k!#:#EY(B $B$OCf?H$b8+$F$_$h$&!#(B

$B"'(BNEWOBJ() OBJSETUP()

 274  #define NEWOBJ(obj,type) type *obj = (type*)rb_newobj()
 275  #define OBJSETUP(obj,c,t) do {\
 276      RBASIC(obj)->flags = (t);\
 277      RBASIC(obj)->klass = (c);\
 278      if (rb_safe_level() >= 3) FL_SET(obj, FL_TAINT);\
 279  } while (0)

(ruby.h)

rb_newobj()$B$O(BRVALUE$B$r0l$D(Bfreelist$B$+$i30$7$FJV$7$F$/$l$k4X?t$@$C$?!#(B NEWOBJ()$B$O$=$N(Brb_newobj()$B$K7?$N$4$^$+$7$r2C$($?$b$N$K$9$.$J$$$H$o(B $B$+$k!#$^$?(BOBJSETUP()$B$O(Bstruct RBasic$BItJ,$r=i4|2=$9$k%^%/%m$G$"$k!#(B $B$3$A$i$O(BFL_TAINT$B%U%i%0$rN)$F$k$N$rK:$l$J$$$?$a$@$1$K$"$k$H;W$C$F(B $B$$$$$@$m$&!#(B

$B$"$H$O(Brb_class_new_instance()$B$KLa$C$F(Brb_obj_call_init()$B$r8F$V$3$H$K$J(B $B$k!#$3$N4X?t$,:n$C$?$P$+$j$N%*%V%8%'%/%H$KBP$7$F(Binitialize$B$r8F$S=P$7$F(B $B=i4|2=$O40N;$G$"$k!#(B

$B$^$H$a$k$H0J2<$N$h$&$K$J$C$F$$$k!#(B

SomeClass.new            = Class#new (rb_class_new_instance)
    SomeClass.allocate       = Class#allocate (rb_class_allocate_instance)
    SomeClass#initialize     = Object#initialize (rb_obj_dummy)

$B%/%i%9%a%=%C%I$N(Ballocate$B$,J*M}E*$J=i4|2=!"(Binitialize$B$,O@M}E*$J=i4|(B $B2=$H8@$C$F$b$$$$!#$3$N$h$&$J;EAH$_!D!D$D$^$j%*%V%8%'%/%H@8@.$r(B allocate$B!&(Binitialize$B$KJ,3d$7!"(Bnew$B$,E}3m$9$k$H$$$&;EAH$_$r!"(B $B!V%"%m%1!<%7%g%s%U%l!<%`%o!<%/!W$H8F$s$G$$$k!#(B

$B%f!<%6Dj5A%*%V%8%'%/%H$N@8@.(B

$Bruby$B$K$O$I$&$d$C$F:n$C$F$$$$$N$+$o$+$i$J$$!#$=$l(B $B$r65$($kJ}K!$r8+$h$&!#(B

Data_Wrap_Struct()

$B%f!<%6Dj5A$@$m$&$H$J$s$@$m$&$H@8@.$N;EAH$_<+BN$O%"%m%1!<%7%g%s%U%l!<%`(B $B%o!<%/$K=>$($P$$$$!#$D$^$j?7$7$$%/%i%9(BSomeClass$B$r(BC$B$GDj5A$9$k$H$-$O(B SomeClass.allocate$B$H(BSomeClass#initialize$B$NN>J}$r%*!<%P!<%i%$%I$9$k!#(B

$B$^$:$O(Ballocate$B$N$[$&$+$i8+$F$$$3$&!#$3$3$G$OJ*M}E*$J=i4|2=$r$9$k!#(B $B2?$r3d$jEv$F$l$P$h$$$+$H8@$&$H!"%f!<%6Dj5A%/%i%9$N%$%s%9%?%s%9$O(B struct RData$B$H!"$3$A$i$GMQ0U$9$k9=B$BN$NAH$G$"$C$?!#2>$K$=$N9=B$BN$r(B struct my$B7?$H$7$F$*$3$&!#$=$N(Bstruct my$B$r85$K(BVALUE$B$r:n$k$K$O(B Data_Wrap_Struct()$B$H$$$&%^%/%m$r;H$&!#;H$$$+$?$O$3$&$@!#(B

struct my *ptr = malloc(sizeof(struct my));  /* $BE,Ev$K%R!<%W$K

data_class$B$,(Bval$B$N=jB0$9$k%/%i%9$G!"(Bptr$B$,%i%C%W$7$h$&$H$7$F$$$k%](B $B%$%s%?$@!#(Bmark_f$B$,$3$N9=B$BN$r%^!<%/$9$k$?$a$N4X?t!J$X$N%]%$%s%?!K!#(B $B$H8@$C$F$b(Bptr$B<+BN$r%^!<%/$9$k$o$1$G$O$b$A$m$s$J$/$F!"(Bptr$B$N;X$99=B$(B $BBN$NCf$K(BVALUE$B$,$"$k$H$-$K;H$&$b$N$@!#0lJ}$N(Bfree_f$B$O(Bptr$B<+BN$r2rJ|(B $B$9$k$?$a$K;H$&4X?t$G$"$k!#$I$A$i$N4X?t$b0z?t$O(Bptr$B$@!#$3$N$"$?$j$O>/(B $B$7La$C$F%^!<%/$N%3!<%I$rFI$s$G$b$i$($k$H0lH/$GG

Data_Wrap_Struct()$B$NCf?H$b8+$F$*$3$&!#(B

$B"'(BData_Wrap_Struct()

 369  #define Data_Wrap_Struct(klass, mark, free, sval) \
 370      rb_data_object_alloc(klass, sval,             \
                               (RUBY_DATA_FUNC)mark,    \
                               (RUBY_DATA_FUNC)free)

 365  typedef void (*RUBY_DATA_FUNC) _((void*));

(ruby.h)

rb_data_object_alloc()$B$K$[$H$s$I0Q>y$5$l$F$$$k!#(B

$B"'(Brb_data_object_alloc()

 310  VALUE
 311  rb_data_object_alloc(klass, datap, dmark, dfree)
 312      VALUE klass;
 313      void *datap;
 314      RUBY_DATA_FUNC dmark;
 315      RUBY_DATA_FUNC dfree;
 316  {
 317      NEWOBJ(data, struct RData);
 318      OBJSETUP(data, klass, T_DATA);
 319      data->data = datap;
 320      data->dfree = dfree;
 321      data->dmark = dmark;
 322
 323      return (VALUE)data;
 324  }

(gc.c)

$B$J$s$F$3$H$O$J$$!#DL>o$N%*%V%8%'%/%H$HF1$8$/(BNEWOBJ() OBJSETUP()$B$r;H$C$F(B RVALUE$B$rMQ0U$7!"%a%s%P$rF~$l$k$@$1$@!#(B

$B$3$3$G(Ballocate$B$NOC$KLa$m$&!#$3$3$^$G$G(BVALUE$B$O:n$l$?$N$G!"$"$H$O$3$l$r(B $BE,Ev$J4X?t$KF~$l$F(Brb_define_singleton_method()$B$G%/%i%9$KDj5A$7$F(B $B$d$l$P$h$$!#(B

Data_Get_Struct()

$Binitialize$B$@!#(Binitialize$B$K8B$i$:!"%a%=%C%I$G$O$5$C$-:n$C$?(BVALUE$B$+(B $B$i(Bstruct my*$B$rData_Get_Struct()$B$H$$$&%^%/%m$r;H$&!#(B

$B"'(BData_Get_Struct()

 378  #define Data_Get_Struct(obj,type,sval) do {\
 379      Check_Type(obj, T_DATA); \
 380      sval = (type*)DATA_PTR(obj);\
 381  } while (0)

 360  #define DATA_PTR(dta) (RDATA(dta)->data)

(ruby.h)

$B8+$F$NDL$j!"(BRData$B$N%a%s%P$+$i!J(Bstruct my$B$X$N!K%]%$%s%?$rCheck_Type()$B$O9=B$BN7?$N%A%'%C%/$r$9$k$@$1!#(B

$B%"%m%1!<%7%g%s%U%l!<%`%o!<%/$NLdBjE@(B

$B$H!"$3$3$^$G2??)$o$L4i$G@bL@$7$F$-$?$N$@$,!"allocate$B$G:n$C$?%*%V%8%'%/%H(B $B$,(Binitialize$B$d$=$NB>$N%a%=%C%I$K=P$F$/$k!"$H$$$&$3$H$r8@$C$?$,!"$3$3$G(B $BF1$8%/%i%9$N(Ballocate$B$G:n$C$?%*%V%8%'%/%H$,EO$C$F$-$F$/$l$J$$$HHs>o$K:$(B $B$k$O$:$@!#Nc$($P%G%U%)%k%H$N(BObject.allocate$B!J(BClass#allocate$B!K$G:n$C$?(B $B%*%V%8%'%/%H$,(BString$B$N%a%=%C%I$KEO$C$F$7$^$C$?$i$H$F$b:$$k!#$J$<$J$i(B String$B$N%a%=%C%I$O(Bstruct RString$B$N9=B$BN$,$b$i$($k$H2>Dj$7$F=q$$$F$"$k(B $B$N$K!"struct RObject$B$@$+$i$@!#$3$&$$$&$3$H$rKI$0$?$a$K$O!"(B C.allocate$B$G:n$C$?%*%V%8%'%/%H$J$i!"(BC$B$+!"$=$N2<0L%/%i%9$N%a%=%C%I$@$1(B $B$KEO$k$h$&$K$7$J$1$l$P$J$i$J$$!#(B

$B$b$A$m$sIaDL$K$d$C$F$$$l$P$=$&$J$k!#(BC.allocate$B$J$i%/%i%9(BC$B$N%$%s%9%?%s(B $B%9$r:n$k$o$1$@$+$i!"%/%i%9(BC$B$N%a%=%C%I0J30$K$OEO$i$J$$$O$:$@!#(B $BNc30$H$7$F(BObject$B$N%a%=%C%I$K$OEO$k2DG=@-$,$"$k$,!"(B Object$B$N%a%=%C%I$O9=B$BN7?$K0MB8$7$J$$$h$&=q$$$F$"$k!#(B

$B$@$,IaDL$K$d$i$J$+$C$?$i$I$&$@$m$&$+!#(BC.allocate$B$O(BRuby$B%l%Y%k$KO*=P$7$F(B $B$$$k$N$G!"$^$@@bL@$7$F$$$J$$$,(Balias$B$@$N(Bsuper$B$@$N$r3hMQ$7$^$/$k$H(B allocate$B$NDj5A$rJL$N%/%i%9$K0\?"$G$-$F$7$^$&!#$=$&$9$k$H!"%/%i%9$O(B String$B$J$N$KK\Ev$N9=B$BN7?$O(Bstruct RObject$B!"$J$s$F%*%V%8%'%/%H$b(B $B:n$l$F$7$^$&!#$D$^$j(BRuby$B%l%Y%k$+$i9%$-J|Bj(Bruby$B$rMn$H$;$k$N$@!#$3$l$O(B $B:$$k!#(B

$BLdBj$N:,8;$O(Ballocate$B$,%a%=%C%I$H$7$F(BRuby$B%l%Y%k$KO*=P$7$F$$$k$3$H$@!#(B $B5U$K8@$&$H(Ballocate$B$NCf?H$r%a%=%C%I0J30$N

rb_define_allocator(rb_cMy, my_allocate);

$B$H$$$&46$8$NBeBX0F$,8=:_5DO@$5$l$F$$$k!#(B


$B8f0U8+!&8f46A[!&8m?#$N;XE&$J$I$O(B $B@DLZJvO:(B <[email protected]> $B$^$G$*4j$$$7$^$9!#(B

$B!X(BRuby$B%=!<%9%3!<%I40A42r@b!Y(B $B$O%$%s%W%l%9%@%$%l%/%H$G8fM=Ls!&8f9XF~$$$?$@$1$^$9(B ($B=q@R>R2p%Z!<%8$XHt$S$^$9(B)$B!#(B

Copyright (c) 2002-2004 Minero Aoki, All rights reserved.