Promising C coding techniques to reduce MRI's memory use[ruby-core:20149]

[ruby-core:20149] Promising C coding techniques to reduce MRI's memory use
これの話.読みたかったのだけど色々忙しくて..今朝になってようやく読めた.
浜地さんの日記で「GCフェチには当然」とか書いてあったので反応してみる.
これは無駄なスタックをきれいにしてマーク始めればいいんじゃねという意味と理解した(あってるだろうか..)
bdw_gcでいうと以下の部分かなと思います.

/* Clear the stack up to about limit.  Return arg. */
/*ARGSUSED*/
void * GC_clear_stack_inner(void *arg, ptr_t limit)
{
    word dummy[CLEAR_SIZE];
    
    BZERO(dummy, CLEAR_SIZE*sizeof(word));
    if ((ptr_t)(dummy) COOLER_THAN limit) {
        (void) GC_clear_stack_inner(arg, limit);
    }
    /* Make sure the recursive call is not a tail call, and the bzero	*/
    /* call is not recognized as dead code.				*/
    GC_noop1((word)dummy);
    return(arg);
}
#endif

/* Clear some of the inaccessible part of the stack.  Returns its	*/
/* argument, so it can be used in a tail call position, hence clearing  */
/* another frame.							*/
void * GC_clear_stack(void *arg)
{
    ptr_t sp = GC_approx_sp();  /* Hotter than actual sp */
#   ifdef THREADS
        word dummy[SMALL_CLEAR_SIZE];
	static unsigned random_no = 0;
       			 	 /* Should be more random than it is ... */
				 /* Used to occasionally clear a bigger	 */
				 /* chunk.				 */
#   endif
    ptr_t limit;
    
#   define SLOP 400
	/* Extra bytes we clear every time.  This clears our own	*/
	/* activation record, and should cause more frequent		*/
	/* clearing near the cold end of the stack, a good thing.	*/
#   define GC_SLOP 4000
	/* We make GC_high_water this much hotter than we really saw   	*/
	/* saw it, to cover for GC noise etc. above our current frame.	*/
#   define CLEAR_THRESHOLD 100000
	/* We restart the clearing process after this many bytes of	*/
	/* allocation.  Otherwise very heavily recursive programs	*/
	/* with sparse stacks may result in heaps that grow almost	*/
	/* without bounds.  As the heap gets larger, collection 	*/
	/* frequency decreases, thus clearing frequency would decrease, */
	/* thus more junk remains accessible, thus the heap gets	*/
	/* larger ...							*/
# ifdef THREADS
    if (++random_no % 13 == 0) {
	limit = sp;
	MAKE_HOTTER(limit, BIG_CLEAR_SIZE*sizeof(word));
	limit = (ptr_t)((word)limit & ~0xf);
        		/* Make it sufficiently aligned for assembly	*/
        		/* implementations of GC_clear_stack_inner.	*/
	return GC_clear_stack_inner(arg, limit);
    } else {
	BZERO(dummy, SMALL_CLEAR_SIZE*sizeof(word));
	return arg;
    }
# else
    if (GC_gc_no > GC_stack_last_cleared) {
        /* Start things over, so we clear the entire stack again */
        if (GC_stack_last_cleared == 0) GC_high_water = (ptr_t)GC_stackbottom;
        GC_min_sp = GC_high_water;
        GC_stack_last_cleared = GC_gc_no;
        GC_bytes_allocd_at_reset = GC_bytes_allocd;
    }
    /* Adjust GC_high_water */
        MAKE_COOLER(GC_high_water, WORDS_TO_BYTES(DEGRADE_RATE) + GC_SLOP);
        if (sp HOTTER_THAN GC_high_water) {
            GC_high_water = sp;
        }
        MAKE_HOTTER(GC_high_water, GC_SLOP);
    limit = GC_min_sp;
    MAKE_HOTTER(limit, SLOP);
    if (sp COOLER_THAN limit) {
        limit = (ptr_t)((word)limit & ~0xf);
			/* Make it sufficiently aligned for assembly	*/
        		/* implementations of GC_clear_stack_inner.	*/
        GC_min_sp = sp;
        return(GC_clear_stack_inner(arg, limit));
    } else if (GC_bytes_allocd - GC_bytes_allocd_at_reset > CLEAR_THRESHOLD) {
    	/* Restart clearing process, but limit how much clearing we do. */
    	GC_min_sp = sp;
    	MAKE_HOTTER(GC_min_sp, CLEAR_THRESHOLD/4);
    	if (GC_min_sp HOTTER_THAN GC_high_water) GC_min_sp = GC_high_water;
    	GC_bytes_allocd_at_reset = GC_bytes_allocd;
    }  
    return(arg);
# endif
}

そういえば大分前の日記でここに触れてた気がしたけど,途中で挫折したのだった.
BoehmGC解読室 - 1 (small object の allocate)後編 - I am Cruby!

追記

完全に勘違いしてた..orz
はじめてのにき(2008-12-04)