gc.c:1209
void
rb_gc()
{
    struct gc_list *list;
    struct FRAME * volatile frame; /* gcc 2.7.2.3 -O2 bug??  */
    jmp_buf save_regs_gc_mark;
    SET_STACK_END;

    if (dont_gc || during_gc) {
	if (!freelist) {
	    add_heap();
	}
	return;
    }
    if (during_gc) return;
    during_gc++;

    init_mark_stack();
    
    /* mark frame stack */
    for (frame = ruby_frame; frame; frame = frame->prev) {
	rb_gc_mark_frame(frame); 
	if (frame->tmp) {
	    struct FRAME *tmp = frame->tmp;
	    while (tmp) {
		rb_gc_mark_frame(tmp);
		tmp = tmp->prev;
	    }
	}
    }
    rb_gc_mark((VALUE)ruby_scope);
    rb_gc_mark((VALUE)ruby_dyna_vars);
    if (finalizer_table) {
	rb_mark_tbl(finalizer_table);
    }

    FLUSH_REGISTER_WINDOWS;
    /* This assumes that all registers are saved into the jmp_buf (and stack) */
    setjmp(save_regs_gc_mark);
    mark_locations_array((VALUE*)save_regs_gc_mark, sizeof(save_regs_gc_mark) / sizeof(VALUE *));
#if STACK_GROW_DIRECTION < 0
    rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start);
#elif STACK_GROW_DIRECTION > 0
    rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1);
#else
    if ((VALUE*)STACK_END < rb_gc_stack_start)
	rb_gc_mark_locations((VALUE*)STACK_END, rb_gc_stack_start);
    else
	rb_gc_mark_locations(rb_gc_stack_start, (VALUE*)STACK_END + 1);
#endif
#ifdef __ia64__
    /* mark backing store (flushed register window on the stack) */
    /* the basic idea from guile GC code                         */
    {
	ucontext_t ctx;
	VALUE *top, *bot;
	getcontext(&ctx);
	mark_locations_array((VALUE*)&ctx.uc_mcontext,
			     ((size_t)(sizeof(VALUE)-1 + sizeof ctx.uc_mcontext)/sizeof(VALUE)));
	bot = (VALUE*)__libc_ia64_register_backing_store_base;
#if defined(__FreeBSD__)
	top = (VALUE*)ctx.uc_mcontext.mc_special.bspstore;
#else
	top = (VALUE*)ctx.uc_mcontext.sc_ar_bsp;
#endif
	rb_gc_mark_locations(bot, top);
    }
#endif
#if defined(__human68k__) || defined(__mc68000__)
    rb_gc_mark_locations((VALUE*)((char*)STACK_END + 2),
			 (VALUE*)((char*)rb_gc_stack_start + 2));
#endif
    rb_gc_mark_threads();

    /* mark protected global variables */
    for (list = global_List; list; list = list->next) {
	rb_gc_mark_maybe(*list->varptr);
    }
    rb_mark_end_proc();
    rb_gc_mark_global_tbl();

    rb_mark_tbl(rb_class_tbl);
    rb_gc_mark_trap_list();

    /* mark generic instance variables for special constants */
    rb_mark_generic_ivar_tbl();

    rb_gc_mark_parser();
    
    /* gc_mark objects whose marking are not completed*/
    while (!MARK_STACK_EMPTY){
	if (mark_stack_overflow){
	    gc_mark_all();
	}
	else {
	    gc_mark_rest();
	}
    }
    gc_sweep();
}
