コード例 #1
0
ファイル: gc.c プロジェクト: jakevdp/julia
static void gc_mark(void)
{
    // mark all roots

    // active tasks
    GC_Markval(jl_root_task);
    GC_Markval(jl_current_task);

    // modules
    GC_Markval(jl_core_module);
    GC_Markval(jl_current_module);

    // invisible builtin values
    if (jl_an_empty_cell) GC_Markval(jl_an_empty_cell);
    GC_Markval(jl_exception_in_transit);
    GC_Markval(jl_task_arg_in_transit);
    GC_Markval(jl_unprotect_stack_func);
    GC_Markval(jl_bottom_func);
    GC_Markval(jl_typetype_type);

    // constants
    GC_Markval(jl_null);
    GC_Markval(jl_true);
    GC_Markval(jl_false);

    jl_mark_box_caches();

    size_t i;

    // stuff randomly preserved
    for(i=0; i < preserved_values.len; i++) {
        GC_Markval((jl_value_t*)preserved_values.items[i]);
    }

    // objects currently being finalized
    for(i=0; i < to_finalize.len; i++) {
        GC_Markval(to_finalize.items[i]);
    }
    // find unmarked objects that need to be finalized.
    // this must happen last.
    for(i=0; i < finalizer_table.size; i+=2) {
        if (finalizer_table.table[i+1] != HT_NOTFOUND) {
            jl_value_t *v = finalizer_table.table[i];
            if (!gc_marked_obj(v)) {
                GC_Markval(v);
                schedule_finalization(v);
            }
            GC_Markval(finalizer_table.table[i+1]);
        }
    }
}
コード例 #2
0
ファイル: gc.c プロジェクト: ChappedSky/julia
static void sweep_weak_refs(void)
{
    size_t n=0, ndel=0, l=weak_refs.len;
    jl_weakref_t *wr;
    void **lst = weak_refs.items;
    void *tmp;
#define SWAP_wr(a,b) (tmp=a,a=b,b=tmp,1)
    if (l == 0)
        return;
    do {
        wr = (jl_weakref_t*)lst[n];
        if (gc_marked_obj(wr)) {
            // weakref itself is alive
            if (!gc_marked_obj(wr->value))
                wr->value = (jl_value_t*)jl_nothing;
            n++;
        }
        else {
            ndel++;
        }
    } while ((n < l-ndel) && SWAP_wr(lst[n],lst[n+ndel]));

    weak_refs.len -= ndel;
}
コード例 #3
0
ファイル: gc.c プロジェクト: ChappedSky/julia
static void gc_markval_(jl_value_t *v)
{
    assert(v != NULL);
    //assert(v != lookforme);
    if (gc_marked_obj(v)) return;
    jl_value_t *vt = (jl_value_t*)jl_typeof(v);
#ifdef OBJPROFILE
    void **bp = ptrhash_bp(&obj_counts, vt);
    if (*bp == HT_NOTFOUND)
        *bp = (void*)2;
    else
        (*((ptrint_t*)bp))++;
#endif
    jl_value_t *vtt = gc_typeof(vt);
    gc_setmark_obj(v);

    if (vtt==(jl_value_t*)jl_bits_kind) return;

    // some values have special representations
    if (vt == (jl_value_t*)jl_tuple_type) {
        size_t i;
        for(i=0; i < ((jl_tuple_t*)v)->length; i++) {
            jl_value_t *elt = ((jl_tuple_t*)v)->data[i];
            if (elt != NULL)
                GC_Markval(elt);
        }
    }
    else if (((jl_struct_type_t*)(vt))->name == jl_array_typename) {
        jl_array_t *a = (jl_array_t*)v;
        int ndims = jl_array_ndims(a);
        int ndimwords = (ndims > 2 ? (ndims-2) : 0);
#ifndef __LP64__
        // on 32-bit, ndimwords must be odd to preserve 8-byte alignment
        ndimwords += (~ndimwords)&1;
#endif
        void *data_area = &a->_space[0] + ndimwords*sizeof(size_t);
        if (a->reshaped) {
            GC_Markval(*((jl_value_t**)data_area));
        }
        else if (a->data) {
            char *data = a->data;
            if (ndims == 1) data -= a->offset*a->elsize;
            if (data != data_area) {
                gc_setmark(data);
            }
        }
        jl_value_t *elty = jl_tparam0(vt);
        if (gc_typeof(elty) != (jl_value_t*)jl_bits_kind) {
            size_t i;
            for(i=0; i < a->length; i++) {
                jl_value_t *elt = ((jl_value_t**)a->data)[i];
                if (elt != NULL) GC_Markval(elt);
            }
        }
    }
    else if (vt == (jl_value_t*)jl_module_type) {
        gc_mark_module((jl_module_t*)v);
    }
    else if (vt == (jl_value_t*)jl_task_type) {
        jl_task_t *ta = (jl_task_t*)v;
        GC_Markval(ta->on_exit);
        GC_Markval(ta->tls);
        if (ta->start)
            GC_Markval(ta->start);
        if (ta->result)
            GC_Markval(ta->result);
        GC_Markval(ta->state.eh_task);
        if (ta->stkbuf != NULL)
            gc_setmark(ta->stkbuf);
#ifdef COPY_STACKS
        ptrint_t offset;
        if (ta == jl_current_task) {
            offset = 0;
            gc_mark_stack(jl_pgcstack, offset);
        }
        else {
            offset = ta->stkbuf - (ta->stackbase-ta->ssize);
            gc_mark_stack(ta->state.gcstack, offset);
        }
        jl_savestate_t *ss = &ta->state;
        while (ss != NULL) {
            GC_Markval(ss->ostream_obj);
            ss = ss->prev;
            if (ss != NULL)
                ss = (jl_savestate_t*)((char*)ss + offset);
        }
#else
        gc_mark_stack(ta->state.gcstack, 0);
        jl_savestate_t *ss = &ta->state;
        while (ss != NULL) {
            GC_Markval(ss->ostream_obj);
            ss = ss->prev;
        }
#endif
    }
    else if (vt == (jl_value_t*)jl_weakref_type) {
        // don't mark contents
    }
    else {
        assert(vtt == (jl_value_t*)jl_struct_kind);
        size_t nf = ((jl_struct_type_t*)vt)->names->length;
        size_t i=0;
        if (vt == (jl_value_t*)jl_struct_kind ||
            vt == (jl_value_t*)jl_function_type) {
            i++;  // skip fptr field
        }
        for(; i < nf; i++) {
            jl_value_t *fld = ((jl_value_t**)v)[i+1];
            if (fld)
                GC_Markval(fld);
        }
    }
}