/* This code should not be used by anyone... */ #include "config.h" #include "system.h" #include "coretypes.h" #include "tm.h" #include "ggc.h" #include "timevar.h" #include #include #include #undef COLLECT #if defined(COLLECT) && !defined(__i386__) #error COLLECT only works on i386 (for now) #endif struct alloc_zone *tree_zone = NULL; #define BLOCK_SIZE PAGE_SIZE #define MBLOCK_SIZE (BLOCK_SIZE * 64) #define map_anon(hint,sz) mmap(hint,sz,PROT_READ|PROT_WRITE,MAP_ANON|MAP_PRIVATE,-1,0); static char *Hp; static char *HpLim; static size_t allocated; static int context; #ifdef COLLECT static unsigned char inheap[1048576]; #endif void * ggc_alloc (size_t size) { void *ret; if(size >= MBLOCK_SIZE / 8) { size = (size + BLOCK_SIZE-1) & ~(BLOCK_SIZE-1); ret = map_anon(NULL,size); if(ret == MAP_FAILED) goto fail; #ifdef COLLECT if(size / BLOCK_SIZE > 255) abort(); inheap[(unsigned long) ret / BLOCK_SIZE] = size / BLOCK_SIZE; #endif allocated += size; return ret; } size = (size + ALIGNBYTES) & ~ALIGNBYTES; ret = Hp; Hp += size; #ifdef COLLECT if((((unsigned long)ret) >> 12) != (((unsigned long) Hp) >> 12)) { ret = Hp = (char*) (((unsigned long) Hp) & ~4095); Hp += size; } #endif if(Hp > HpLim) { ret = map_anon(HpLim,MBLOCK_SIZE); if(ret == MAP_FAILED) goto fail; #ifdef COLLECT { int i; for(i=0;i 128 * 1024 * 1024) internal_error("runnaway allocation: %lu\n", allocated);*/ if(context) return; if(allocated < 65536 * 1024 || allocated - last_run < 42 * 1024 * 1024) return; timevar_push (TV_GC); //return; //fprintf(stderr,"free heap is: %p - %p\n", Hp, HpLim); memset(mark,0,sizeof(mark)); Hp += BLOCK_SIZE; // XXX; for(i=(unsigned long) Hp / 4096;i<(unsigned long) HpLim / 4096;i++) mark[i] = 1; my_mark(__data_start, _end); ggc_mark_stringpool(); for(i=0;i %lu\n",old_allocated / 1024, allocated / 1024); last_run = allocated; //exit(EXIT_FAILURE); } #else void gt_ggc_m_9tree_node(void *x) { abort(); } void ggc_collect (void) { } #endif void ggc_push_context (void) { context++; } void ggc_pop_context (void) { context--; } void init_ggc_heuristics (void) { #ifdef COLLECT set_param_value ("ggc-min-expand", ggc_min_expand_heuristic()); set_param_value ("ggc-min-heapsize", ggc_min_heapsize_heuristic()); #endif } void init_ggc (void) { #ifndef COLLECT /* Prevent runaway allocations, 80m ought to be enough for anybody */ struct rlimit rl; if(getrlimit(RLIMIT_DATA,&rl) == 0) { rl.rlim_cur = MIN(rl.rlim_max,80 * 1024 * 1024); if(setrlimit(RLIMIT_DATA,&rl) < 0) perror("setrlimit"); } #endif } void ggc_print_statistics (void) { fprintf(stderr,"Total bytes allocated: %lu\n", allocated); } /* These are for splay_tree_new_ggc. */ void * ggc_splay_alloc (int sz, void *nl) { if (nl != NULL) abort (); return ggc_alloc (sz); } void ggc_splay_dont_free (void * x ATTRIBUTE_UNUSED, void *nl) { if (nl != NULL) abort (); } int gt_pch_note_object (void *obj, void *note_ptr_cookie, gt_note_pointers note_ptr_fn) { abort(); } int ggc_marked_p (const void *p) { abort(); }