27 #include <sys/types.h> 30 #ifdef HAVE_SYS_TIME_H 34 #ifdef HAVE_SYS_RESOURCE_H 35 #include <sys/resource.h> 38 #if defined _WIN32 || defined __CYGWIN__ 42 #ifdef HAVE_VALGRIND_MEMCHECK_H 43 # include <valgrind/memcheck.h> 44 # ifndef VALGRIND_MAKE_MEM_DEFINED 45 # define VALGRIND_MAKE_MEM_DEFINED(p, n) VALGRIND_MAKE_READABLE((p), (n)) 47 # ifndef VALGRIND_MAKE_MEM_UNDEFINED 48 # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) VALGRIND_MAKE_WRITABLE((p), (n)) 51 # define VALGRIND_MAKE_MEM_DEFINED(p, n) 52 # define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 55 #define rb_setjmp(env) RUBY_SETJMP(env) 56 #define rb_jmp_buf rb_jmpbuf_t 62 # define alloca __builtin_alloca 79 #ifndef GC_MALLOC_LIMIT 80 #define GC_MALLOC_LIMIT 8000000 82 #define HEAP_MIN_SLOTS 10000 96 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE 101 #define nomem_error GET_VM()->special_exceptions[ruby_error_nomemory] 103 #if SIZEOF_LONG == SIZEOF_VOIDP 104 # define nonspecial_obj_id(obj) (VALUE)((SIGNED_VALUE)(obj)|FIXNUM_FLAG) 105 # define obj_id_to_ref(objid) ((objid) ^ FIXNUM_FLAG) 106 #elif SIZEOF_LONG_LONG == SIZEOF_VOIDP 107 # define nonspecial_obj_id(obj) LL2NUM((SIGNED_VALUE)(obj) / 2) 108 # define obj_id_to_ref(objid) (FIXNUM_P(objid) ? \ 109 ((objid) ^ FIXNUM_FLAG) : (NUM2PTR(objid) << 1)) 111 # error not supported 117 #define GC_PROFILE_MORE_DETAIL 0 145 time =
usage.ru_utime;
148 FILETIME creation_time, exit_time, kernel_time, user_time;
153 if (GetProcessTimes(GetCurrentProcess(),
154 &creation_time, &exit_time, &kernel_time, &user_time) == 0)
158 memcpy(&ui, &user_time,
sizeof(FILETIME));
159 q = ui.QuadPart / 10L;
160 t = (
DWORD)(q % 1000000L) * 1e-6;
165 t += (double)(
DWORD)(q >> 16) * (1 << 16);
166 t += (
DWORD)q & ~(~0 << 16);
174 #define GC_PROF_TIMER_START do {\ 175 if (objspace->profile.run) {\ 176 if (!objspace->profile.record) {\ 177 objspace->profile.size = 1000;\ 178 objspace->profile.record = malloc(sizeof(gc_profile_record) * objspace->profile.size);\ 180 if (count >= objspace->profile.size) {\ 181 objspace->profile.size += 1000;\ 182 objspace->profile.record = realloc(objspace->profile.record, sizeof(gc_profile_record) * objspace->profile.size);\ 184 if (!objspace->profile.record) {\ 185 rb_bug("gc_profile malloc or realloc miss");\ 187 MEMZERO(&objspace->profile.record[count], gc_profile_record, 1);\ 188 gc_time = getrusage_time();\ 189 objspace->profile.record[count].gc_invoke_time = gc_time - objspace->profile.invoke_time;\ 193 #define GC_PROF_TIMER_STOP(marked) do {\ 194 if (objspace->profile.run) {\ 195 gc_time = getrusage_time() - gc_time;\ 196 if (gc_time < 0) gc_time = 0;\ 197 objspace->profile.record[count].gc_time = gc_time;\ 198 objspace->profile.record[count].is_marked = !!(marked);\ 199 GC_PROF_SET_HEAP_INFO(objspace->profile.record[count]);\ 200 objspace->profile.count++;\ 204 #if GC_PROFILE_MORE_DETAIL 205 #define INIT_GC_PROF_PARAMS double gc_time = 0, sweep_time = 0;\ 206 size_t count = objspace->profile.count, total = 0, live = 0 208 #define GC_PROF_MARK_TIMER_START double mark_time = 0;\ 210 if (objspace->profile.run) {\ 211 mark_time = getrusage_time();\ 215 #define GC_PROF_MARK_TIMER_STOP do {\ 216 if (objspace->profile.run) {\ 217 mark_time = getrusage_time() - mark_time;\ 218 if (mark_time < 0) mark_time = 0;\ 219 objspace->profile.record[objspace->profile.count].gc_mark_time = mark_time;\ 223 #define GC_PROF_SWEEP_TIMER_START do {\ 224 if (objspace->profile.run) {\ 225 sweep_time = getrusage_time();\ 229 #define GC_PROF_SWEEP_TIMER_STOP do {\ 230 if (objspace->profile.run) {\ 231 sweep_time = getrusage_time() - sweep_time;\ 232 if (sweep_time < 0) sweep_time = 0;\ 233 objspace->profile.record[count].gc_sweep_time = sweep_time;\ 236 #define GC_PROF_SET_MALLOC_INFO do {\ 237 if (objspace->profile.run) {\ 238 gc_profile_record *record = &objspace->profile.record[objspace->profile.count];\ 239 record->allocate_increase = malloc_increase;\ 240 record->allocate_limit = malloc_limit; \ 243 #define GC_PROF_SET_HEAP_INFO(record) do {\ 244 live = objspace->heap.live_num;\ 245 total = heaps_used * HEAP_OBJ_LIMIT;\ 246 (record).heap_use_slots = heaps_used;\ 247 (record).heap_live_objects = live;\ 248 (record).heap_free_objects = total - live;\ 249 (record).heap_total_objects = total;\ 250 (record).have_finalize = deferred_final_list ? Qtrue : Qfalse;\ 251 (record).heap_use_size = live * sizeof(RVALUE);\ 252 (record).heap_total_size = total * sizeof(RVALUE);\ 254 #define GC_PROF_INC_LIVE_NUM objspace->heap.live_num++ 255 #define GC_PROF_DEC_LIVE_NUM objspace->heap.live_num-- 257 #define INIT_GC_PROF_PARAMS double gc_time = 0;\ 258 size_t count = objspace->profile.count, total = 0, live = 0 259 #define GC_PROF_MARK_TIMER_START 260 #define GC_PROF_MARK_TIMER_STOP 261 #define GC_PROF_SWEEP_TIMER_START 262 #define GC_PROF_SWEEP_TIMER_STOP 263 #define GC_PROF_SET_MALLOC_INFO 264 #define GC_PROF_SET_HEAP_INFO(record) do {\ 265 live = objspace->heap.live_num;\ 266 total = heaps_used * HEAP_OBJ_LIMIT;\ 267 (record).heap_total_objects = total;\ 268 (record).heap_use_size = live * sizeof(RVALUE);\ 269 (record).heap_total_size = total * sizeof(RVALUE);\ 271 #define GC_PROF_INC_LIVE_NUM 272 #define GC_PROF_DEC_LIVE_NUM 276 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__) 277 #pragma pack(push, 1) 310 #if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__) 333 #define STACK_CHUNK_SIZE 500 349 #define CALC_EXACT_MALLOC_SIZE 0 355 #if CALC_EXACT_MALLOC_SIZE 356 size_t allocated_size;
399 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE 400 #define rb_objspace (*GET_VM()->objspace) 401 #define ruby_initial_gc_stress initial_params.gc_stress 407 #define malloc_limit objspace->malloc_params.limit 408 #define malloc_increase objspace->malloc_params.increase 409 #define heaps objspace->heap.ptr 410 #define heaps_length objspace->heap.length 411 #define heaps_used objspace->heap.used 412 #define freelist objspace->heap.freelist 413 #define lomem objspace->heap.range[0] 414 #define himem objspace->heap.range[1] 415 #define heaps_inc objspace->heap.increment 416 #define heaps_freed objspace->heap.freed 417 #define dont_gc objspace->flags.dont_gc 418 #define during_gc objspace->flags.during_gc 419 #define finalizing objspace->flags.finalizing 420 #define finalizer_table objspace->final.table 421 #define deferred_final_list objspace->final.deferred 422 #define global_List objspace->global_list 423 #define ruby_gc_stress objspace->gc_stress 424 #define initial_malloc_limit initial_params.initial_malloc_limit 425 #define initial_heap_min_slots initial_params.initial_heap_min_slots 426 #define initial_free_min initial_params.initial_free_min 430 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE 435 memset(objspace, 0,
sizeof(*objspace));
449 char *malloc_limit_ptr, *heap_min_slots_ptr, *free_min_ptr;
453 malloc_limit_ptr =
getenv(
"RUBY_GC_MALLOC_LIMIT");
454 if (malloc_limit_ptr !=
NULL) {
455 int malloc_limit_i = atoi(malloc_limit_ptr);
457 fprintf(stderr,
"malloc_limit=%d (%d)\n",
459 if (malloc_limit_i > 0) {
464 heap_min_slots_ptr =
getenv(
"RUBY_HEAP_MIN_SLOTS");
465 if (heap_min_slots_ptr !=
NULL) {
466 int heap_min_slots_i = atoi(heap_min_slots_ptr);
468 fprintf(stderr,
"heap_min_slots=%d (%d)\n",
470 if (heap_min_slots_i > 0) {
476 free_min_ptr =
getenv(
"RUBY_FREE_MIN");
477 if (free_min_ptr !=
NULL) {
478 int free_min_i = atoi(free_min_ptr);
481 if (free_min_i > 0) {
487 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE 531 #define HEAP_SIZE 0x4000 539 #define HEAP_OBJ_LIMIT (unsigned int)(HEAP_SIZE / sizeof(struct RVALUE)) 574 fprintf(stderr,
"[FATAL] failed to allocate memory\n");
586 fprintf(stderr,
"[FATAL] failed to allocate memory\n");
716 fprintf(stderr,
"[FATAL] %s\n",
msg);
741 fprintf(stderr,
"[FATAL] failed to allocate memory\n");
752 if ((ssize_t)
size < 0) {
757 #if CALC_EXACT_MALLOC_SIZE 758 size +=
sizeof(size_t);
774 #if CALC_EXACT_MALLOC_SIZE 777 ((
size_t *)mem)[0] =
size;
778 mem = (
size_t *)mem + 1;
784 #define TRY_WITH_GC(alloc) do { \ 786 (!garbage_collect_with_gvl(objspace) || \ 807 if ((ssize_t)
size < 0) {
818 #if CALC_EXACT_MALLOC_SIZE 819 size +=
sizeof(size_t);
821 ptr = (
size_t *)ptr - 1;
835 #if CALC_EXACT_MALLOC_SIZE 837 ((
size_t *)mem)[0] =
size;
838 mem = (
size_t *)mem + 1;
847 #if CALC_EXACT_MALLOC_SIZE 849 ptr = ((
size_t *)ptr) - 1;
850 size = ((
size_t*)ptr)[0];
868 if (n != 0 &&
size !=
len / n) {
909 if (n != 0 &&
size !=
len / n) {
995 if (tmp->
varptr == addr) {
1073 register RVALUE *mid_membase;
1074 mid = (
lo +
hi) / 2;
1079 else if (mid_membase >
membase) {
1094 heaps->limit = objs;
1102 p->as.free.flags = 0;
1118 for (
i = 0;
i <
add;
i++) {
1129 #ifdef USE_SIGALTSTACK 1133 void *tmp = th->altstack;
1156 size_t next_heaps_length = (size_t)(
heaps_used * 1.8);
1159 next_heaps_length++;
1187 #define RANY(o) ((RVALUE*)(o)) 1198 rb_bug(
"object allocation during garbage collection phase");
1250 data->dfree = dfree;
1251 data->dmark = dmark;
1266 data->typed_flag = 1;
1295 #define SET_STACK_END (SET_MACHINE_STACK_END(&th->machine_stack_end), th->machine_register_stack_end = rb_ia64_bsp()) 1297 #define SET_STACK_END SET_MACHINE_STACK_END(&th->machine_stack_end) 1300 #define STACK_START (th->machine_stack_start) 1301 #define STACK_END (th->machine_stack_end) 1302 #define STACK_LEVEL_MAX (th->machine_stack_maxsize/sizeof(VALUE)) 1304 #if STACK_GROW_DIRECTION < 0 1305 # define STACK_LENGTH (size_t)(STACK_START - STACK_END) 1306 #elif STACK_GROW_DIRECTION > 0 1307 # define STACK_LENGTH (size_t)(STACK_END - STACK_START + 1) 1309 # define STACK_LENGTH ((STACK_END < STACK_START) ? (size_t)(STACK_START - STACK_END) \ 1310 : (size_t)(STACK_END - STACK_START + 1)) 1312 #if !STACK_GROW_DIRECTION 1353 stack->
cache = chunk;
1363 chunk = stack->
cache;
1402 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE 1409 while (chunk !=
NULL) {
1432 if (stack->
index == 1) {
1449 for(
i=0;
i < 4;
i++) {
1465 #if !(defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK)) 1475 ret = (
VALUE*)rb_ia64_bsp() - th->machine_register_stack_start >
1476 th->machine_register_stack_maxsize/
sizeof(
VALUE) - water_mark;
1483 #define STACKFRAME_FOR_CALL_CFUNC 512 1488 #if defined(POSIX_SIGNAL) && defined(SIGSEGV) && defined(HAVE_SIGALTSTACK) 1495 #define MARK_STACK_EMPTY (mark_stack_ptr == mark_stack) 1506 if (!mstack->
index)
return;
1518 register size_t hi,
lo, mid;
1527 mid = (
lo +
hi) / 2;
1571 #define rb_gc_mark_locations(start, end) gc_mark_locations(objspace, (start), (end)) 1648 switch (def->
type) {
1792 rb_bug(
"rb_gc_mark() called for broken object");
1946 for (
i=0;
i <
len;
i++) {
1958 #define STR_ASSOC FL_USER3 1968 if (mark_func) (*mark_func)(
DATA_PTR(obj));
1979 for (
i = 0;
i <
len;
i++) {
2035 rb_bug(
"rb_gc_mark(): unknown data type 0x%x(%p) %s",
2047 p->as.free.flags = 0;
2056 RVALUE *tmp =
p->as.free.next;
2060 p->as.free.flags = 0;
2129 size_t free_num = 0, final_num = 0;
2134 p = sweep_slot->
slot; pend =
p + sweep_slot->
limit;
2136 if (!(
p->as.basic.flags &
FL_MARK)) {
2137 if (
p->as.basic.flags &&
2163 if (final_num + free_num == sweep_slot->
limit &&
2168 RDATA(pp)->dmark = (void (*)(
void *))(
VALUE)sweep_slot;
2171 sweep_slot->
limit = final_num;
2217 if (
GET_VM()->unlinked_method_entry_list) {
2350 RANY(
p)->as.free.flags = 0;
2369 p->as.data.data = fptr;
2380 rb_bug(
"obj_free() called for broken object");
2392 RANY(obj)->as.object.as.heap.ivptr) {
2393 xfree(
RANY(obj)->as.object.as.heap.ivptr);
2418 if (
RANY(obj)->as.hash.ntbl) {
2423 if (
RANY(obj)->as.regexp.ptr) {
2430 RDATA(obj)->dfree =
RANY(obj)->as.typeddata.type->function.dfree;
2435 else if (
RANY(obj)->as.data.dfree) {
2442 if (
RANY(obj)->as.match.rmatch) {
2443 struct rmatch *rm =
RANY(obj)->as.match.rmatch;
2451 if (
RANY(obj)->as.file.fptr) {
2475 if (
RANY(obj)->as.node.u1.tbl) {
2487 RANY(obj)->as.rstruct.as.heap.ptr) {
2488 xfree(
RANY(obj)->as.rstruct.as.heap.ptr);
2493 rb_bug(
"gc_sweep(): unknown data type 0x%x(%p)",
2502 #if STACK_GROW_DIRECTION < 0 2503 #define GET_STACK_BOUNDS(start, end, appendix) ((start) = STACK_END, (end) = STACK_START) 2504 #elif STACK_GROW_DIRECTION > 0 2505 #define GET_STACK_BOUNDS(start, end, appendix) ((start) = STACK_START, (end) = STACK_END+(appendix)) 2507 #define GET_STACK_BOUNDS(start, end, appendix) \ 2508 ((STACK_END < STACK_START) ? \ 2509 ((start) = STACK_END, (end) = STACK_START) : ((start) = STACK_START, (end) = STACK_END+(appendix))) 2512 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0])) 2520 } save_regs_gc_mark;
2521 VALUE *stack_start, *stack_end;
2536 #if defined(__mc68000__) 2590 if (
GC_NOTIFY) printf(
"start garbage_collect()\n");
2611 if (
GC_NOTIFY) printf(
"end garbage_collect()\n");
2625 VALUE *stack_start, *stack_end;
2736 for (; pstart != pend; pstart++) {
2742 if (pstart != pend) {
2743 if ((*
args->callback)(pstart, pend,
sizeof(
RVALUE),
args->data)) {
2795 objspace->flags.dont_lazy_sweep =
TRUE;
2814 for (;
p != pend;
p++) {
2815 if (
p->as.basic.flags) {
2826 if (!
p->as.basic.klass)
continue;
2934 VALUE obj, block, table;
2956 table = (
VALUE)data;
2961 RBASIC(table)->klass = 0;
2976 table = (
VALUE)data;
3032 free_func =
RDATA(obj)->dfree;
3126 p->as.free.flags = 0;
3128 RDATA(
p)->dfree =
RANY(
p)->as.typeddata.type->function.dfree;
3133 else if (
RANY(
p)->as.data.dfree) {
3135 RANY(
p)->as.free.next = final_list;
3140 if (
RANY(
p)->as.file.fptr) {
3142 RANY(
p)->as.free.next = final_list;
3184 #if SIZEOF_LONG == SIZEOF_VOIDP 3185 #define NUM2PTR(x) NUM2ULONG(x) 3186 #elif SIZEOF_LONG_LONG == SIZEOF_VOIDP 3187 #define NUM2PTR(x) NUM2ULL(x) 3203 if ((ptr %
sizeof(
RVALUE)) == (4 << 2)) {
3339 for (;
p < pend;
p++) {
3340 if (
p->as.basic.flags) {
3362 #define COUNT_TYPE(t) case (t): type = ID2SYM(rb_intern(#t)); break; 3469 #if CALC_EXACT_MALLOC_SIZE 3480 gc_malloc_allocated_size(
VALUE self)
3495 gc_malloc_allocations(
VALUE self)
3521 #if GC_PROFILE_MORE_DETAIL 3560 rb_str_cat2(
result,
"Index Invoke Time(sec) Use Size(byte) Total Size(byte) Total Object GC Time(ms)\n");
3563 #if !GC_PROFILE_MORE_DETAIL 3572 #if !GC_PROFILE_MORE_DETAIL 3576 #if GC_PROFILE_MORE_DETAIL 3579 rb_str_cat2(
result,
"Index Allocate Increase Allocate Limit Use Slot Have Finalize Mark Time(ms) Sweep Time(ms)\n");
3718 #if CALC_EXACT_MALLOC_SIZE
static void mark_hash(rb_objspace_t *objspace, st_table *tbl)
void rb_gc_finalize_deferred(void)
size_t heap_total_objects
void(* RUBY_DATA_FUNC)(void *)
static int mark_entry(ID key, VALUE value, st_data_t data)
int * ruby_initial_gc_stress_ptr
#define VALGRIND_MAKE_MEM_UNDEFINED(p, n)
static VALUE UINT2NUM(unsigned int v)
int ruby_thread_has_gvl_p(void)
static void * vm_xcalloc(rb_objspace_t *objspace, size_t count, size_t elsize)
unsigned int initial_free_min
void rb_bug(const char *fmt,...)
static VALUE gc_profile_disable(void)
static int set_zero(st_data_t key, st_data_t val, st_data_t arg)
VALUE rb_obj_id(VALUE obj)
#define rb_gc_mark_locations(start, end)
void rb_objspace_free(rb_objspace_t *objspace)
#define RCLASS_CONST_TBL(c)
union rb_method_definition_struct::@39 body
static void pop_mark_stack_chunk(mark_stack_t *stack)
static size_t vm_malloc_prepare(rb_objspace_t *objspace, size_t size)
static VALUE id2ref(VALUE obj, VALUE objid)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
static VALUE os_each_obj(int argc, VALUE *argv, VALUE os)
static int is_pointer_to_heap(rb_objspace_t *objspace, void *ptr)
static void * vm_xmalloc(rb_objspace_t *objspace, size_t size)
#define FLUSH_REGISTER_WINDOWS
static VALUE run_single_final(VALUE arg)
if(len<=MAX_WORD_LENGTH &&len >=MIN_WORD_LENGTH)
#define ATOMIC_EXCHANGE(var, val)
VALUE rb_obj_is_thread(VALUE obj)
#define GC_PROF_DEC_LIVE_NUM
struct rb_objspace::@22 heap
struct rb_data_type_struct::@34 function
static int stack_check(int water_mark)
void * ruby_xmalloc2(size_t n, size_t size)
VALUE rb_ary_push(VALUE ary, VALUE item)
static void gc_mark_stacked_objects(rb_objspace_t *objspace)
#define INIT_GC_PROF_PARAMS
void * ruby_xrealloc2(void *ptr, size_t n, size_t size)
static VALUE INT2NUM(int v)
static VALUE count_objects(int argc, VALUE *argv, VALUE os)
#define initial_heap_min_slots
#define STACK_UPPER(x, a, b)
VALUE rb_protect(VALUE(*proc)(VALUE), VALUE data, int *state)
struct RVALUE::@19::@20 free
void rb_raise(VALUE exc, const char *fmt,...)
int rb_io_fptr_finalize(rb_io_t *)
static void ruby_memerror(void)
int ruby_get_stack_grow_direction(volatile VALUE *addr)
void rb_sweep_method_entry(void *vm)
VALUE rb_obj_is_kind_of(VALUE, VALUE)
#define GC_PROF_MARK_TIMER_START
static int mark_keyvalue(VALUE key, VALUE value, st_data_t data)
#define RARRAY_LEN(ARRAY)
VALUE rb_ary_new3(long n,...)
static VALUE gc_profile_total_time(VALUE self)
#define nd_set_type(n, t)
void rb_objspace_each_objects(each_obj_callback *callback, void *data)
#define RSTRUCT_EMBED_LEN_MASK
void rb_gc_mark(VALUE ptr)
static void before_gc_sweep(rb_objspace_t *objspace)
#define ATOMIC_PTR_EXCHANGE(var, val)
void rb_gc_register_address(VALUE *addr)
VALUE rb_io_write(VALUE, VALUE)
static void init_heap(rb_objspace_t *objspace)
#define GC_PROF_SET_MALLOC_INFO
static void after_gc_sweep(rb_objspace_t *objspace)
void callback(ffi_cif *cif, void *resp, void **args, void *ctx)
VALUE writeconv_pre_ecopts
static int mark_const_entry_i(ID key, const rb_const_entry_t *ce, st_data_t data)
int ruby_stack_grow_direction
void rb_mark_method_entry(const rb_method_entry_t *me)
static int garbage_collect(rb_objspace_t *objspace)
const char * rb_obj_classname(VALUE)
static void push_mark_stack(mark_stack_t *, VALUE)
void rb_gc_force_recycle(VALUE p)
static void rest_sweep(rb_objspace_t *)
static int lazy_sweep(rb_objspace_t *objspace)
static VALUE objspace_each_objects(VALUE arg)
#define ruby_initial_gc_stress
static VALUE define_final(int argc, VALUE *argv, VALUE os)
static int force_chain_object(st_data_t key, st_data_t val, st_data_t arg)
#define obj_id_to_ref(objid)
void rb_global_variable(VALUE *var)
static void mark_current_machine_context(rb_objspace_t *objspace, rb_thread_t *th)
static int mark_method_entry_i(ID key, const rb_method_entry_t *me, st_data_t data)
VALUE data[STACK_CHUNK_SIZE]
void rb_exc_raise(VALUE mesg)
static void finalize_list(rb_objspace_t *objspace, RVALUE *p)
static void set_heaps_increment(rb_objspace_t *objspace)
static size_t xmalloc2_size(size_t n, size_t size)
void * ruby_xcalloc(size_t n, size_t size)
#define GET_STACK_BOUNDS(start, end, appendix)
#define ATOMIC_SET(var, val)
#define MEMZERO(p, type, n)
static void negative_size_allocation_error(const char *msg)
void rb_free_generic_ivar(VALUE)
#define RUBY_VM_SET_FINALIZER_INTERRUPT(th)
unsigned int initial_heap_min_slots
int ruby_disable_gc_stress
void rb_ary_free(VALUE ary)
void rb_mark_end_proc(void)
static void gc_mark(rb_objspace_t *objspace, VALUE ptr)
static void mark_m_tbl(rb_objspace_t *objspace, st_table *tbl)
void rb_vm_mark(void *ptr)
VALUE rb_hash_aset(VALUE hash, VALUE key, VALUE val)
static void * gc_with_gvl(void *ptr)
void rb_gc_copy_finalizer(VALUE dest, VALUE obj)
#define GC_PROF_SWEEP_TIMER_STOP
static void finalize_deferred(rb_objspace_t *objspace)
static void add_freelist(rb_objspace_t *objspace, RVALUE *p)
unsigned int initial_malloc_limit
static void * negative_size_allocation_error_with_gvl(void *ptr)
void rb_gc_unregister_address(VALUE *addr)
static int pop_mark_stack(mark_stack_t *, VALUE *)
static VALUE gc_stress_get(VALUE self)
static void initial_expand_heap(rb_objspace_t *objspace)
VALUE rb_str_cat2(VALUE, const char *)
RUBY_EXTERN VALUE rb_cBasicObject
void rb_clear_cache_by_class(VALUE)
struct gc_profile_record gc_profile_record
void rb_free_method_entry(rb_method_entry_t *me)
RUBY_EXTERN VALUE rb_mKernel
static void vm_xfree(rb_objspace_t *objspace, void *ptr)
static void mark_locations_array(rb_objspace_t *objspace, register VALUE *x, register long n)
#define nonspecial_obj_id(obj)
static void push_mark_stack_chunk(mark_stack_t *stack)
int ruby_stack_check(void)
static VALUE os_obj_of(VALUE of)
void rb_mark_generic_ivar_tbl(void)
VALUE rb_obj_is_mutex(VALUE obj)
#define NEWOBJ(obj, type)
void onig_region_free(OnigRegion *r, int free_self)
struct rb_io_t::rb_io_enc_t encs
struct rb_objspace::@25 profile
VALUE writeconv_asciicompat
struct force_finalize_list * next
static int free_const_entry_i(ID key, rb_const_entry_t *ce, st_data_t data)
void rb_gc_register_mark_object(VALUE obj)
gc_profile_record * record
void rb_gc_mark_global_tbl(void)
static void assign_heap_slot(rb_objspace_t *objspace)
void rb_gc_mark_symbols(void)
size_t rb_objspace_data_type_memsize(VALUE obj)
#define RBIGNUM_DIGITS(b)
NODE * rb_node_newnode(enum node_type type, VALUE a0, VALUE a1, VALUE a2)
void rb_gc_mark_machine_stack(rb_thread_t *th)
#define rb_thread_raised_clear(th)
static void * vm_malloc_fixup(rb_objspace_t *objspace, void *mem, size_t size)
static void gc_mark_locations(rb_objspace_t *objspace, VALUE *start, VALUE *end)
struct rb_objspace::@21 malloc_params
static void allocate_sorted_heaps(rb_objspace_t *objspace, size_t next_heaps_length)
struct rb_objspace::@23 flags
#define initial_malloc_limit
void rb_define_module_function(VALUE module, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a module function for module.
struct RRational rational
static double getrusage_time(void)
static VALUE gc_profile_report(int argc, VALUE *argv, VALUE self)
VALUE rb_sprintf(const char *format,...)
#define STACKFRAME_FOR_CALL_CFUNC
static void make_deferred(RVALUE *p)
static void make_io_deferred(RVALUE *p)
static void add_stack_chunk_cache(mark_stack_t *stack, stack_chunk_t *chunk)
#define MEMMOVE(p1, p2, type, n)
static void run_final(rb_objspace_t *objspace, VALUE obj)
static int os_obj_of_i(void *vstart, void *vend, size_t stride, void *data)
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
#define rb_thread_raised_set(th, f)
static void mark_const_tbl(rb_objspace_t *objspace, st_table *tbl)
static void mark_tbl(rb_objspace_t *objspace, st_table *tbl)
void Init_stack(volatile VALUE *addr)
VALUE tied_io_for_writing
static VALUE lazy_sweep_enable(void)
#define GC_PROF_MARK_TIMER_STOP
static VALUE gc_profile_enable_get(VALUE self)
const char * rb_objspace_data_type_name(VALUE obj)
void rb_free_const_table(st_table *tbl)
static void * ruby_memerror_body(void *dummy)
void rb_mark_tbl(st_table *tbl)
void rb_mark_generic_ivar(VALUE)
static int mark_key(VALUE key, VALUE value, st_data_t data)
register unsigned int len
VALUE rb_gc_disable(void)
#define RARRAY_PTR(ARRAY)
#define SET_MACHINE_STACK_END(p)
VALUE rb_ensure(VALUE(*b_proc)(ANYARGS), VALUE data1, VALUE(*e_proc)(ANYARGS), VALUE data2)
struct RString::@28::@29 heap
static VALUE gc_stress_set(VALUE self, VALUE flag)
int rb_garbage_collect(void)
#define GC_PROF_TIMER_STOP(marked)
int rb_respond_to(VALUE, ID)
VALUE rb_define_module_under(VALUE outer, const char *name)
void rb_gc_set_params(void)
void * ruby_xmalloc(size_t size)
static VALUE gc_profile_result(void)
VALUE rb_data_typed_object_alloc(VALUE klass, void *datap, const rb_data_type_t *type)
void * ruby_xrealloc(void *ptr, size_t size)
struct sorted_heaps_slot * sorted
static void free_unused_heaps(rb_objspace_t *objspace)
void rb_gc_mark_parser(void)
static void free_stack_chunks(mark_stack_t *)
static VALUE gc_profile_record_get(void)
static int ready_to_gc(rb_objspace_t *objspace)
VALUE rb_exc_new3(VALUE etype, VALUE str)
int getrusage(int who, struct rusage *r_usage)
static void mark_method_entry(rb_objspace_t *objspace, const rb_method_entry_t *me)
VALUE rb_block_proc(void)
rb_method_definition_t * def
void rb_set_errinfo(VALUE err)
void rb_mark_set(st_table *tbl)
#define GC_PROF_INC_LIVE_NUM
size_t ruby_stack_length(VALUE **p)
VALUE rb_hash_aref(VALUE hash, VALUE key)
static VALUE gc_count(VALUE self)
static int obj_free(rb_objspace_t *, VALUE)
VALUE rb_str_catf(VALUE str, const char *format,...)
#define RCLASS_IV_INDEX_TBL(c)
struct gc_list * global_list
static int garbage_collect_with_gvl(rb_objspace_t *objspace)
#define VALGRIND_MAKE_MEM_DEFINED(p, n)
VALUE rb_obj_is_fiber(VALUE obj)
static int rb_special_const_p(VALUE obj)
static stack_chunk_t * stack_chunk_alloc(void)
static void unlink_heap_slot(rb_objspace_t *objspace, struct heaps_slot *slot)
static void rb_objspace_call_finalizer(rb_objspace_t *objspace)
struct rb_encoding_entry * list
static int is_mark_stask_empty(mark_stack_t *stack)
void rb_gc_mark_unlinked_live_method_entries(void *pvm)
int each_obj_callback(void *, void *, size_t, void *)
rb_objspace_t * rb_objspace_alloc(void)
#define GC_PROF_TIMER_START
static int free_method_entry_i(ID key, rb_method_entry_t *me, st_data_t data)
static void add_heap_slots(rb_objspace_t *objspace, size_t add)
VALUE rb_eval_cmd(VALUE, VALUE, int)
static void run_finalizer(rb_objspace_t *objspace, VALUE objid, VALUE table)
struct mark_stack mark_stack_t
#define rb_thread_raised_p(th, f)
static unsigned int hash(const char *str, unsigned int len)
#define RETURN_ENUMERATOR(obj, argc, argv)
struct rmatch_offset * char_offset
static void init_mark_stack(mark_stack_t *stack)
void rb_gc_mark_maybe(VALUE obj)
static void gc_marks(rb_objspace_t *objspace)
#define assert(condition)
static void shrink_stack_chunk_cache(mark_stack_t *stack)
const char * rb_id2name(ID id)
#define ruby_native_thread_p()
static void slot_sweep(rb_objspace_t *, struct heaps_slot *)
const rb_data_type_t * type
#define RTYPEDDATA_DATA(v)
static void * vm_xrealloc(rb_objspace_t *objspace, void *ptr, size_t size)
ruby_gc_params_t initial_params
#define rb_check_frozen(obj)
#define RBIGNUM_EMBED_FLAG
struct RTypedData typeddata
RUBY_EXTERN VALUE rb_stdout
void * rb_thread_call_with_gvl(void *(*func)(void *), void *data1)
void rb_gc_call_finalizer_at_exit(void)
VALUE rb_obj_freeze(VALUE)
#define deferred_final_list
#define SPECIAL_CONST_P(x)
struct rb_objspace rb_objspace_t
static int heaps_increment(rb_objspace_t *objspace)
static void gc_mark_children(rb_objspace_t *objspace, VALUE ptr)
VALUE rb_define_module(const char *name)
struct RArray::@31::@32 heap
void rb_mark_hash(st_table *tbl)
each_obj_callback * callback
static VALUE undefine_final(VALUE os, VALUE obj)
static VALUE gc_profile_clear(void)
void rb_gc_mark_encodings(void)
#define RTYPEDDATA_TYPE(v)
static int gc_lazy_sweep(rb_objspace_t *objspace)
struct heaps_slot * sweep_slots
static VALUE gc_stat(int argc, VALUE *argv, VALUE self)
static void mark_set(rb_objspace_t *objspace, st_table *tbl)
void onig_free(regex_t *reg)
#define OBJSETUP(obj, c, t)
void ruby_init_stack(volatile VALUE *)
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
VALUE rb_str_new2(const char *)
struct stack_chunk stack_chunk_t
static VALUE gc_profile_enable(void)
void rb_free_m_table(st_table *tbl)
VALUE rb_data_object_alloc(VALUE klass, void *datap, RUBY_DATA_FUNC dmark, RUBY_DATA_FUNC dfree)
static void gc_sweep(rb_objspace_t *)
#define TRY_WITH_GC(alloc)
#define GC_PROF_SWEEP_TIMER_START
struct stack_chunk * next