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

📄 ggc.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
	else#endif	{	    ERL_MESSAGE_TERM(mp) = *v_ptr++;	    ASSERT((is_nil(*v_ptr) || is_tuple(*v_ptr) || is_atom(*v_ptr)));	    ERL_MESSAGE_TOKEN(mp) = *v_ptr++;	}	mp = mp->next;    }        if (rootset->v_msg != rootset->def_msg) {        erts_free(ERTS_ALC_T_MSG_ROOTS, rootset->v_msg);    }}#if defined(HYBRID)#ifdef INCREMENTALvoid restore_one_rootset(Process *p, Rootset *rootset){    restore_this_rootset(p, rootset);}#endifvoid restore_rootset(Process *p, Rootset *rootset){    if (ma_gc_flags & GC_GLOBAL)    {        Uint i, j = 0;        Uint n = erts_num_active_procs;        for (i = 0; i < n; i++) {            p = erts_active_procs[i];            if ((IS_ACTIVE(p) && INC_IS_ACTIVE(p)) ||                ma_gc_flags & GC_INCLUDE_ALL) {                restore_this_rootset(p, &rootset[j++]);            }        }    }    else        restore_this_rootset(p, rootset);}#elsevoid restore_rootset(Process *p, Rootset *rootset){    restore_this_rootset(p, rootset);}#endif /* HYBRID *//* * Remove all message buffers. */static voidremove_message_buffers(Process* p){    ErlHeapFragment* bp = MBUF(p);    MBUF(p) = NULL;    MBUF_SIZE(p) = 0;    while (bp != NULL) {	ErlHeapFragment* next_bp = bp->next;#ifdef DEBUG	sys_memset(bp->mem, 0xf9, bp->size*sizeof(Eterm));#endif 	free_message_buffer(bp);	bp = next_bp;    }}/* ** This function is used when using fullsweep gc.** This replaces gen_gc for processes that use the** fullsweep algorithm and don't have an old_heap.** Parameters:** p: The process who is being garbage collected.** new_sz: The wanted size of the heap after collecting.** objv: Vector of "extra" objects to be "saved".** nobj: Number of objects in objv.*/static void fullsweep_heap(Process *p, int new_sz, Eterm* objv, int nobj){	    Rootset rootset;            /* Rootset for GC (stack, dictionary, etc). */    Eterm* n_hstart;		/* Start of new heap */    Eterm* n_htop;		/* Top of new heap */    Eterm* n_heap;		/* The new heap */    Eterm* n_hp;    int n;#if HIPE    char *const_start = (char*)hipe_constants_start;    unsigned long const_size = (char*)hipe_constants_next - const_start;#endif#ifdef HYBRID    Eterm *g_heap  = global_heap;    Eterm *g_htop  = global_htop;    Eterm *go_heap = global_old_heap;    Eterm *go_htop = global_old_hend;#endif#ifdef INCREMENTAL    Eterm *i_heap = inc_fromspc;    Eterm *i_hend = inc_fromend;#endif    /* Create new, empty heap */    n_heap = (Eterm *) ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP, sizeof(Eterm)*new_sz);    n_hstart = n_htop = n_heap;    FLAGS(p) &= ~F_NEED_FULLSWEEP;    VERBOSE(DEBUG_PRIVATE_GC,("Fullsweep GC\n"));#ifdef HYBRID    p->nrr = 0;#endif    n = setup_rootset(p, objv, nobj, &rootset);    n_htop = fullsweep_nstack(p, n_htop);    while (n--) {        Eterm* g_ptr = rootset.v[n];        Eterm g_sz = rootset.sz[n];	while(g_sz--) {	    Eterm* ptr;	    Eterm val;	    Eterm gval = *g_ptr;	    switch (primary_tag(gval)) {	      case TAG_PRIMARY_BOXED: {		ptr = boxed_val(gval);		val = *ptr;		if (MY_IS_MOVED(val)) {		    ASSERT(is_boxed(val));		    *g_ptr++ = val;                }#ifdef HYBRID                else if( ptr_within(ptr, g_heap, g_htop) ||#ifdef INCREMENTAL                         ptr_within(ptr, i_heap, i_hend) ||#endif                         ptr_within(ptr, go_heap, go_htop) )                {                    ++g_ptr;                }#endif#if HIPE		else if( in_area(ptr, const_start, const_size) ) {		    ++g_ptr;                }#endif		else {		    ASSERT(within(ptr, p));		    MOVE_BOXED(ptr,val,n_htop,g_ptr++);		}		continue;	      }	      case TAG_PRIMARY_LIST: {		ptr = list_val(gval);		val = *ptr;		if (is_non_value(val))		    *g_ptr++ = ptr[1];#ifdef HYBRID                else if( ptr_within(ptr, g_heap, g_htop) ||#ifdef INCREMENTAL                         ptr_within(ptr, i_heap, i_hend) ||#endif                         ptr_within(ptr, go_heap, go_htop) )                {                    ++g_ptr;                }#endif#if HIPE		else if( in_area(ptr, const_start, const_size) )		    ++g_ptr;#endif		else {		    ASSERT(within(ptr, p));		    MOVE_CONS(ptr,val,n_htop,g_ptr++);		}		continue;	      }	      default: {		g_ptr++;		continue;	      }	    }	}    }    /*     * Now all references on the stack point to the new heap. However,     * most references on the new heap point to the old heap, so the     * next stage is to scan through the new heap evacuating data from     * the old heap until all is copied.     */    n_hp = n_heap;        while (n_hp != n_htop) {	Eterm* ptr;	Eterm val;	Eterm gval = *n_hp;	switch (primary_tag(gval)) {	case TAG_PRIMARY_BOXED: {	    ptr = boxed_val(gval);	    val = *ptr;	    if (MY_IS_MOVED(val)) {		ASSERT(is_boxed(val));		*n_hp++ = val;            }#ifdef HYBRID            else if( ptr_within(ptr, g_heap, g_htop) ||#ifdef INCREMENTAL		    ptr_within(ptr, i_heap, i_hend) ||#endif		    ptr_within(ptr, go_heap, go_htop) )            {                RRMA_STORE(p,gval,n_hp);                ++n_hp;            }#endif#if HIPE	    else if( in_area(ptr, const_start, const_size) ) {		++n_hp;            }#endif	    else {		ASSERT(within(ptr, p));		MOVE_BOXED(ptr,val,n_htop,n_hp++);	    }	    continue;	}	case TAG_PRIMARY_LIST: {	    ptr = list_val(gval);	    val = *ptr;	    if (is_non_value(val)) {		*n_hp++ = ptr[1];            }#ifdef HYBRID            else if( ptr_within(ptr, g_heap, g_htop) ||#ifdef INCREMENTAL		    ptr_within(ptr, i_heap, i_hend) ||#endif		    ptr_within(ptr, go_heap, go_htop) )            {                RRMA_STORE(p,gval,n_hp);                ++n_hp;            }#endif#if HIPE	    else if( in_area(ptr, const_start, const_size) ) {		++n_hp;            }#endif	    else {		ASSERT(within(ptr, p));		MOVE_CONS(ptr,val,n_htop,n_hp++);	    }	    continue;	}	case TAG_PRIMARY_HEADER: {	    if (header_is_thing(gval)) {		if (header_is_bin_matchstate(gval)) {		    ErlBinMatchState *ms = (ErlBinMatchState*) n_hp;		    ErlBinMatchBuffer *mb = &(ms->mb);		    Eterm* origptr;			    origptr = &(mb->orig);		    ptr = boxed_val(*origptr);		    val = *ptr;		    if (MY_IS_MOVED(val)) {			*origptr = val;			mb->base = binary_bytes(*origptr);		    }#if HIPE		    else if( in_area(ptr, const_start, const_size) )		    {} /* Orig is in constant area no changes needed*/#ifdef HYBRID            else if( ptr_within(ptr, g_heap, g_htop) ||#ifdef INCREMENTAL                     ptr_within(ptr, i_heap, i_hend) ||#endif                     ptr_within(ptr, go_heap, go_htop) )            {                RRMA_STORE(p,gval,n_hp);            }#endif#endif	 		    else {			ASSERT(within(ptr, p));			MOVE_BOXED(ptr,val,n_htop,origptr); 			mb->base=binary_bytes(*origptr);			ptr = boxed_val(*origptr);			val = *ptr;		    }		}		n_hp += (thing_arityval(gval)+1);	    }	    else		n_hp++;	    continue;	}	default: {	    n_hp++;	    continue;	}	}    }    restore_rootset(p, &rootset);    if (MSO(p).mso) {	sweep_proc_bins(p, 1);    }#ifndef HYBRID /* FIND ME! */    if (MSO(p).funs) {	sweep_proc_funs(p, 1);    }#endif    if (MSO(p).externals) {	sweep_proc_externals(p, 1);    }    remove_message_buffers(p);    if (OLD_HEAP(p) != NULL) {#ifdef DEBUG        sys_memset(OLD_HEAP(p), DEBUG_BAD_BYTE,                   (OLD_HEND(p) - OLD_HEAP(p)) * sizeof(Eterm));#endif        ERTS_HEAP_FREE(ERTS_ALC_T_OLD_HEAP,		       OLD_HEAP(p),		       (OLD_HEND(p)-OLD_HEAP(p))*sizeof(Eterm));        OLD_HEAP(p) = OLD_HTOP(p) = OLD_HEND(p) = NULL;    }    /* Move the stack, the beam stack is "in the heap" */    n = HEAP_END(p) - p->stop;    sys_memcpy(n_heap + new_sz - n, p->stop, n * sizeof(Eterm));#ifdef DEBUG    sys_memset(HEAP_START(p), DEBUG_BAD_BYTE,                (HEAP_END(p) - HEAP_START(p)) * sizeof(Eterm));#endif    ERTS_HEAP_FREE(ERTS_ALC_T_HEAP,		   (void *) HEAP_START(p),		   HEAP_SIZE(p)*sizeof(Eterm));    HEAP_START(p) = n_heap;    HEAP_TOP(p) = n_htop;    HEAP_SIZE(p) = new_sz;    HEAP_END(p) = n_heap + new_sz;    p->stop = HEAP_END(p) - n;    GEN_GCS(p) = 0;    /*     * Should we set p->high_water to p->heap or p->htop?     *     * Setting it to p->htop means that any surviving data will be     * placed on the old heap in the next garbage collection.     * This setting gives a better estone value, but one can assume     * that more garbage is placed on the old heap.     *     * Setting it to p->heap means that two more garbage collections     * are needed to move data to the old heap.     */    HIGH_WATER(p) = HEAP_TOP(p);#ifdef INCREMENTAL    p->scan_top = HEAP_TOP(p);#endif}voiderts_offset_off_heap(ErlOffHeap *ohp, Sint offs, Eterm* low, Eterm* high){    if (ohp->mso && ptr_within((Eterm *)ohp->mso, low, high)) {        Eterm** uptr = (Eterm**) &ohp->mso;        *uptr += offs;    }#ifndef HYBRID /* FIND ME! */    if (ohp->funs && ptr_within((Eterm *)ohp->funs, low, high)) {        Eterm** uptr = (Eterm**) &ohp->funs;        *uptr += offs;    }#endif    if (ohp->externals && ptr_within((Eterm *)ohp->externals, low, high)) {        Eterm** uptr = (Eterm**) &ohp->externals;        *uptr += offs;    }}static voidoffset_off_heap(Process* p, Eterm* low, Eterm* high, Sint offs){    erts_offset_off_heap(&MSO(p), offs, low, high);}static voidoffset_rootset(Process *p, Sint offs, 	       Eterm* low, Eterm* high, 	       Eterm* objv, int nobj){    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_nstack(p, offs, low, high);    if (nobj > 0) {	offset_heap_ptr(objv, nobj, offs, low, high);    }    offset_off_heap(p, low, high, offs);#ifdef HYBRID    if (p->nrr > 0)    {        int i;        for (i = 0; i < p->nrr; i++) {            if (ptr_within(p->rrsrc[i],low,high))                p->rrsrc[i] += offs;        }    }#endif}/* * Grow the new heap size to 'new_sz'. */static voidgrow_new_heap(Process *p, Uint new_sz, Eterm* objv, int nobj){    Eterm* new_heap;    int heap_size = HEAP_TOP(p) - HEAP_START(p);    int stack_size = p->hend - p->stop;    Sint offs;        ASSERT(HEAP_SIZE(p) < new_sz);    new_heap = (Eterm *) ERTS_HEAP_REALLOC(ERTS_ALC_T_HEAP,					   (void*)HEAP_START(p),					   sizeof(Eterm)*(HEAP_SIZE(p)),					   sizeof(Eterm)*new_sz);    VERBOSE(DEBUG_PRIVATE_GC,            ("grow_new_heap: FROM %d UPTO %d (used %d)\n",             HEAP_SIZE(p), new_sz, heap_size));    if ((offs = new_heap - HEAP_START(p)) == 0) { /* No move. */        HEAP_END(p) = new_heap + new_sz;        sys_memmove(p->hend - stack_size, p->stop, stack_size * sizeof(Eterm));        p->stop = p->hend - stack_size;    } else {        Eterm* prev_stop = p->stop;        offset_heap(new_heap, heap_size, offs, HEAP_START(p), HEAP_TOP(p));        HIGH_WATER(p) = new_heap + (HIGH_WATER(p) - HEAP_START(p));#ifdef INCREMENTAL        p->scan_top = new_heap + (p->scan_top - HEAP_START(p));#endif        HEAP_END(p) = new_heap + new_sz;        prev_stop = new_heap + (p->stop - p->heap);        p->stop = p->hend - stack_size;        sys_memmove(p->stop, prev_stop, stack_size * sizeof(Eterm));        offset_rootset(p, offs, HEAP_START(p), HEAP_TOP(p), objv, nobj);        HEAP_TOP(p) = new_heap + heap_size;        HEAP_START(p) = new_heap;    }    HEAP_SIZE(p) = new_sz;}voiderts_shrink_new_heap(Process *p, Uint new_sz, Eterm *objv, int nobj){    Eterm* new_heap;    int heap_size = HEAP_TOP(p) - HEAP_START(p);    Sint offs;    int stack_size = p->hend - p->stop;    ASSERT(new_sz != 0);    ASSERT(new_sz < p->heap_sz);    sys_memmove(p->heap + new_sz - stack_size, p->stop, stack_size *                                                        sizeof(Eterm));    new_heap = (Eterm *) ERTS_HEAP_REALLOC(ERTS_ALC_T_HEAP,					   (void*)p->heap,

⌨️ 快捷键说明

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