void jl_gc_collect(void) { size_t actual_allocd = allocd_bytes; total_allocd_bytes += allocd_bytes; allocd_bytes = 0; if (is_gc_enabled) { JL_SIGATOMIC_BEGIN(); jl_in_gc = 1; #if defined(GCTIME) || defined(GC_FINAL_STATS) double t0 = clock_now(); #endif gc_mark(); #ifdef GCTIME JL_PRINTF(JL_STDERR, "mark time %.3f ms\n", (clock_now()-t0)*1000); #endif #if defined(MEMPROFILE) all_pool_stats(); big_obj_stats(); #endif #ifdef GCTIME t0 = clock_now(); #endif sweep_weak_refs(); gc_sweep(); #ifdef GCTIME JL_PRINTF(JL_STDERR, "sweep time %.3f ms\n", (clock_now()-t0)*1000); #endif int nfinal = to_finalize.len; run_finalizers(); jl_in_gc = 0; JL_SIGATOMIC_END(); #if defined(GC_FINAL_STATS) total_gc_time += (clock_now()-t0); total_freed_bytes += freed_bytes; #endif #ifdef OBJPROFILE print_obj_profile(); htable_reset(&obj_counts, 0); #endif // tune collect interval based on current live ratio #if defined(MEMPROFILE) jl_printf(JL_STDERR, "allocd %ld, freed %ld, interval %ld, ratio %.2f\n", actual_allocd, freed_bytes, collect_interval, (double)freed_bytes/(double)actual_allocd); #endif if (freed_bytes < (7*(actual_allocd/10))) { if (collect_interval <= 2*(max_collect_interval/5)) collect_interval = 5*(collect_interval/2); } else { collect_interval = default_collect_interval; } freed_bytes = 0; // if a lot of objects were finalized, re-run GC to finish freeing // their storage if possible. if (nfinal > 100000) jl_gc_collect(); } }
void *jl_gc_managed_realloc(void *d, size_t sz, size_t oldsz, int isaligned) { if (allocd_bytes > collect_interval) jl_gc_collect(); sz = (sz+15) & -16; void *b; #ifdef _P64 b = realloc(d, sz); #elif defined(_OS_WINDOWS_) if (isaligned) b = _aligned_realloc(d, sz, 16); else b = realloc(d, sz); #elif defined(__APPLE__) b = realloc(d, sz); #else // TODO better aligned realloc here b = malloc_a16(sz); if (b != NULL) { memcpy(b, d, oldsz); if (isaligned) free_a16(d); else free(d); } #endif if (b == NULL) jl_throw(jl_memory_exception); allocd_bytes += sz; return b; }
DLLEXPORT void jl_save_system_image(char *fname, char *startscriptname) { jl_gc_collect(); jl_gc_collect(); int en = jl_gc_is_enabled(); jl_gc_disable(); htable_reset(&backref_table, 50000); ios_t f; ios_file(&f, fname, 1, 1, 1, 1); // orphan old Base module if present jl_base_module = (jl_module_t*)jl_get_global(jl_main_module, jl_symbol("Base")); // delete cached slow ASCIIString constructor if present jl_methtable_t *mt = jl_gf_mtable((jl_function_t*)jl_ascii_string_type); jl_array_t *spec = mt->defs->func->linfo->specializations; if (spec->length > 0 && ((jl_lambda_info_t*)jl_cellref(spec,0))->inferred == 0) { mt->cache = JL_NULL; mt->cache_arg1 = JL_NULL; mt->defs->func->linfo->tfunc = (jl_value_t*)jl_null; mt->defs->func->linfo->specializations = NULL; } jl_idtable_type = jl_get_global(jl_base_module, jl_symbol("ObjectIdDict")); jl_serialize_value(&f, jl_array_type->env); jl_serialize_value(&f, jl_main_module); write_int32(&f, jl_get_t_uid_ctr()); write_int32(&f, jl_get_gs_ctr()); htable_reset(&backref_table, 0); ios_t ss; ios_file(&ss, startscriptname, 1, 0, 0, 0); ios_copyall(&f, &ss); ios_close(&ss); ios_putc(0, &f); ios_close(&f); if (en) jl_gc_enable(); }
DLLEXPORT void *jl_gc_counted_realloc(void *p, size_t sz) { if (allocd_bytes > collect_interval) jl_gc_collect(); allocd_bytes += ((sz+1)/2); // NOTE: wild guess at growth amount void *b = realloc(p, sz); if (b == NULL) jl_throw(jl_memory_exception); return b; }
DLLEXPORT void *jl_gc_counted_malloc(size_t sz) { if (allocd_bytes > collect_interval) jl_gc_collect(); allocd_bytes += sz; void *b = malloc(sz); if (b == NULL) jl_throw(jl_memory_exception); return b; }
void *jl_gc_managed_malloc(size_t sz) { if (allocd_bytes > collect_interval) jl_gc_collect(); sz = (sz+15) & -16; void *b = malloc_a16(sz); if (b == NULL) jl_throw(jl_memory_exception); allocd_bytes += sz; return b; }
DLLEXPORT void *jl_gc_counted_realloc_with_old_size(void *p, size_t old, size_t sz) { if (allocd_bytes > collect_interval) jl_gc_collect(); if (sz > old) allocd_bytes += (sz-old); void *b = realloc(p, sz); if (b == NULL) jl_throw(jl_memory_exception); return b; }
jl_mallocptr_t *jl_gc_managed_malloc(size_t sz) { if (allocd_bytes > collect_interval) { jl_gc_collect(); } sz = (sz+15) & -16; void *b = malloc_a16(sz); if (b == NULL) jl_throw(jl_memory_exception); allocd_bytes += sz; return jl_gc_acquire_buffer(b, sz, 1); }
static void *pool_alloc(pool_t *p) { if (allocd_bytes > collect_interval) { jl_gc_collect(); } if (p->freelist == NULL) { add_page(p); } assert(p->freelist != NULL); gcval_t *v = p->freelist; p->freelist = p->freelist->next; v->flags = 0; return v; }
static void *alloc_big(size_t sz) { if (allocd_bytes > collect_interval) { jl_gc_collect(); } size_t offs = BVOFFS*sizeof(void*); if (sz+offs+15 < offs+15) // overflow in adding offs, size was "negative" jl_throw(jl_memory_exception); size_t allocsz = (sz+offs+15) & -16; bigval_t *v = (bigval_t*)malloc_a16(allocsz); allocd_bytes += allocsz; if (v == NULL) jl_throw(jl_memory_exception); v->sz = sz; v->flags = 0; v->next = big_objects; big_objects = v; return &v->_data[0]; }
static void *alloc_big(size_t sz, int isobj) { if (allocd_bytes > collect_interval) { jl_gc_collect(); } sz = (sz+3) & -4; allocd_bytes += sz; size_t offs = BVOFFS*sizeof(void*); if (sz + offs < offs) // overflow in adding offs, size was "negative" jl_raise(jl_memory_exception); bigval_t *v = (bigval_t*)malloc(sz + offs); if (v == NULL) jl_raise(jl_memory_exception); #if defined(MEMDEBUG) || defined(MEMPROFILE) v->sz = sz; #endif v->next = big_objects; v->flags = 0; v->isobj = isobj; big_objects = v; return &v->_data[0]; }
DLLEXPORT void jl_save_system_image(char *fname, char *startscriptname) { jl_gc_collect(); jl_gc_collect(); int en = jl_gc_is_enabled(); jl_gc_disable(); htable_reset(&backref_table, 50000); ios_t f; ios_file(&f, fname, 1, 1, 1, 1); if (jl_current_module != jl_system_module) { // set up for stage 1 bootstrap, where the System module is already // loaded and we are loading an updated copy in a separate module. // step 1: set Base.System = current_module jl_binding_t *b = jl_get_binding_wr(jl_base_module, jl_symbol("System")); b->value = (jl_value_t*)jl_current_module; assert(b->constp); // step 2: set current_module.Base = Base jl_set_const(jl_current_module, jl_symbol("Base"), (jl_value_t*)jl_base_module); // step 3: current_module.System = current_module b = jl_get_binding_wr(jl_current_module, jl_symbol("System")); b->value = (jl_value_t*)jl_current_module; assert(b->constp); // step 4: remove current_module.current_module b = jl_get_binding_wr(jl_current_module, jl_current_module->name); b->value = NULL; b->constp = 0; // step 5: rename current_module to System jl_current_module->name = jl_symbol("System"); // step 6: orphan old system module jl_system_module = jl_current_module; } else { // delete cached slow ASCIIString constructor jl_methtable_t *mt = jl_gf_mtable((jl_function_t*)jl_ascii_string_type); mt->cache = NULL; mt->cache_1arg = NULL; mt->defs->func->linfo->tfunc = (jl_value_t*)jl_null; mt->defs->func->linfo->specializations = NULL; } jl_idtable_type = jl_get_global(jl_system_module, jl_symbol("IdTable")); idtable_list = jl_alloc_cell_1d(0); jl_serialize_value(&f, jl_array_type->env); jl_serialize_value(&f, jl_base_module); jl_serialize_value(&f, jl_current_module); jl_serialize_value(&f, idtable_list); //jl_serialize_finalizers(&f); write_int32(&f, jl_get_t_uid_ctr()); write_int32(&f, jl_get_gs_ctr()); htable_reset(&backref_table, 0); ios_t ss; ios_file(&ss, startscriptname, 1, 0, 0, 0); ios_copyall(&f, &ss); ios_close(&ss); ios_putc(0, &f); ios_close(&f); if (en) jl_gc_enable(); }