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

📄 ggc.c

📁 OTP是开放电信平台的简称
💻 C
📖 第 1 页 / 共 5 页
字号:
		    MOVE_CONS(ptr,val,n_htop,n_hp++);		}#ifdef HYBRID            } else if (ptr_within(ptr,g_start,g_end) ||#ifdef INCREMENTAL                       ptr_within(ptr, i_heap, i_hend) ||#endif                       ptr_within(ptr,go_start,go_end)) {                RRMA_STORE(p,gval,n_hp);                ++n_hp;#endif            } else {                ASSERT(within(ptr, p));                ++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* orig;		orig = &(mb->orig);		ptr = boxed_val((mb->orig));		val = *ptr; 		if (in_area(ptr, water_start, water_size)) {		  /* Orig is in high water*/		  if (MY_IS_MOVED(val)) {		    ASSERT(is_boxed(val));		    *orig = val; 		    mb->base=binary_bytes((mb->orig));		  }		  else {		   MOVE_BOXED(ptr,val,n_htop,orig);		   mb->base=binary_bytes((mb->orig));		  } 		}#ifdef HYBRID	       else if (ptr_within(ptr,g_start,g_end) ||#ifdef INCREMENTAL			 ptr_within(ptr, i_heap, i_hend) ||#endif			 ptr_within(ptr,go_start,go_end)) {                RRMA_STORE(p,gval,n_hp);	       }#endif		else {		  ASSERT(within(ptr, p));		  			}	      }	      n_hp += (thing_arityval(gval)+1);	    }	    else	      n_hp++;	    continue;          }          default: {            ++n_hp;            continue;          }        }    }    return n_htop;}/* * This function sweeps both the remainder of the new heap * as well as the remainder of the old heap after the first pass * of the generational collector gen_gc(). */static Eterm*gen_cheney_old(Process *p, Eterm* from, Eterm** to,	       Eterm* low, Eterm* high, Eterm* old_htop,	       Eterm* objv, int nobj){ /*  printf("small New heap: 0x%08lx Old heap: 0x%08lx\n", (Uint)from,(Uint)OLD_HEAP(p)); */    Eterm* n_hp;    Eterm* n_htop;    Eterm* oh_start;    Eterm* oh_end;    char* water_start = (char *)low;    Uint water_size = (char *)high - water_start;    Eterm* ptr;    Eterm val;    Eterm gval;#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    n_hp = from;    n_htop = *to;    oh_start = OLD_HEAP(p);    oh_end = OLD_HEND(p);    while (n_hp != n_htop) {        gval = *n_hp;        switch (primary_tag(gval)) {          case TAG_PRIMARY_BOXED: {            ptr = boxed_val(gval);            val = *ptr;            if (ptr_within(ptr, oh_start, oh_end))            {                n_hp++;            }#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 if (MY_IS_MOVED(val)) {		ASSERT(is_boxed(val));                *n_hp++ = val;            } else if (in_area(ptr, water_start, water_size)) {                /* Make object old */                MOVE_BOXED(ptr,val,old_htop,n_hp++);            } 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 (ptr_within(ptr, oh_start, oh_end))            {                n_hp++;            }#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 if (is_non_value(val)) {                *n_hp++ = ptr[1];            } else if (in_area(ptr, water_start, water_size)) {                /* Make object old */                MOVE_CONS(ptr,val,old_htop,n_hp++);            } 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* orig;		orig = &(mb->orig);		ptr = boxed_val((mb->orig));		val = *ptr;		if (ptr_within(ptr, oh_start, oh_end))		  {} /* Orig is in old heap 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#if HIPE		else if( in_area(ptr, const_start, const_size) )		  {} /* Orig is in constant area no changes needed*/#endif		else if (MY_IS_MOVED(val)) {		  *orig = val;		  mb->base=binary_bytes(val);		}		else if (in_area(ptr, water_start, water_size)) {		  MOVE_BOXED(ptr,val,old_htop,orig);		  mb->base=binary_bytes((mb->orig));		} 		else {		  ASSERT(within(ptr, p));		  		  MOVE_BOXED(ptr,val,n_htop,orig);		  mb->base=binary_bytes(*orig);				}	      }	      n_hp += (thing_arityval(gval)+1);	    }	    else	      n_hp++;	    continue;          }          default: {            n_hp++;            continue;          }        }    }    /* Now set the parameter pointers for the caller */    *to = n_htop;    return old_htop;}/* * Garbage collect the heap. However, all objects pointing * to the old generation heap may be left as is. * Every other turn, we remember the position on the heap * that turned out to be the heap top, every other second turn * we tenure all live objects that reside below that water mark. * This means that we only tenure objects that have survived at * least two collections.*/#include "hipe_debug.h"static voidgen_gc(Process *p, int new_sz, Eterm* objv, int nobj){    Rootset rootset;            /* Rootset for GC (stack, dictionary, etc). */    Eterm* n_hstart;    Eterm* n_htop;    int n;    Eterm* ptr;    Eterm val;    Eterm gval;    Eterm* oh_start = OLD_HEAP(p);    Eterm* oh_end = OLD_HEND(p);    Eterm* old_htop = OLD_HTOP(p);    Eterm* low_water = HEAP_START(p);    Eterm* high_water = HIGH_WATER(p);    Eterm* tmp;#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    VERBOSE(DEBUG_PRIVATE_GC,("Generational GC\n"));    /* If flip is true, we need to tenure all (live) objects */    /* within the watermarks, if flip is 0, we need to alloc a */    /* new new_heap and copy all live objects to the new new_heap */    /* that is to not tenure any objects at all */    n_hstart = (Eterm*) ERTS_HEAP_ALLOC(ERTS_ALC_T_HEAP, sizeof(Eterm)*new_sz);    n_htop = n_hstart;    n = setup_rootset(p, objv, nobj, &rootset);    GENSWEEP_NSTACK(p, old_htop, n_htop);    while (n--) {        Eterm* g_ptr = rootset.v[n];        Uint g_sz = rootset.sz[n];        while (g_sz--) {            gval = *g_ptr;            switch (primary_tag(gval)) {	    case TAG_PRIMARY_BOXED: {                ptr = boxed_val(gval);                val = *ptr;                if (ptr_within(ptr, oh_start, oh_end)) {                    g_ptr++;                }#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 if (MY_IS_MOVED(val)) {		    ASSERT(is_boxed(val));                    *g_ptr++ = val;                } else if (ptr_within(ptr, low_water, high_water)) {                    MOVE_BOXED(ptr,val,old_htop,g_ptr++);                } 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 (ptr_within(ptr, oh_start, oh_end))                {                    g_ptr++;                }#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 if (is_non_value(val)) {                    *g_ptr++ = ptr[1];                }                else if (ptr_within(ptr, low_water, high_water)) {                    MOVE_CONS(ptr,val,old_htop,g_ptr++);                } else {                    ASSERT(within(ptr, p));                    MOVE_CONS(ptr,val,n_htop,g_ptr++);                }                continue;              }              default: {                g_ptr++;                continue;              }            }        }    }    /*     * Now all references in the rootset 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 changed.     */    tmp = n_htop;    old_htop = gen_cheney_old(p, n_hstart, &tmp, low_water, high_water, old_htop, objv, nobj);    n_htop = tmp;    /*     * And also if we have been tenuring, references on the second generation     * may point to the old (soon to be deleted) heap.     */    if (OLD_HTOP(p) < old_htop) {      if (MBUF(p) == NULL) {          old_htop = gen_cheney(p, HEAP_START(p), HEAP_END(p), OLD_HTOP(p), old_htop);      } else {          tmp = old_htop;          (void) gen_cheney_old(p, OLD_HTOP(p), &tmp, OLD_HEAP(p),                                OLD_HEAP(p), NULL, NULL, 0);          old_htop = tmp;      }    }    OLD_HTOP(p) = old_htop;    restore_rootset(p, &rootset);    if (MSO(p).mso) {        sweep_proc_bins(p, 0);    }#ifndef HYBRID /* FIND ME! */    if (MSO(p).funs) {        sweep_proc_funs(p, 0);    }#endif    if (MSO(p).externals) {	sweep_proc_externals(p, 0);    }    remove_message_buffers(p);    HIGH_WATER(p) = (HEAP_START(p) != HIGH_WATER(p)) ? n_hstart : n_htop;    /*     * Now we got to move the stack to the top of the new heap...     */    n = HEAP_END(p) - p->stop;    sys_memcpy(n_hstart + new_sz - n, p->stop, n * sizeof(Eterm));#ifdef DEBUG    sys_memset(HEAP_START(p), DEBUG_BAD_BYTE, HEAP_SIZE(p) * sizeof(Eterm));#endif    ERTS_HEAP_FREE(ERTS_ALC_T_HEAP,		   (void *) HEAP_START(p),		   HEAP_SIZE(p)*sizeof(Eterm));    HEAP_START(p) = n_hstart;    HEAP_TOP(p) = n_htop;    HEAP_SIZE(p) = new_sz;    HEAP_END(p) = n_hstart + new_sz;    p->stop = HEAP_END(p) - n;#ifdef INCREMENTAL    p->scan_top = HEAP_TOP(p);#endif}static voidsweep_proc_externals(Process *p, int fullsweep){    ExternalThing** prev;    ExternalThing* 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.externals;        ptr = erts_global_offheap.externals;    }    else#endif    {        bot = OLD_HEAP(p);        top = OLD_HEND(p);        prev = &MSO(p).externals;        ptr = MSO(p).externals;    }    while (ptr) {        Eterm* ppt = (Eterm *) ptr;        if (MY_IS_MOVED(*ppt)) {        /* Object is alive */            ExternalThing* ro = external_thing_ptr(*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 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) ||

⌨️ 快捷键说明

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