⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ggc.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
		     ptr_within(ppt, global_old_heap, global_old_hend)))) {	    /*	     * An entry in the list of externals for a PRIVATE heap points to	     * the shared message area. This is WRONG!	     */	    abort();#endif        } else {                /* Object has not been moved - deref it */	    erts_deref_node_entry(ptr->node);            *prev = ptr = ptr->next;        }    }    ASSERT(*prev == NULL);}#ifndef HYBRID /* FIND ME! */static voidsweep_proc_funs(Process *p, int fullsweep){    ErlFunThing** prev;    ErlFunThing* ptr;    Eterm* bot;    Eterm* top;#ifdef HYBRID    if (ma_gc_flags & GC_GLOBAL)    {        bot = global_old_heap;        top = global_old_hend;        prev = &erts_global_offheap.funs;        ptr = erts_global_offheap.funs;    }    else#endif    {        bot = OLD_HEAP(p);        top = OLD_HEND(p);        prev = &MSO(p).funs;        ptr = MSO(p).funs;    }    while (ptr) {        Eterm* ppt = (Eterm *) ptr;        if (MY_IS_MOVED(*ppt)) {        /* Object is alive */            ErlFunThing* ro = (ErlFunThing *) fun_val(*ppt);            *prev = ro;         /* Patch to moved pos */            prev = &ro->next;            ptr = ro->next;        } else if (fullsweep == 0 &&                   ( ptr_within(ppt, bot, top)#ifdef HYBRID                     || (!(ma_gc_flags & GC_GLOBAL) &&                         ( ptr_within(ppt, global_heap, global_hend) ||                           ptr_within(ppt, global_old_heap, global_old_hend)))#endif                     )) {            /*             * Object resides on old heap, and we just did a             * generational collection - keep object in list.             */            prev = &ptr->next;            ptr = ptr->next;        } else {                /* Object has not been moved - deref it */            ErlFunEntry* fe = ptr->fe;            *prev = ptr = ptr->next;	    if (erts_refc_dectest(&fe->refc, 0) == 0) {                erts_erase_fun_entry(fe);            }        }    }    ASSERT(*prev == NULL);}#endifstatic voidsweep_proc_bins(Process *p, int fullsweep){    ProcBin** prev;    ProcBin* ptr;    Binary* bptr;    Eterm* bot;    Eterm* top;#ifdef HYBRID    if (ma_gc_flags & GC_GLOBAL)    {        bot  = global_old_heap;        top  = global_old_hend;        prev = &erts_global_offheap.mso;        ptr  = erts_global_offheap.mso;    }    else#endif    {        bot = OLD_HEAP(p);        top = OLD_HEND(p);        prev = &MSO(p).mso;        ptr  = MSO(p).mso;    }    /*     * Note: In R7 we no longer force a fullsweep when we find binaries     * on the old heap. The reason is that with the introduction of the     * bit syntax we can expect binaries to be used a lot more. Note that     * in earlier releases a brand new binary (or any other term) could     * be put on the old heap during a gen-gc fullsweep, but this is     * no longer the case in R7.     */    while (ptr) {        Eterm* ppt = (Eterm *) ptr;        if (MY_IS_MOVED(*ppt)) {        /* Object is alive */            ProcBin* ro = (ProcBin*) binary_val(*ppt);            *prev = ro;         /* Patch to moved pos */            prev = &ro->next;            ptr = ro->next;        } else if (fullsweep == 0 && ptr_within(ppt, bot, top)) {            /*             * Object resides on the old heap, and we just did a             * generational collection - keep object in list.             */            prev = &ptr->next;            ptr = ptr->next;#ifdef HYBRID	} else if (fullsweep == 0 &&		   (!(ma_gc_flags & GC_GLOBAL) &&		    (ptr_within(ppt, global_heap, global_hend) ||		     ptr_within(ppt, global_old_heap, global_old_hend)))) {	    /*	     * An entry in the list of binaries for a PRIVATE heap points	     * to the shared message area. This is WRONG!	     */	    abort();#endif        } else {                /* Object has not been moved - deref it */            *prev = ptr->next;            bptr = ptr->val;            if (erts_refc_dectest(&bptr->refc, 0) == 0) {                if (bptr->flags & BIN_FLAG_MATCH_PROG) {                    erts_match_set_free(bptr);                } else {		    erts_bin_free(bptr);                }            }            ptr = *prev;        }    }    ASSERT(*prev == NULL);}voiderts_gc_info(ErtsGCInfo *gcip){    if (gcip) {	erts_smp_spin_lock(&info_lck);	gcip->garbage_collections = garbage_cols;	gcip->reclaimed = reclaimed;	erts_smp_spin_unlock(&info_lck);    }}extern void erts_init_ggc(void); /* Avoid warning... */				    voiderts_init_ggc(void) /*called from erl_gc.c:erts_init_gc() */{    erts_smp_spinlock_init(&info_lck, "gc_info");    garbage_cols = 0;    reclaimed = 0;}/************************************************************** *//*  DEBUG routines                                              *//****************************************************************/#ifdef DEBUGstatic voidcheck_mbuf_sz(Process *p){    ErlHeapFragment *bp;    Uint sz;    for (sz = 0, bp = MBUF(p); bp; bp = bp->next)	sz += (Uint) bp->size;    ASSERT(sz == MBUF_SIZE(p));}#endif#ifdef HARDDEBUGint within(Eterm *ptr, Process *p){    ErlHeapFragment* bp = MBUF(p);    if (HEAP_START(p) <= ptr && ptr < HEAP_TOP(p)) {        return 1;    }    if (OLD_HEAP(p) && (OLD_HEAP(p) <= ptr && ptr < OLD_HEND(p))) {        return 1;    }#ifdef HYBRID    if (global_heap <= ptr && ptr < global_htop) {        return 1;    }    if (global_old_heap <= ptr && ptr < global_old_hend) {        return 1;    }#ifdef INCREMENTAL    if (inc_fromspc <= ptr && ptr < inc_fromend) {        return 1;    }#endif#endif    while (bp != NULL) {        if (bp->mem <= ptr && ptr < bp->mem + bp->size) {            return 1;        }        bp = bp->next;    }#if HIPE    if(in_area(ptr,(char*)hipe_constants_start,               (char*)hipe_constants_next - (char*)hipe_constants_start))        return 1;#endif    return 0;}static voidcheck_pointer(Process* p, Eterm obj, int back_pointers_allowed, char *msg){    if (back_pointers_allowed && !within(ptr_val(obj), p)) {        erl_exit(1, "%T: %s, line %d: %s: bad address %x\n",                 p->id, __FILE__, __LINE__, msg, obj);    } else if (!back_pointers_allowed &&               !ptr_within(ptr_val(obj), OLD_HEAP(p), OLD_HEND(p))               ) {        if (within(ptr_val(obj), p)) {            erl_exit(1, "%T: %s, line %d: %s: back pointer %x\n",                     p->id, __FILE__, __LINE__, msg, obj);        } else {            erl_exit(1, "%T: %s, line %d: %s: bad address %x\n",                     p->id, __FILE__, __LINE__, msg, obj);        }    }}static voidcheck_binary(Process *p, Eterm obj, char* msg){    Eterm* ptr = binary_val(obj);    int btype = thing_subtag(*ptr);    ASSERT(is_thing(*ptr));    if (*ptr == DEBUG_BAD_WORD) {        erl_exit(1, "%T: Clobbered binary left\n", p->id);    }    check_pointer(p, obj, 1, msg);    switch (btype) {    case REFC_BINARY_SUBTAG:        {            ProcBin *bp = (ProcBin*)binary_val(obj);            if (bp->size > 0xffffffff) {                erl_exit(1, "%T: check_binary: %s: LARGE binary found %x\n",                         p->id, msg, obj);            }            if (bp->bytes == 0) {                erl_exit(1, "%T: check_binary: %s: NULL binary found %x\n",                         p->id, msg, obj);            }            if (erts_refc_read(&bp->val->refc, 0) <= 0) {                erl_exit(1, "Bad refc in binary\n");            }        }        break;    case HEAP_BINARY_SUBTAG:	/* TODO */	break;    case SUB_BINARY_SUBTAG:	/* TODO */	break;    default:        erl_exit(1, "Unknown subtag in thing binary \n");    }}static voidcheck_stack(Process *p, char *msg){    Eterm* sp;    Eterm* stack_end;    int stack_size;    int sz;    sp = p->stop;    stack_end = p->hend;    sz = p->hend - p->htop;    stack_size = stack_end - sp;    if (sp < p->htop) {        erl_exit(1, "%T: Overrun stack and heap\n", p->id);    }    for (sp = p->stop; sp < p->hend; sp++) {        if (is_not_catch(*sp)) {            ;        }    }}intchk_sys(void){    Process *p = *process_tab;    int i, res = 0;    for (i = 0; i < erts_max_processes; i++) {        if ((p = process_tab[i]) != NULL) {            res++;            check_stack(p, "chk");        }    }    return res;}voidcheck_bins(Process *p){    ProcBin *pb = MSO(p).mso;    while (pb) {        check_binary(p, make_binary((Eterm*) pb), "CHECK");        pb = pb->next;    }    return;}#endif  /* HARDDEBUG  */#endif /* HEAP_FRAG_ELIM_TEST */#if defined(HYBRID) && defined(DEBUG)static void print_roots(Rootset *rootset, int n) /* FIND ME! */{    fprintf(stderr,"-- Rootset --\n\r");    while (n--)    {        int i = rootset[n].n;        while (i--)        {            Eterm* g_ptr = rootset[n].v[i];            Uint g_sz = rootset[n].sz[i];            while (g_sz--)            {                Eterm gval = *g_ptr++;                fprintf(stderr,"Root: 0x%08x\n\r",(int)gval);            }        }    }    fprintf(stderr,"-------------\n\r");}#endif#if defined(HYBRID) && !defined(INCREMENTAL)/*************************************************************************** *                                                                         * *                Garbage collection of the Message Area                   * *                                                                         * ***************************************************************************/static void ma_gen_gc(Process*, int, Eterm*, int);static voidma_offset_off_heap(Process* p, Eterm* low, Eterm* high, int offs){    if (erts_global_offheap.mso &&        ptr_within((Eterm *)erts_global_offheap.mso, low, high)) {        Eterm** uptr = (Eterm**) &erts_global_offheap.mso;        *uptr += offs;    }#ifndef HYBRID /* FIND ME! */    if (erts_global_offheap.funs &&        ptr_within((Eterm *)erts_global_offheap.funs, low, high)) {        Eterm** uptr = (Eterm**) &erts_global_offheap.funs;        *uptr += offs;    }#endif    if (erts_global_offheap.externals &&        ptr_within((Eterm *)erts_global_offheap.externals, low, high)) {        Eterm** uptr = (Eterm**) &erts_global_offheap.externals;        *uptr += offs;    }}static voidma_offset_rootset(Process *cp, Sint offs, 	       Eterm* low, Eterm* high, 	       Eterm* objv, int nobj){    Uint i;    Uint n = erts_num_active_procs;    Process *p;    for (i = 0; i < n; i++) {        p = erts_active_procs[i];        if (p->dictionary) {            offset_heap(p->dictionary->data,                         p->dictionary->used,                         offs, low, high);	}        if (p->debug_dictionary) {            offset_heap(p->debug_dictionary->data,                         p->debug_dictionary->used,                         offs, low, high);	}	offset_heap(&p->fvalue, 1, offs, low, high);	offset_heap(&p->ftrace, 1, offs, low, high);	offset_heap(&p->group_leader, 1, offs, low, high);        offset_heap(&p->seq_trace_token, 1, offs, low, high);        offset_mqueue(p, offs, low, high);        offset_heap_ptr(p->stop, (STACK_START(p) - p->stop), offs, low, high);        offset_heap(p->heap, p->htop - p->heap, offs, low, high);        offset_heap_ptr(p->rrma, p->nrr, offs, low, high);        offset_nstack(p, offs, low, high);	offset_off_heap(p, low, high, offs);	if (p->old_heap)            offset_heap(p->old_heap, p->old_htop - p->old_heap,                        offs, low, high);	if (p != cp ) {            if (p->arity > 0)                offset_heap_ptr(p->arg_reg, p->arity, offs, low, high);	} else if (nobj > 0) {	    offset_heap_ptr(objv, nobj, offs, low, high);	}#ifdef DEBUG        if (p->nrr > 0) {            int i;            for (i = 0; i < p->nrr; i++) {                if (p->rrsrc[i] != NULL) {                    ASSERT(*(p->rrsrc[i]) == p->rrma[i]);                }            }        }#endif    }    ma_offset_off_heap(p, low, high, offs);}#if defined(HIPE)#define MA_GENSWEEP_NSTACK(p,old_htop,n_htop)				\	do {								\		Eterm *tmp_old_htop = old_htop;				\		Eterm *tmp_n_htop = n_htop;				\		ma_gensweep_nstack((p),&tmp_old_htop,&tmp_n_htop);	\		old_htop = tmp_old_htop;				\		n_htop = tmp_n_htop;					\	} while(0)/* * offset_nstack() can ignore the descriptor-based traversal the other * nstack procedures use and simply call offset_heap_ptr() instead. * This relies on two facts: * 1. The only live non-Erlang terms on an nstack are return addresses, *    and they will be skipped thanks to the low/high range check. * 2. Dead values, even if mistaken for pointers into the low/high area, *    can be offset safely since they won't be dereferenced. * * XXX: WARNING: If HiPE starts storing other non-Erlang values on the * nstack, such as floats, then this will have to be changed. */#else /* !HIPE */#define ma_fulls

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -