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

📄 alloc.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 3 页
字号:
    GC_clear_marks();#   ifdef SAVE_CALL_CHAIN        GC_save_callers(GC_last_stack);#   endif    GC_is_full_gc = TRUE;    if (!GC_stopped_mark(stop_func)) {      if (!GC_incremental) {    	/* We're partially done and have no way to complete or use 	*/    	/* current work.  Reestablish invariants as cheaply as		*/    	/* possible.							*/    	GC_invalidate_mark_state();	GC_unpromote_black_lists();      } /* else we claim the world is already still consistent.  We'll 	*/        /* finish incrementally.					*/      return(FALSE);    }    GC_finish_collection();    if (GC_print_stats) {        GET_TIME(current_time);        GC_log_printf("Complete collection took %lu msecs\n",                  MS_TIME_DIFF(current_time,start_time));    }    return(TRUE);}/* * Perform n units of garbage collection work.  A unit is intended to touch * roughly GC_RATE pages.  Every once in a while, we do more than that. * This needs to be a fairly large number with our current incremental * GC strategy, since otherwise we allocate too much during GC, and the * cleanup gets expensive. */# define GC_RATE 10 # define MAX_PRIOR_ATTEMPTS 1 	/* Maximum number of prior attempts at world stop marking	*/ 	/* A value of 1 means that we finish the second time, no matter */ 	/* how long it takes.  Doesn't count the initial root scan	*/ 	/* for a full GC.						*/int GC_deficit = 0;	/* The number of extra calls to GC_mark_some	*/			/* that we have made.				*/void GC_collect_a_little_inner(int n){    int i;        if (GC_dont_gc) return;    if (GC_incremental && GC_collection_in_progress()) {    	for (i = GC_deficit; i < GC_RATE*n; i++) {    	    if (GC_mark_some((ptr_t)0)) {    	        /* Need to finish a collection */#     		ifdef SAVE_CALL_CHAIN        	    GC_save_callers(GC_last_stack);#     		endif#		ifdef PARALLEL_MARK		    GC_wait_for_reclaim();#		endif		if (GC_n_attempts < MAX_PRIOR_ATTEMPTS		    && GC_time_limit != GC_TIME_UNLIMITED) {		  GET_TIME(GC_start_time);		  if (!GC_stopped_mark(GC_timeout_stop_func)) {		    GC_n_attempts++;		    break;		  }		} else {		  (void)GC_stopped_mark(GC_never_stop_func);		}    	        GC_finish_collection();    	        break;    	    }    	}    	if (GC_deficit > 0) GC_deficit -= GC_RATE*n;	if (GC_deficit < 0) GC_deficit = 0;    } else {        GC_maybe_gc();    }}int GC_collect_a_little(void){    int result;    DCL_LOCK_STATE;    LOCK();    GC_collect_a_little_inner(1);    result = (int)GC_collection_in_progress();    UNLOCK();    if (!result && GC_debugging_started) GC_print_all_smashed();    return(result);}/* * Assumes lock is held, signals are disabled. * We stop the world. * If stop_func() ever returns TRUE, we may fail and return FALSE. * Increment GC_gc_no if we succeed. */GC_bool GC_stopped_mark(GC_stop_func stop_func){    unsigned i;    int dummy;    CLOCK_TYPE start_time, current_time;	    if (GC_print_stats)	GET_TIME(start_time);#   if defined(REGISTER_LIBRARIES_EARLY)        GC_cond_register_dynamic_libraries();#   endif    STOP_WORLD();    IF_THREADS(GC_world_stopped = TRUE);    if (GC_print_stats) {	GC_log_printf("--> Marking for collection %lu ",		  (unsigned long)GC_gc_no + 1);	GC_log_printf("after %lu allocd bytes\n",	   	   (unsigned long) GC_bytes_allocd);    }#   ifdef MAKE_BACK_GRAPH      if (GC_print_back_height) {        GC_build_back_graph();      }#   endif    /* Mark from all roots.  */        /* Minimize junk left in my registers and on the stack */            GC_clear_a_few_frames();            GC_noop(0,0,0,0,0,0);	GC_initiate_gc();	for(i = 0;;i++) {	    if ((*stop_func)()) {		    if (GC_print_stats) {		    	GC_log_printf("Abandoned stopped marking after ");			GC_log_printf("%u iterations\n", i);		    }		    GC_deficit = i; /* Give the mutator a chance. */                    IF_THREADS(GC_world_stopped = FALSE);	            START_WORLD();	            return(FALSE);	    }	    if (GC_mark_some((ptr_t)(&dummy))) break;	}	    GC_gc_no++;    if (GC_print_stats) {      GC_log_printf("Collection %lu reclaimed %ld bytes",		    (unsigned long)GC_gc_no - 1,	   	    (long)GC_bytes_found);      GC_log_printf(" ---> heapsize = %lu bytes\n",      	        (unsigned long) GC_heapsize);        /* Printf arguments may be pushed in funny places.  Clear the	*/        /* space.							*/      GC_log_printf("");    }    /* Check all debugged objects for consistency */        if (GC_debugging_started) {            (*GC_check_heap)();        }        IF_THREADS(GC_world_stopped = FALSE);    START_WORLD();    if (GC_print_stats) {      GET_TIME(current_time);      GC_log_printf("World-stopped marking took %lu msecs\n",	            MS_TIME_DIFF(current_time,start_time));    }    return(TRUE);}/* Set all mark bits for the free list whose first entry is q	*/void GC_set_fl_marks(ptr_t q){   ptr_t p;   struct hblk * h, * last_h = 0;   hdr *hhdr;  /* gcc "might be uninitialized" warning is bogus. */   IF_PER_OBJ(size_t sz;)   unsigned bit_no;   for (p = q; p != 0; p = obj_link(p)){	h = HBLKPTR(p);	if (h != last_h) {	  last_h = h; 	  hhdr = HDR(h);	  IF_PER_OBJ(sz = hhdr->hb_sz;)	}	bit_no = MARK_BIT_NO((ptr_t)p - (ptr_t)h, sz);	if (!mark_bit_from_hdr(hhdr, bit_no)) {      	  set_mark_bit_from_hdr(hhdr, bit_no);          ++hhdr -> hb_n_marks;        }   }}#ifdef GC_ASSERTIONS/* Check that all mark bits for the free list whose first entry is q	*//* are set.								*/void GC_check_fl_marks(ptr_t q){   ptr_t p;   for (p = q; p != 0; p = obj_link(p)){	if (!GC_is_marked(p)) {	    GC_err_printf("Unmarked object %p on list %p\n", p, q);	    ABORT("Unmarked local free list entry.");	}   }}#endif/* Clear all mark bits for the free list whose first entry is q	*//* Decrement GC_bytes_found by number of bytes on free list.	*/void GC_clear_fl_marks(ptr_t q){   ptr_t p;   struct hblk * h, * last_h = 0;   hdr *hhdr;   size_t sz;   unsigned bit_no;   for (p = q; p != 0; p = obj_link(p)){	h = HBLKPTR(p);	if (h != last_h) {	  last_h = h; 	  hhdr = HDR(h);	  sz = hhdr->hb_sz;  /* Normally set only once. */	}	bit_no = MARK_BIT_NO((ptr_t)p - (ptr_t)h, sz);	if (mark_bit_from_hdr(hhdr, bit_no)) {	  size_t n_marks = hhdr -> hb_n_marks - 1;      	  clear_mark_bit_from_hdr(hhdr, bit_no);#	  ifdef PARALLEL_MARK	    /* Appr. count, don't decrement to zero! */	    if (0 != n_marks) {              hhdr -> hb_n_marks = n_marks;	    }#	  else            hhdr -> hb_n_marks = n_marks;#	  endif        }	GC_bytes_found -= sz;   }}#if defined(GC_ASSERTIONS) && defined(THREADS) && defined(THREAD_LOCAL_ALLOC)extern void GC_check_tls(void);#endif/* Finish up a collection.  Assumes lock is held, signals are disabled,	*//* but the world is otherwise running.					*/void GC_finish_collection(){    CLOCK_TYPE start_time;    CLOCK_TYPE finalize_time;    CLOCK_TYPE done_time;	#   if defined(GC_ASSERTIONS) && defined(THREADS) \       && defined(THREAD_LOCAL_ALLOC) && !defined(DBG_HDRS_ALL)	/* Check that we marked some of our own data.  		*/        /* FIXME: Add more checks.				*/        GC_check_tls();#   endif    if (GC_print_stats)      GET_TIME(start_time);    GC_bytes_found = 0;#   if defined(LINUX) && defined(__ELF__) && !defined(SMALL_CONFIG)	if (getenv("GC_PRINT_ADDRESS_MAP") != 0) {	  GC_print_address_map();	}#   endif    COND_DUMP;    if (GC_find_leak) {      /* Mark all objects on the free list.  All objects should be */      /* marked when we're done.				   */	{	  word size;		/* current object size		*/	  unsigned kind;	  ptr_t q;	  for (kind = 0; kind < GC_n_kinds; kind++) {	    for (size = 1; size <= MAXOBJGRANULES; size++) {	      q = GC_obj_kinds[kind].ok_freelist[size];	      if (q != 0) GC_set_fl_marks(q);	    }	  }	}	GC_start_reclaim(TRUE);	  /* The above just checks; it doesn't really reclaim anything. */    }    GC_finalize();#   ifdef STUBBORN_ALLOC      GC_clean_changing_list();#   endif    if (GC_print_stats)      GET_TIME(finalize_time);    if (GC_print_back_height) {#     ifdef MAKE_BACK_GRAPH	GC_traverse_back_graph();#     else#	ifndef SMALL_CONFIG	  GC_err_printf("Back height not available: "		        "Rebuild collector with -DMAKE_BACK_GRAPH\n");#  	endif#     endif    }    /* Clear free list mark bits, in case they got accidentally marked   */    /* (or GC_find_leak is set and they were intentionally marked).	 */    /* Also subtract memory remaining from GC_bytes_found count.         */    /* Note that composite objects on free list are cleared.             */    /* Thus accidentally marking a free list is not a problem;  only     */    /* objects on the list itself will be marked, and that's fixed here. */      {	word size;		/* current object size		*/	ptr_t q;	/* pointer to current object	*/	unsigned kind;	for (kind = 0; kind < GC_n_kinds; kind++) {	  for (size = 1; size <= MAXOBJGRANULES; size++) {	    q = GC_obj_kinds[kind].ok_freelist[size];	    if (q != 0) GC_clear_fl_marks(q);	  }	}      }    if (GC_print_stats == VERBOSE)	GC_log_printf("Bytes recovered before sweep - f.l. count = %ld\n",	          (long)GC_bytes_found);        /* Reconstruct free lists to contain everything not marked */        GC_start_reclaim(FALSE);	if (GC_print_stats) {	  GC_log_printf("Heap contains %lu pointer-containing "		        "+ %lu pointer-free reachable bytes\n",		        (unsigned long)GC_composite_in_use,

⌨️ 快捷键说明

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