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

📄 alloc.c

📁 linux下建立JAVA虚拟机的源码KAFFE
💻 C
📖 第 1 页 / 共 3 页
字号:
	GC_printf2(		"\n%lu (atomic) + %lu (composite) collectable bytes in use\n",	        (unsigned long)WORDS_TO_BYTES(GC_atomic_in_use),	        (unsigned long)WORDS_TO_BYTES(GC_composite_in_use));#   endif      GC_n_attempts = 0;      GC_is_full_gc = FALSE;    /* Reset or increment counters for next cycle */      GC_words_allocd_before_gc += GC_words_allocd;      GC_non_gc_bytes_at_gc = GC_non_gc_bytes;      GC_words_allocd = 0;      GC_words_wasted = 0;      GC_mem_freed = 0;      GC_finalizer_mem_freed = 0;      #   ifdef USE_MUNMAP      GC_unmap_old();#   endif#   ifdef PRINTTIMES	GET_TIME(done_time);	GC_printf2("Finalize + initiate sweep took %lu + %lu msecs\n",	           MS_TIME_DIFF(finalize_time,start_time),	           MS_TIME_DIFF(done_time,finalize_time));#   endif}/* Externally callable routine to invoke full, stop-world collection */# if defined(__STDC__) || defined(__cplusplus)    int GC_try_to_collect(GC_stop_func stop_func)# else    int GC_try_to_collect(stop_func)    GC_stop_func stop_func;# endif{    int result;    DCL_LOCK_STATE;        if (GC_debugging_started) GC_print_all_smashed();    GC_INVOKE_FINALIZERS();    DISABLE_SIGNALS();    LOCK();    ENTER_GC();    if (!GC_is_initialized) GC_init_inner();    /* Minimize junk left in my registers */      GC_noop(0,0,0,0,0,0);    result = (int)GC_try_to_collect_inner(stop_func);    EXIT_GC();    UNLOCK();    ENABLE_SIGNALS();    if(result) {        if (GC_debugging_started) GC_print_all_smashed();        GC_INVOKE_FINALIZERS();    }    return(result);}void GC_gcollect GC_PROTO(()){    (void)GC_try_to_collect(GC_never_stop_func);    if (GC_have_errors) GC_print_all_errors();}word GC_n_heap_sects = 0;	/* Number of sections currently in heap. *//* * Use the chunk of memory starting at p of size bytes as part of the heap. * Assumes p is HBLKSIZE aligned, and bytes is a multiple of HBLKSIZE. */void GC_add_to_heap(p, bytes)struct hblk *p;word bytes;{    word words;    hdr * phdr;        if (GC_n_heap_sects >= MAX_HEAP_SECTS) {    	ABORT("Too many heap sections: Increase MAXHINCR or MAX_HEAP_SECTS");    }    phdr = GC_install_header(p);    if (0 == phdr) {    	/* This is extremely unlikely. Can't add it.  This will		*/    	/* almost certainly result in a	0 return from the allocator,	*/    	/* which is entirely appropriate.				*/    	return;    }    GC_heap_sects[GC_n_heap_sects].hs_start = (ptr_t)p;    GC_heap_sects[GC_n_heap_sects].hs_bytes = bytes;    GC_n_heap_sects++;    words = BYTES_TO_WORDS(bytes);    phdr -> hb_sz = words;    phdr -> hb_map = (unsigned char *)1;   /* A value != GC_invalid_map	*/    phdr -> hb_flags = 0;    GC_freehblk(p);    GC_heapsize += bytes;    if ((ptr_t)p <= (ptr_t)GC_least_plausible_heap_addr        || GC_least_plausible_heap_addr == 0) {        GC_least_plausible_heap_addr = (GC_PTR)((ptr_t)p - sizeof(word));        	/* Making it a little smaller than necessary prevents	*/        	/* us from getting a false hit from the variable	*/        	/* itself.  There's some unintentional reflection	*/        	/* here.						*/    }    if ((ptr_t)p + bytes >= (ptr_t)GC_greatest_plausible_heap_addr) {        GC_greatest_plausible_heap_addr = (GC_PTR)((ptr_t)p + bytes);    }}# if !defined(NO_DEBUGGING)void GC_print_heap_sects(){    register unsigned i;        GC_printf1("Total heap size: %lu\n", (unsigned long) GC_heapsize);    for (i = 0; i < GC_n_heap_sects; i++) {        unsigned long start = (unsigned long) GC_heap_sects[i].hs_start;        unsigned long len = (unsigned long) GC_heap_sects[i].hs_bytes;        struct hblk *h;        unsigned nbl = 0;            	GC_printf3("Section %ld from 0x%lx to 0x%lx ", (unsigned long)i,    		   start, (unsigned long)(start + len));    	for (h = (struct hblk *)start; h < (struct hblk *)(start + len); h++) {    	    if (GC_is_black_listed(h, HBLKSIZE)) nbl++;    	}    	GC_printf2("%lu/%lu blacklisted\n", (unsigned long)nbl,    		   (unsigned long)(len/HBLKSIZE));    }}# endifGC_PTR GC_least_plausible_heap_addr = (GC_PTR)ONES;GC_PTR GC_greatest_plausible_heap_addr = 0;ptr_t GC_max(x,y)ptr_t x, y;{    return(x > y? x : y);}ptr_t GC_min(x,y)ptr_t x, y;{    return(x < y? x : y);}# if defined(__STDC__) || defined(__cplusplus)    void GC_set_max_heap_size(GC_word n)# else    void GC_set_max_heap_size(n)    GC_word n;# endif{    GC_max_heapsize = n;}GC_word GC_max_retries = 0;/* * this explicitly increases the size of the heap.  It is used * internally, but may also be invoked from GC_expand_hp by the user. * The argument is in units of HBLKSIZE. * Tiny values of n are rounded up. * Returns FALSE on failure. */GC_bool GC_expand_hp_inner(n)word n;{    word bytes;    struct hblk * space;    word expansion_slop;	/* Number of bytes by which we expect the */    				/* heap to expand soon.			  */    if (n < MINHINCR) n = MINHINCR;    bytes = n * HBLKSIZE;    /* Make sure bytes is a multiple of GC_page_size */      {	word mask = GC_page_size - 1;	bytes += mask;	bytes &= ~mask;      }        if (GC_max_heapsize != 0 && GC_heapsize + bytes > GC_max_heapsize) {        /* Exceeded self-imposed limit */        return(FALSE);    }    space = GET_MEM(bytes);    if( space == 0 ) {#	ifdef CONDPRINT	  if (GC_print_stats) {	    GC_printf1("Failed to expand heap by %ld bytes\n",		       (unsigned long)bytes);	  }#       endif	return(FALSE);    }#   ifdef CONDPRINT      if (GC_print_stats) {	GC_printf2("Increasing heap size by %lu after %lu allocated bytes\n",	           (unsigned long)bytes,	           (unsigned long)WORDS_TO_BYTES(GC_words_allocd));# 	ifdef UNDEFINED	  GC_printf1("Root size = %lu\n", GC_root_size);	  GC_print_block_list(); GC_print_hblkfreelist();	  GC_printf0("\n");#	endif      }#   endif    expansion_slop = WORDS_TO_BYTES(min_words_allocd()) + 4*MAXHINCR*HBLKSIZE;    if (GC_last_heap_addr == 0 && !((word)space & SIGNB)        || (GC_last_heap_addr != 0 && GC_last_heap_addr < (ptr_t)space)) {        /* Assume the heap is growing up */        GC_greatest_plausible_heap_addr =            (GC_PTR)GC_max((ptr_t)GC_greatest_plausible_heap_addr,                           (ptr_t)space + bytes + expansion_slop);    } else {        /* Heap is growing down */        GC_least_plausible_heap_addr =            (GC_PTR)GC_min((ptr_t)GC_least_plausible_heap_addr,                           (ptr_t)space - expansion_slop);    }#   if defined(LARGE_CONFIG)      if (((ptr_t)GC_greatest_plausible_heap_addr <= (ptr_t)space + bytes           || (ptr_t)GC_least_plausible_heap_addr >= (ptr_t)space)	  && GC_heapsize > 0) {	/* GC_add_to_heap will fix this, but ... */	WARN("Too close to address space limit: blacklisting ineffective\n", 0);      }#   endif    GC_prev_heap_addr = GC_last_heap_addr;    GC_last_heap_addr = (ptr_t)space;    GC_add_to_heap(space, bytes);    /* Force GC before we are likely to allocate past expansion_slop */      GC_collect_at_heapsize =	  GC_heapsize + expansion_slop - 2*MAXHINCR*HBLKSIZE;#     if defined(LARGE_CONFIG)        if (GC_collect_at_heapsize < GC_heapsize /* wrapped */)	  GC_collect_at_heapsize = (word)(-1);#     endif    return(TRUE);}/* Really returns a bool, but it's externally visible, so that's clumsy. *//* Arguments is in bytes.						*/# if defined(__STDC__) || defined(__cplusplus)  int GC_expand_hp(size_t bytes)# else  int GC_expand_hp(bytes)  size_t bytes;# endif{    int result;    DCL_LOCK_STATE;        DISABLE_SIGNALS();    LOCK();    if (!GC_is_initialized) GC_init_inner();    result = (int)GC_expand_hp_inner(divHBLKSZ((word)bytes));    if (result) GC_requested_heapsize += bytes;    UNLOCK();    ENABLE_SIGNALS();    return(result);}unsigned GC_fail_count = 0;  			/* How many consecutive GC/expansion failures?	*/			/* Reset by GC_allochblk.			*/GC_bool GC_collect_or_expand(needed_blocks, ignore_off_page)word needed_blocks;GC_bool ignore_off_page;{    if (!GC_incremental && !GC_dont_gc &&	((GC_dont_expand && GC_words_allocd > 0) || GC_should_collect())) {      GC_gcollect_inner();    } else {      word blocks_to_get = GC_heapsize/(HBLKSIZE*GC_free_space_divisor)      			   + needed_blocks;            if (blocks_to_get > MAXHINCR) {          word slop;          	  /* Get the minimum required to make it likely that we		*/	  /* can satisfy the current request in the presence of black-	*/	  /* listing.  This will probably be more than MAXHINCR.	*/          if (ignore_off_page) {              slop = 4;          } else {	      slop = 2*divHBLKSZ(BL_LIMIT);	      if (slop > needed_blocks) slop = needed_blocks;	  }          if (needed_blocks + slop > MAXHINCR) {              blocks_to_get = needed_blocks + slop;          } else {              blocks_to_get = MAXHINCR;          }      }      if (!GC_expand_hp_inner(blocks_to_get)        && !GC_expand_hp_inner(needed_blocks)) {      	if (GC_fail_count++ < GC_max_retries) {      	    WARN("Out of Memory!  Trying to continue ...\n", 0);	    GC_gcollect_inner();	} else {#	    if !defined(AMIGA) || !defined(GC_AMIGA_FASTALLOC)	      WARN("Out of Memory!  Returning NIL!\n", 0);#	    endif	    return(FALSE);	}      } else {#	  ifdef CONDPRINT            if (GC_fail_count && GC_print_stats) {	      GC_printf0("Memory available again ...\n");	    }#	  endif      }    }    return(TRUE);}/* * Make sure the object free list for sz is not empty. * Return a pointer to the first object on the free list. * The object MUST BE REMOVED FROM THE FREE LIST BY THE CALLER. * Assumes we hold the allocator lock and signals are disabled. * */ptr_t GC_allocobj(sz, kind)word sz;int kind;{    ptr_t * flh = &(GC_obj_kinds[kind].ok_freelist[sz]);    GC_bool tried_minor = FALSE;        if (sz == 0) return(0);    while (*flh == 0) {      ENTER_GC();      /* Do our share of marking work */        if(TRUE_INCREMENTAL) GC_collect_a_little_inner(1);      /* Sweep blocks for objects of this size */        GC_continue_reclaim(sz, kind);      EXIT_GC();      if (*flh == 0) {        GC_new_hblk(sz, kind);      }      if (*flh == 0) {        ENTER_GC();	if (GC_incremental && GC_time_limit == GC_TIME_UNLIMITED	    && ! tried_minor ) {	    GC_collect_a_little_inner(1);	    tried_minor = TRUE;	} else {          if (!GC_collect_or_expand((word)1,FALSE)) {	    EXIT_GC();	    return(0);	  }	}	EXIT_GC();      }    }    /* Successful allocation; reset failure count.	*/    GC_fail_count = 0;        return(*flh);}

⌨️ 快捷键说明

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