Ejemplo n.º 1
0
Archivo: gc.c Proyecto: RichMng/julia
void jl_gc_setmark(jl_value_t *v)
{
    gc_setmark(v);
}
Ejemplo n.º 2
0
Archivo: gc.c Proyecto: wlbksy/julia
static void gc_mark_all()
{
    while (mark_sp > 0) {
    jl_value_t *v = mark_stack[--mark_sp];
    jl_value_t *vt = (jl_value_t*)gc_typeof(v);

    // some values have special representations
    if (vt == (jl_value_t*)jl_tuple_type) {
        size_t l = jl_tuple_len(v);
        jl_value_t **data = ((jl_tuple_t*)v)->data;
        for(size_t i=0; i < l; i++) {
            jl_value_t *elt = data[i];
            if (elt != NULL)
                gc_push_root(elt);
        }
    }
    else if (((jl_datatype_t*)(vt))->name == jl_array_typename) {
        jl_array_t *a = (jl_array_t*)v;
        char *data = a->data;
        if (data == NULL) continue;
        int ndims = jl_array_ndims(a);
        char *data0 = data;
        if (ndims == 1) data0 -= a->offset*a->elsize;
        if (!a->isinline) {
            jl_value_t *owner = jl_array_data_owner(a);
            if (a->ismalloc) {
                // jl_mallocptr_t
                if (gc_marked(owner))
                    continue;
                gc_setmark(owner);
            }
            else {
                // an array
                v = owner;
                if (v != (jl_value_t*)a) {
                    gc_push_root(v);
                    continue;
                }
            }
        }
        if (a->ptrarray) {
            size_t l = jl_array_len(a);
            for(size_t i=0; i < l; i++) {
                jl_value_t *elt = ((jl_value_t**)data)[i];
                if (elt != NULL) gc_push_root(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;
        if (ta->on_exit) gc_push_root(ta->on_exit);
        gc_push_root(ta->last);
        gc_push_root(ta->tls);
        gc_push_root(ta->consumers);
        if (ta->start)  gc_push_root(ta->start);
        if (ta->result) gc_push_root(ta->result);
        if (ta->stkbuf != NULL || ta == jl_current_task) {
            if (ta->stkbuf != NULL)
                gc_setmark_buf(ta->stkbuf);
#ifdef COPY_STACKS
            ptrint_t offset;
            if (ta == jl_current_task) {
                offset = 0;
                gc_mark_stack(jl_pgcstack, offset);
            }
            else {
                offset = (char *)ta->stkbuf - ((char *)ta->stackbase - ta->ssize);
                gc_mark_stack(ta->gcstack, offset);
            }
#else
            gc_mark_stack(ta->gcstack, 0);
#endif
        }
    }
    else {
        jl_datatype_t *dt = (jl_datatype_t*)vt;
        int nf = (int)jl_tuple_len(dt->names);
        for(int i=0; i < nf; i++) {
            if (dt->fields[i].isptr) {
                jl_value_t *fld = *(jl_value_t**)((char*)v + dt->fields[i].offset + sizeof(void*));
                if (fld)
                    gc_push_root(fld);
            }
        }
    }
    }
}
Ejemplo n.º 3
0
Archivo: gc.c Proyecto: JHonaker/julia
static void push_root(jl_value_t *v, int d)
{
    assert(v != NULL);
    jl_value_t *vt = (jl_value_t*)gc_typeof(v);

#ifdef OBJPROFILE
    if (!gc_marked(v)) {
        void **bp = ptrhash_bp(&obj_counts, vt);
        if (*bp == HT_NOTFOUND)
            *bp = (void*)2;
        else
            (*((ptrint_t*)bp))++;
    }
#endif

    gc_setmark(v);

    if (vt == (jl_value_t*)jl_weakref_type ||
        (jl_is_datatype(vt) && ((jl_datatype_t*)vt)->pointerfree)) {
        return;
    }

    if (d >= MAX_MARK_DEPTH)
        goto queue_the_root;

    d++;

    // some values have special representations
    if (vt == (jl_value_t*)jl_tuple_type) {
        size_t l = jl_tuple_len(v);
        jl_value_t **data = ((jl_tuple_t*)v)->data;
        for(size_t i=0; i < l; i++) {
            jl_value_t *elt = data[i];
            if (elt != NULL)
                gc_push_root(elt, d);
        }
    }
    else if (((jl_datatype_t*)(vt))->name == jl_array_typename) {
        jl_array_t *a = (jl_array_t*)v;
        if (a->how == 3) {
            jl_value_t *owner = jl_array_data_owner(a);
            gc_push_root(owner, d);
            return;
        }
        else if (a->how == 1) {
            gc_setmark_buf((char*)a->data - a->offset*a->elsize);
        }
        if (a->ptrarray && a->data!=NULL) {
            size_t l = jl_array_len(a);
            if (l > 100000 && d > MAX_MARK_DEPTH-10) {
                // don't mark long arrays at high depth, to try to avoid
                // copying the whole array into the mark queue
                goto queue_the_root;
            }
            else {
                void *data = a->data;
                for(size_t i=0; i < l; i++) {
                    jl_value_t *elt = ((jl_value_t**)data)[i];
                    if (elt != NULL) gc_push_root(elt, d);
                }
            }
        }
    }
    else if (vt == (jl_value_t*)jl_module_type) {
        gc_mark_module((jl_module_t*)v, d);
    }
    else if (vt == (jl_value_t*)jl_task_type) {
        gc_mark_task((jl_task_t*)v, d);
    }
    else {
        jl_datatype_t *dt = (jl_datatype_t*)vt;
        int nf = (int)jl_tuple_len(dt->names);
        for(int i=0; i < nf; i++) {
            if (dt->fields[i].isptr) {
                jl_value_t *fld = *(jl_value_t**)((char*)v + dt->fields[i].offset + sizeof(void*));
                if (fld)
                    gc_push_root(fld, d);
            }
        }
    }
    return;

 queue_the_root:
    if (mark_sp >= mark_stack_size) {
        size_t newsz = mark_stack_size>0 ? mark_stack_size*2 : 32000;
        mark_stack = (jl_value_t**)realloc(mark_stack,newsz*sizeof(void*));
        if (mark_stack == NULL) exit(1);
        mark_stack_size = newsz;
    }
    mark_stack[mark_sp++] = v;
}
Ejemplo n.º 4
0
static void gc_markval_(jl_value_t *v)
{
 gc_markval_top:
    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
    gc_setmark_obj(v);

    if (gc_typeof(vt) == (jl_value_t*)jl_bits_kind) return;

    // some values have special representations
    if (vt == (jl_value_t*)jl_tuple_type) {
        size_t l = ((jl_tuple_t*)v)->length;
        for(size_t i=0; i < l; 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);
            }
        }
        if (gc_typeof(jl_tparam0(vt)) != (jl_value_t*)jl_bits_kind) {
            size_t l = a->length;
            if (l > 0) {
                for(size_t i=0; i < l-1; i++) {
                    jl_value_t *elt = ((jl_value_t**)a->data)[i];
                    if (elt != NULL) GC_Markval(elt);
                }
                v = ((jl_value_t**)a->data)[l-1];
                if (v != NULL) goto gc_markval_top;
            }
        }
    }
    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 {
        int nf = (int)((jl_struct_type_t*)vt)->names->length;
        if (nf > 0) {
            int i = 0;
            if (vt == (jl_value_t*)jl_struct_kind ||
                vt == (jl_value_t*)jl_function_type) {
                i++;  // skip fptr field
            }
            for(; i < nf-1; i++) {
                jl_value_t *fld = ((jl_value_t**)v)[i+1];
                if (fld)
                    GC_Markval(fld);
            }
            v = ((jl_value_t**)v)[i+1];
            if (v)
                goto gc_markval_top;
        }
    }
}