📄 hipe_gc.c
字号:
/* $Id$ * GC support procedures */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include "global.h"#ifdef HEAP_FRAG_ELIM_TEST#include "erl_gc.h"#else#include "ggc.h"#include "erl_nmgc.h"#endif#include "hipe_stack.h"#include "hipe_gc.h"#include "hipe_bif0.h" /* for hipe_constants_{start,next} */#ifdef HEAP_FRAG_ELIM_TESTvoid fullsweep_nstack(Process *p, Eterm **ptr_old_htop, Eterm **ptr_n_htop)#elseEterm *fullsweep_nstack(Process *p, Eterm *n_htop)#endif{ /* known nstack walk state */ Eterm *nsp; Eterm *nsp_end; const struct sdesc *sdesc; unsigned int sdesc_size; unsigned long ra; unsigned int i; unsigned int mask; /* arch-specific nstack walk state */ struct nstack_walk_state walk_state; /* fullsweep-specific state */#ifdef HEAP_FRAG_ELIM_TEST Eterm *n_htop, *old_htop; char *src, *oh; Uint src_size, oh_size;#else char *const_start; unsigned long const_size;#endif if( !nstack_walk_init_check(p) )#ifdef HEAP_FRAG_ELIM_TEST return;#else return n_htop;#endif nsp = nstack_walk_nsp_begin(p); nsp_end = p->hipe.nstgraylim; if( nsp_end ) nstack_walk_kill_trap(p, nsp_end); nsp_end = nstack_walk_nsp_end(p); sdesc = nstack_walk_init_sdesc(p, &walk_state);#ifdef HEAP_FRAG_ELIM_TEST old_htop = *ptr_old_htop; n_htop = *ptr_n_htop; src = (char*)HEAP_START(p); src_size = (char*)HEAP_TOP(p) - src; oh = (char*)OLD_HEAP(p); oh_size = (char*)OLD_HTOP(p) - oh;#else const_start = (char*)hipe_constants_start; const_size = (char*)hipe_constants_next - const_start;#endif for(;;) { if( nstack_walk_nsp_reached_end(nsp, nsp_end) ) { if( nsp == nsp_end ) { if( nsp ) { /* see the HIGH_WATER update in fullsweep_heap() */ p->hipe.nstblacklim = nsp; /* nsp == nsp_end */ nstack_walk_update_trap(p, walk_state.sdesc0); }#ifdef HEAP_FRAG_ELIM_TEST *ptr_old_htop = old_htop; *ptr_n_htop = n_htop; return;#else return n_htop;#endif } fprintf(stderr, "%s: passed end of stack\r\n", __FUNCTION__); break; } sdesc_size = nstack_walk_frame_size(sdesc); i = 0; mask = sdesc->livebits[0]; for(;;) { if( mask & 1 ) { Eterm *nsp_i = nstack_walk_frame_index(nsp, i); Eterm gval = *nsp_i; if( is_boxed(gval) ) { Eterm *ptr = boxed_val(gval); Eterm val = *ptr;#ifdef HEAP_FRAG_ELIM_TEST if (IS_MOVED(val)) { ASSERT(is_boxed(val)); *nsp_i = val; } else if (in_area(ptr, src, src_size)) { MOVE_BOXED(ptr,val,n_htop,nsp_i); } else if (in_area(ptr, oh, oh_size)) { MOVE_BOXED(ptr,val,old_htop,nsp_i); }#else /* !HEAP_FRAG_ELIM_TEST */ if( MY_IS_MOVED(val) ) { *nsp_i = val; } else if( in_area(ptr, const_start, const_size) ) { ;#ifdef HYBRID } else if( ptr_within(ptr, global_heap, global_htop) ) { } else if( ptr_within(ptr, global_old_heap, global_old_hend) ) {#endif } else { ASSERT(within(ptr, p)); MOVE_BOXED(ptr,val,n_htop,nsp_i); }#endif /* !HEAP_FRAG_ELIM_TEST */ } else if( is_list(gval) ) { Eterm *ptr = list_val(gval); Eterm val = *ptr;#ifdef HEAP_FRAG_ELIM_TEST if (is_non_value(val)) { *nsp_i = ptr[1]; } else if (in_area(ptr, src, src_size)) { ASSERT(within(ptr, p)); MOVE_CONS(ptr,val,n_htop,nsp_i); } else if (in_area(ptr, oh, oh_size)) { MOVE_CONS(ptr,val,old_htop,nsp_i); }#else /* !HEAP_FRAG_ELIM_TEST */ if( is_non_value(val) ) { *nsp_i = ptr[1]; } else if( in_area(ptr, const_start, const_size) ) { ;#ifdef HYBRID } else if( ptr_within(ptr, global_heap, global_htop) ) { } else if( ptr_within(ptr, global_old_heap, global_old_hend) ) {#endif } else { ASSERT(within(ptr, p)); MOVE_CONS(ptr,val,n_htop,nsp_i); }#endif /* !HEAP_FRAG_ELIM_TEST */ } } if( ++i >= sdesc_size ) break; if( i & 31 ) mask >>= 1; else mask = sdesc->livebits[i >> 5]; } ra = nstack_walk_frame_ra(nsp, sdesc); sdesc = hipe_find_sdesc(ra); nsp = nstack_walk_next_frame(nsp, sdesc_size); } abort();}void gensweep_nstack(Process *p, Eterm **ptr_old_htop, Eterm **ptr_n_htop){ /* known nstack walk state */ Eterm *nsp; Eterm *nsp_end; const struct sdesc *sdesc; unsigned int sdesc_size; unsigned long ra; unsigned int i; unsigned int mask; /* arch-specific nstack walk state */ struct nstack_walk_state walk_state; /* gensweep-specific state */ Eterm *old_htop, *n_htop;#ifdef HEAP_FRAG_ELIM_TEST char *heap; Uint heap_size, mature_size;#else Eterm *oh_start, *oh_end; Eterm *low_water, *high_water; char *const_start; unsigned long const_size;#endif if( !nstack_walk_init_check(p) ) return; nsp = nstack_walk_nsp_begin(p); nsp_end = p->hipe.nstgraylim; if( nsp_end ) { /* if gray limit passed black limit, reset black limit */ if( nstack_walk_gray_passed_black(nsp_end, p->hipe.nstblacklim) ) p->hipe.nstblacklim = nsp_end; nstack_walk_kill_trap(p, nsp_end); nsp_end = p->hipe.nstblacklim; } else nsp_end = nstack_walk_nsp_end(p); sdesc = nstack_walk_init_sdesc(p, &walk_state); old_htop = *ptr_old_htop; n_htop = *ptr_n_htop;#ifdef HEAP_FRAG_ELIM_TEST heap = (char*)HEAP_START(p); heap_size = (char*)HEAP_TOP(p) - heap; mature_size = (char*)HIGH_WATER(p) - heap;#else const_start = (char*)hipe_constants_start; const_size = (char*)hipe_constants_next - const_start; oh_start = OLD_HEAP(p); oh_end = OLD_HEND(p); low_water = HEAP_START(p); high_water = HIGH_WATER(p);#endif for(;;) { if( nstack_walk_nsp_reached_end(nsp, nsp_end) ) { if( nsp == nsp_end ) { *ptr_old_htop = old_htop; *ptr_n_htop = n_htop; if( nsp ) { /* see the HIGH_WATER update in gen_gc() */ if( HEAP_START(p) != HIGH_WATER(p) ) { p->hipe.nstblacklim = p->hipe.nstgraylim ? p->hipe.nstgraylim : nsp; /* nsp == nsp_end */ } else { /* blacklim = graylim ? blacklim : end */ if( !p->hipe.nstgraylim ) p->hipe.nstblacklim = nsp; /* nsp == nsp_end */ } nstack_walk_update_trap(p, walk_state.sdesc0); } return; } fprintf(stderr, "%s: passed end of stack\r\n", __FUNCTION__); break; } sdesc_size = nstack_walk_frame_size(sdesc); i = 0; mask = sdesc->livebits[0]; for(;;) { if( mask & 1 ) { Eterm *nsp_i = nstack_walk_frame_index(nsp, i); Eterm gval = *nsp_i; if( is_boxed(gval) ) { Eterm *ptr = boxed_val(gval); Eterm val = *ptr;#ifdef HEAP_FRAG_ELIM_TEST if (IS_MOVED(val)) { ASSERT(is_boxed(val)); *nsp_i = val; } else if (in_area(ptr, heap, mature_size)) { MOVE_BOXED(ptr,val,old_htop,nsp_i); } else if (in_area(ptr, heap, heap_size)) { ASSERT(within(ptr, p)); MOVE_BOXED(ptr,val,n_htop,nsp_i); }#else /* !HEAP_FRAG_ELIM_TEST */ if( ptr_within(ptr, oh_start, oh_end) ) { } else if( in_area(ptr, const_start, const_size) ) {#ifdef HYBRID } else if( ptr_within(ptr, global_heap, global_htop) ) { } else if( ptr_within(ptr, global_old_heap, global_old_hend) ) {#endif } else if( MY_IS_MOVED(val) ) { *nsp_i = val; } else if( ptr_within(ptr, low_water, high_water) ) { MOVE_BOXED(ptr,val,old_htop,nsp_i); } else { ASSERT(within(ptr, p)); MOVE_BOXED(ptr,val,n_htop,nsp_i); }#endif /* !HEAP_FRAG_ELIM_TEST */ } else if( is_list(gval) ) { Eterm *ptr = list_val(gval); Eterm val = *ptr;#ifdef HEAP_FRAG_ELIM_TEST if (is_non_value(val)) { *nsp_i = ptr[1]; } else if (in_area(ptr, heap, mature_size)) { MOVE_CONS(ptr,val,old_htop,nsp_i); } else if (in_area(ptr, heap, heap_size)) { MOVE_CONS(ptr,val,n_htop,nsp_i); }#else /* !HEAP_FRAG_ELIM_TEST */ if( ptr_within(ptr, oh_start, oh_end) ) { } else if( in_area(ptr, const_start, const_size) ) {#ifdef HYBRID } else if( ptr_within(ptr, global_heap, global_htop) ) { } else if( ptr_within(ptr, global_old_heap, global_old_hend) ) {#endif } else if( is_non_value(val) ) { *nsp_i = ptr[1]; } else if( ptr_within(ptr, low_water, high_water) ) { MOVE_CONS(ptr,val,old_htop,nsp_i); } else { ASSERT(within(ptr, p)); MOVE_CONS(ptr,val,n_htop,nsp_i); }#endif /* !HEAP_FRAG_ELIM_TEST */ } } if( ++i >= sdesc_size ) break; if( i & 31 ) mask >>= 1; else mask = sdesc->livebits[i >> 5]; } ra = nstack_walk_frame_ra(nsp, sdesc); sdesc = hipe_find_sdesc(ra); nsp = nstack_walk_next_frame(nsp, sdesc_size); } abort();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -