* gc.c: use inline functions instead of macros, and close up
related codes for the profiler. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@36619 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
d7a3331682
commit
de0c788bb4
@ -1,3 +1,8 @@
|
|||||||
|
Sat Aug 4 22:56:20 2012 Narihiro Nakamura <authornari@gmail.com>
|
||||||
|
|
||||||
|
* gc.c: use inline functions instead of macros, and close up
|
||||||
|
related codes for the profiler.
|
||||||
|
|
||||||
Sat Aug 4 20:37:56 2012 Narihiro Nakamura <authornari@gmail.com>
|
Sat Aug 4 20:37:56 2012 Narihiro Nakamura <authornari@gmail.com>
|
||||||
|
|
||||||
* gc.c (gc_mark_children): use gc_mark_ptr instead of marking
|
* gc.c (gc_mark_children): use gc_mark_ptr instead of marking
|
||||||
|
445
gc.c
445
gc.c
@ -116,7 +116,6 @@ static ruby_gc_params_t initial_params = {
|
|||||||
|
|
||||||
int ruby_gc_debug_indent = 0;
|
int ruby_gc_debug_indent = 0;
|
||||||
|
|
||||||
/* for GC profile */
|
|
||||||
#ifndef GC_PROFILE_MORE_DETAIL
|
#ifndef GC_PROFILE_MORE_DETAIL
|
||||||
#define GC_PROFILE_MORE_DETAIL 0
|
#define GC_PROFILE_MORE_DETAIL 0
|
||||||
#endif
|
#endif
|
||||||
@ -141,143 +140,6 @@ typedef struct gc_profile_record {
|
|||||||
size_t allocate_limit;
|
size_t allocate_limit;
|
||||||
} gc_profile_record;
|
} gc_profile_record;
|
||||||
|
|
||||||
static double
|
|
||||||
getrusage_time(void)
|
|
||||||
{
|
|
||||||
#ifdef RUSAGE_SELF
|
|
||||||
struct rusage usage;
|
|
||||||
struct timeval time;
|
|
||||||
getrusage(RUSAGE_SELF, &usage);
|
|
||||||
time = usage.ru_utime;
|
|
||||||
return time.tv_sec + time.tv_usec * 1e-6;
|
|
||||||
#elif defined _WIN32
|
|
||||||
FILETIME creation_time, exit_time, kernel_time, user_time;
|
|
||||||
ULARGE_INTEGER ui;
|
|
||||||
LONG_LONG q;
|
|
||||||
double t;
|
|
||||||
|
|
||||||
if (GetProcessTimes(GetCurrentProcess(),
|
|
||||||
&creation_time, &exit_time, &kernel_time, &user_time) == 0)
|
|
||||||
{
|
|
||||||
return 0.0;
|
|
||||||
}
|
|
||||||
memcpy(&ui, &user_time, sizeof(FILETIME));
|
|
||||||
q = ui.QuadPart / 10L;
|
|
||||||
t = (DWORD)(q % 1000000L) * 1e-6;
|
|
||||||
q /= 1000000L;
|
|
||||||
#ifdef __GNUC__
|
|
||||||
t += q;
|
|
||||||
#else
|
|
||||||
t += (double)(DWORD)(q >> 16) * (1 << 16);
|
|
||||||
t += (DWORD)q & ~(~0 << 16);
|
|
||||||
#endif
|
|
||||||
return t;
|
|
||||||
#else
|
|
||||||
return 0.0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GC_PROF_TIMER_START do {\
|
|
||||||
if (objspace->profile.run) {\
|
|
||||||
if (!objspace->profile.record) {\
|
|
||||||
objspace->profile.size = 1000;\
|
|
||||||
objspace->profile.record = malloc(sizeof(gc_profile_record) * objspace->profile.size);\
|
|
||||||
}\
|
|
||||||
if (count >= objspace->profile.size) {\
|
|
||||||
objspace->profile.size += 1000;\
|
|
||||||
objspace->profile.record = realloc(objspace->profile.record, sizeof(gc_profile_record) * objspace->profile.size);\
|
|
||||||
}\
|
|
||||||
if (!objspace->profile.record) {\
|
|
||||||
rb_bug("gc_profile malloc or realloc miss");\
|
|
||||||
}\
|
|
||||||
MEMZERO(&objspace->profile.record[count], gc_profile_record, 1);\
|
|
||||||
gc_time = getrusage_time();\
|
|
||||||
objspace->profile.record[count].gc_invoke_time = gc_time - objspace->profile.invoke_time;\
|
|
||||||
}\
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define GC_PROF_TIMER_STOP(marked) do {\
|
|
||||||
if (objspace->profile.run) {\
|
|
||||||
gc_time = getrusage_time() - gc_time;\
|
|
||||||
if (gc_time < 0) gc_time = 0;\
|
|
||||||
objspace->profile.record[count].gc_time = gc_time;\
|
|
||||||
objspace->profile.record[count].is_marked = !!(marked);\
|
|
||||||
GC_PROF_SET_HEAP_INFO(objspace->profile.record[count]);\
|
|
||||||
objspace->profile.count++;\
|
|
||||||
}\
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#if GC_PROFILE_MORE_DETAIL
|
|
||||||
#define INIT_GC_PROF_PARAMS double gc_time = 0, sweep_time = 0;\
|
|
||||||
size_t count = objspace->profile.count, total = 0, live = 0
|
|
||||||
|
|
||||||
#define GC_PROF_MARK_TIMER_START double mark_time = 0;\
|
|
||||||
do {\
|
|
||||||
if (objspace->profile.run) {\
|
|
||||||
mark_time = getrusage_time();\
|
|
||||||
}\
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define GC_PROF_MARK_TIMER_STOP do {\
|
|
||||||
if (objspace->profile.run) {\
|
|
||||||
mark_time = getrusage_time() - mark_time;\
|
|
||||||
if (mark_time < 0) mark_time = 0;\
|
|
||||||
objspace->profile.record[objspace->profile.count].gc_mark_time = mark_time;\
|
|
||||||
}\
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define GC_PROF_SWEEP_TIMER_START do {\
|
|
||||||
if (objspace->profile.run) {\
|
|
||||||
sweep_time = getrusage_time();\
|
|
||||||
}\
|
|
||||||
} while(0)
|
|
||||||
|
|
||||||
#define GC_PROF_SWEEP_TIMER_STOP do {\
|
|
||||||
if (objspace->profile.run) {\
|
|
||||||
sweep_time = getrusage_time() - sweep_time;\
|
|
||||||
if (sweep_time < 0) sweep_time = 0;\
|
|
||||||
objspace->profile.record[count].gc_sweep_time = sweep_time;\
|
|
||||||
}\
|
|
||||||
} while(0)
|
|
||||||
#define GC_PROF_SET_MALLOC_INFO do {\
|
|
||||||
if (objspace->profile.run) {\
|
|
||||||
gc_profile_record *record = &objspace->profile.record[objspace->profile.count];\
|
|
||||||
record->allocate_increase = malloc_increase;\
|
|
||||||
record->allocate_limit = malloc_limit; \
|
|
||||||
}\
|
|
||||||
} while(0)
|
|
||||||
#define GC_PROF_SET_HEAP_INFO(record) do {\
|
|
||||||
live = objspace->heap.live_num;\
|
|
||||||
total = heaps_used * HEAP_OBJ_LIMIT;\
|
|
||||||
(record).heap_use_slots = heaps_used;\
|
|
||||||
(record).heap_live_objects = live;\
|
|
||||||
(record).heap_free_objects = total - live;\
|
|
||||||
(record).heap_total_objects = total;\
|
|
||||||
(record).have_finalize = deferred_final_list ? Qtrue : Qfalse;\
|
|
||||||
(record).heap_use_size = live * sizeof(RVALUE);\
|
|
||||||
(record).heap_total_size = total * sizeof(RVALUE);\
|
|
||||||
} while(0)
|
|
||||||
#define GC_PROF_INC_LIVE_NUM objspace->heap.live_num++
|
|
||||||
#define GC_PROF_DEC_LIVE_NUM objspace->heap.live_num--
|
|
||||||
#else
|
|
||||||
#define INIT_GC_PROF_PARAMS double gc_time = 0;\
|
|
||||||
size_t count = objspace->profile.count, total = 0, live = 0
|
|
||||||
#define GC_PROF_MARK_TIMER_START
|
|
||||||
#define GC_PROF_MARK_TIMER_STOP
|
|
||||||
#define GC_PROF_SWEEP_TIMER_START
|
|
||||||
#define GC_PROF_SWEEP_TIMER_STOP
|
|
||||||
#define GC_PROF_SET_MALLOC_INFO
|
|
||||||
#define GC_PROF_SET_HEAP_INFO(record) do {\
|
|
||||||
live = objspace->heap.live_num;\
|
|
||||||
total = heaps_used * HEAP_OBJ_LIMIT;\
|
|
||||||
(record).heap_total_objects = total;\
|
|
||||||
(record).heap_use_size = live * sizeof(RVALUE);\
|
|
||||||
(record).heap_total_size = total * sizeof(RVALUE);\
|
|
||||||
} while(0)
|
|
||||||
#define GC_PROF_INC_LIVE_NUM
|
|
||||||
#define GC_PROF_DEC_LIVE_NUM
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)
|
#if defined(_MSC_VER) || defined(__BORLANDC__) || defined(__CYGWIN__)
|
||||||
#pragma pack(push, 1) /* magic for reducing sizeof(RVALUE): 24 -> 20 */
|
#pragma pack(push, 1) /* magic for reducing sizeof(RVALUE): 24 -> 20 */
|
||||||
@ -577,6 +439,17 @@ static void run_final(rb_objspace_t *objspace, VALUE obj);
|
|||||||
static int garbage_collect(rb_objspace_t *objspace);
|
static int garbage_collect(rb_objspace_t *objspace);
|
||||||
static int gc_lazy_sweep(rb_objspace_t *objspace);
|
static int gc_lazy_sweep(rb_objspace_t *objspace);
|
||||||
|
|
||||||
|
static double getrusage_time(void);
|
||||||
|
static inline void gc_prof_timer_start(rb_objspace_t *);
|
||||||
|
static inline void gc_prof_timer_stop(rb_objspace_t *, int);
|
||||||
|
static inline void gc_prof_mark_timer_start(rb_objspace_t *);
|
||||||
|
static inline void gc_prof_mark_timer_stop(rb_objspace_t *);
|
||||||
|
static inline void gc_prof_sweep_timer_start(rb_objspace_t *);
|
||||||
|
static inline void gc_prof_sweep_timer_stop(rb_objspace_t *);
|
||||||
|
static inline void gc_prof_set_malloc_info(rb_objspace_t *);
|
||||||
|
static inline void gc_prof_inc_live_num(rb_objspace_t *);
|
||||||
|
static inline void gc_prof_dec_live_num(rb_objspace_t *);
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_global_variable(VALUE *var)
|
rb_global_variable(VALUE *var)
|
||||||
{
|
{
|
||||||
@ -709,23 +582,6 @@ gc_profile_disable(void)
|
|||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* call-seq:
|
|
||||||
* GC::Profiler.clear -> nil
|
|
||||||
*
|
|
||||||
* Clears the GC profiler data.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
static VALUE
|
|
||||||
gc_profile_clear(void)
|
|
||||||
{
|
|
||||||
rb_objspace_t *objspace = &rb_objspace;
|
|
||||||
MEMZERO(objspace->profile.record, gc_profile_record, objspace->profile.size);
|
|
||||||
objspace->profile.count = 0;
|
|
||||||
return Qnil;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
negative_size_allocation_error_with_gvl(void *ptr)
|
negative_size_allocation_error_with_gvl(void *ptr)
|
||||||
{
|
{
|
||||||
@ -1363,7 +1219,7 @@ rb_newobj(void)
|
|||||||
RANY(obj)->file = rb_sourcefile();
|
RANY(obj)->file = rb_sourcefile();
|
||||||
RANY(obj)->line = rb_sourceline();
|
RANY(obj)->line = rb_sourceline();
|
||||||
#endif
|
#endif
|
||||||
GC_PROF_INC_LIVE_NUM;
|
gc_prof_inc_live_num(objspace);
|
||||||
|
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
@ -2150,7 +2006,7 @@ finalize_list(rb_objspace_t *objspace, RVALUE *p)
|
|||||||
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
|
if (!FL_TEST(p, FL_SINGLETON)) { /* not freeing page */
|
||||||
add_slot_local_freelist(objspace, p);
|
add_slot_local_freelist(objspace, p);
|
||||||
if (!is_lazy_sweeping(objspace)) {
|
if (!is_lazy_sweeping(objspace)) {
|
||||||
GC_PROF_DEC_LIVE_NUM;
|
gc_prof_dec_live_num(objspace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2330,8 +2186,8 @@ static void
|
|||||||
after_gc_sweep(rb_objspace_t *objspace)
|
after_gc_sweep(rb_objspace_t *objspace)
|
||||||
{
|
{
|
||||||
size_t inc;
|
size_t inc;
|
||||||
GC_PROF_SET_MALLOC_INFO;
|
|
||||||
|
|
||||||
|
gc_prof_set_malloc_info(objspace);
|
||||||
if (objspace->heap.free_num < objspace->heap.free_min) {
|
if (objspace->heap.free_num < objspace->heap.free_min) {
|
||||||
set_heaps_increment(objspace);
|
set_heaps_increment(objspace);
|
||||||
heaps_increment(objspace);
|
heaps_increment(objspace);
|
||||||
@ -2381,7 +2237,6 @@ static int
|
|||||||
gc_lazy_sweep(rb_objspace_t *objspace)
|
gc_lazy_sweep(rb_objspace_t *objspace)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
INIT_GC_PROF_PARAMS;
|
|
||||||
|
|
||||||
if (objspace->flags.dont_lazy_sweep)
|
if (objspace->flags.dont_lazy_sweep)
|
||||||
return garbage_collect(objspace);
|
return garbage_collect(objspace);
|
||||||
@ -2390,15 +2245,15 @@ gc_lazy_sweep(rb_objspace_t *objspace)
|
|||||||
if (!ready_to_gc(objspace)) return TRUE;
|
if (!ready_to_gc(objspace)) return TRUE;
|
||||||
|
|
||||||
during_gc++;
|
during_gc++;
|
||||||
GC_PROF_TIMER_START;
|
gc_prof_timer_start(objspace);
|
||||||
GC_PROF_SWEEP_TIMER_START;
|
gc_prof_sweep_timer_start(objspace);
|
||||||
|
|
||||||
if (objspace->heap.sweep_slots) {
|
if (objspace->heap.sweep_slots) {
|
||||||
res = lazy_sweep(objspace);
|
res = lazy_sweep(objspace);
|
||||||
if (res) {
|
if (res) {
|
||||||
GC_PROF_SWEEP_TIMER_STOP;
|
gc_prof_sweep_timer_stop(objspace);
|
||||||
GC_PROF_SET_MALLOC_INFO;
|
gc_prof_set_malloc_info(objspace);
|
||||||
GC_PROF_TIMER_STOP(Qfalse);
|
gc_prof_timer_stop(objspace, Qfalse);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
after_gc_sweep(objspace);
|
after_gc_sweep(objspace);
|
||||||
@ -2417,7 +2272,7 @@ gc_lazy_sweep(rb_objspace_t *objspace)
|
|||||||
set_heaps_increment(objspace);
|
set_heaps_increment(objspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
GC_PROF_SWEEP_TIMER_START;
|
gc_prof_sweep_timer_start(objspace);
|
||||||
if (!(res = lazy_sweep(objspace))) {
|
if (!(res = lazy_sweep(objspace))) {
|
||||||
after_gc_sweep(objspace);
|
after_gc_sweep(objspace);
|
||||||
if (has_free_object) {
|
if (has_free_object) {
|
||||||
@ -2425,9 +2280,9 @@ gc_lazy_sweep(rb_objspace_t *objspace)
|
|||||||
during_gc = 0;
|
during_gc = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GC_PROF_SWEEP_TIMER_STOP;
|
gc_prof_sweep_timer_stop(objspace);
|
||||||
|
|
||||||
GC_PROF_TIMER_STOP(Qtrue);
|
gc_prof_timer_stop(objspace, Qtrue);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2459,7 +2314,7 @@ rb_gc_force_recycle(VALUE p)
|
|||||||
add_slot_local_freelist(objspace, (RVALUE *)p);
|
add_slot_local_freelist(objspace, (RVALUE *)p);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GC_PROF_DEC_LIVE_NUM;
|
gc_prof_dec_live_num(objspace);
|
||||||
slot = add_slot_local_freelist(objspace, (RVALUE *)p);
|
slot = add_slot_local_freelist(objspace, (RVALUE *)p);
|
||||||
if (slot->free_next == NULL) {
|
if (slot->free_next == NULL) {
|
||||||
link_free_heap_slot(objspace, slot);
|
link_free_heap_slot(objspace, slot);
|
||||||
@ -2664,7 +2519,7 @@ gc_marks(rb_objspace_t *objspace)
|
|||||||
{
|
{
|
||||||
struct gc_list *list;
|
struct gc_list *list;
|
||||||
rb_thread_t *th = GET_THREAD();
|
rb_thread_t *th = GET_THREAD();
|
||||||
GC_PROF_MARK_TIMER_START;
|
gc_prof_mark_timer_start(objspace);
|
||||||
|
|
||||||
objspace->heap.live_num = 0;
|
objspace->heap.live_num = 0;
|
||||||
objspace->count++;
|
objspace->count++;
|
||||||
@ -2707,14 +2562,12 @@ gc_marks(rb_objspace_t *objspace)
|
|||||||
gc_mark_rest(objspace);
|
gc_mark_rest(objspace);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
GC_PROF_MARK_TIMER_STOP;
|
gc_prof_mark_timer_stop(objspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
garbage_collect(rb_objspace_t *objspace)
|
garbage_collect(rb_objspace_t *objspace)
|
||||||
{
|
{
|
||||||
INIT_GC_PROF_PARAMS;
|
|
||||||
|
|
||||||
if (GC_NOTIFY) printf("start garbage_collect()\n");
|
if (GC_NOTIFY) printf("start garbage_collect()\n");
|
||||||
|
|
||||||
if (!heaps) {
|
if (!heaps) {
|
||||||
@ -2724,18 +2577,18 @@ garbage_collect(rb_objspace_t *objspace)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
GC_PROF_TIMER_START;
|
gc_prof_timer_start(objspace);
|
||||||
|
|
||||||
rest_sweep(objspace);
|
rest_sweep(objspace);
|
||||||
|
|
||||||
during_gc++;
|
during_gc++;
|
||||||
gc_marks(objspace);
|
gc_marks(objspace);
|
||||||
|
|
||||||
GC_PROF_SWEEP_TIMER_START;
|
gc_prof_sweep_timer_start(objspace);
|
||||||
gc_sweep(objspace);
|
gc_sweep(objspace);
|
||||||
GC_PROF_SWEEP_TIMER_STOP;
|
gc_prof_sweep_timer_stop(objspace);
|
||||||
|
|
||||||
GC_PROF_TIMER_STOP(Qtrue);
|
gc_prof_timer_stop(objspace, Qtrue);
|
||||||
if (GC_NOTIFY) printf("end garbage_collect()\n");
|
if (GC_NOTIFY) printf("end garbage_collect()\n");
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -3866,6 +3719,246 @@ gc_malloc_allocations(VALUE self)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
------------------------------ GC profiler ------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
static inline void gc_prof_set_heap_info(rb_objspace_t *, gc_profile_record *);
|
||||||
|
|
||||||
|
static double
|
||||||
|
getrusage_time(void)
|
||||||
|
{
|
||||||
|
#ifdef RUSAGE_SELF
|
||||||
|
struct rusage usage;
|
||||||
|
struct timeval time;
|
||||||
|
getrusage(RUSAGE_SELF, &usage);
|
||||||
|
time = usage.ru_utime;
|
||||||
|
return time.tv_sec + time.tv_usec * 1e-6;
|
||||||
|
#elif defined _WIN32
|
||||||
|
FILETIME creation_time, exit_time, kernel_time, user_time;
|
||||||
|
ULARGE_INTEGER ui;
|
||||||
|
LONG_LONG q;
|
||||||
|
double t;
|
||||||
|
|
||||||
|
if (GetProcessTimes(GetCurrentProcess(),
|
||||||
|
&creation_time, &exit_time, &kernel_time, &user_time) == 0)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
memcpy(&ui, &user_time, sizeof(FILETIME));
|
||||||
|
q = ui.QuadPart / 10L;
|
||||||
|
t = (DWORD)(q % 1000000L) * 1e-6;
|
||||||
|
q /= 1000000L;
|
||||||
|
#ifdef __GNUC__
|
||||||
|
t += q;
|
||||||
|
#else
|
||||||
|
t += (double)(DWORD)(q >> 16) * (1 << 16);
|
||||||
|
t += (DWORD)q & ~(~0 << 16);
|
||||||
|
#endif
|
||||||
|
return t;
|
||||||
|
#else
|
||||||
|
return 0.0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_timer_start(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
if (objspace->profile.run) {
|
||||||
|
size_t count = objspace->profile.count;
|
||||||
|
|
||||||
|
if (!objspace->profile.record) {
|
||||||
|
objspace->profile.size = 1000;
|
||||||
|
objspace->profile.record = malloc(sizeof(gc_profile_record) * objspace->profile.size);
|
||||||
|
}
|
||||||
|
if (count >= objspace->profile.size) {
|
||||||
|
objspace->profile.size += 1000;
|
||||||
|
objspace->profile.record = realloc(objspace->profile.record, sizeof(gc_profile_record) * objspace->profile.size);
|
||||||
|
}
|
||||||
|
if (!objspace->profile.record) {
|
||||||
|
rb_bug("gc_profile malloc or realloc miss");
|
||||||
|
}
|
||||||
|
MEMZERO(&objspace->profile.record[count], gc_profile_record, 1);
|
||||||
|
objspace->profile.record[count].gc_time = getrusage_time();
|
||||||
|
objspace->profile.record[objspace->profile.count].gc_invoke_time =
|
||||||
|
objspace->profile.record[count].gc_time - objspace->profile.invoke_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_timer_stop(rb_objspace_t *objspace, int marked)
|
||||||
|
{
|
||||||
|
if (objspace->profile.run) {
|
||||||
|
double gc_time = 0;
|
||||||
|
size_t count = objspace->profile.count;
|
||||||
|
gc_profile_record *record = &objspace->profile.record[count];
|
||||||
|
|
||||||
|
gc_time = getrusage_time() - record->gc_time;
|
||||||
|
if (gc_time < 0) gc_time = 0;
|
||||||
|
record->gc_time = gc_time;
|
||||||
|
record->is_marked = !!(marked);
|
||||||
|
gc_prof_set_heap_info(objspace, record);
|
||||||
|
objspace->profile.count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !GC_PROFILE_MORE_DETAIL
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_mark_timer_start(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_mark_timer_stop(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_sweep_timer_start(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_sweep_timer_stop(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_set_malloc_info(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_set_heap_info(rb_objspace_t *objspace, gc_profile_record *record)
|
||||||
|
{
|
||||||
|
size_t live = objspace->heap.live_num;
|
||||||
|
size_t total = heaps_used * HEAP_OBJ_LIMIT;
|
||||||
|
|
||||||
|
record->heap_total_objects = total;
|
||||||
|
record->heap_use_size = live * sizeof(RVALUE);
|
||||||
|
record->heap_total_size = total * sizeof(RVALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_inc_live_num(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_dec_live_num(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_mark_timer_start(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
if (objspace->profile.run) {
|
||||||
|
size_t count = objspace->profile.count;
|
||||||
|
|
||||||
|
objspace->profile.record[count].gc_mark_time = getrusage_time();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_mark_timer_stop(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
if (objspace->profile.run) {
|
||||||
|
double mark_time = 0;
|
||||||
|
size_t count = count;
|
||||||
|
gc_profile_record *record = &objspace->profile.record[count];
|
||||||
|
|
||||||
|
mark_time = getrusage_time() - record->gc_mark_time;
|
||||||
|
if (mark_time < 0) mark_time = 0;
|
||||||
|
record->gc_mark_time = mark_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_sweep_timer_start(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
if (objspace->profile.run) {
|
||||||
|
size_t count = objspace->profile.count;
|
||||||
|
|
||||||
|
objspace->profile.record[count].gc_sweep_time = getrusage_time();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_sweep_timer_stop(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
if (objspace->profile.run) {
|
||||||
|
double sweep_time = 0;
|
||||||
|
size_t count = objspace->profile.count;
|
||||||
|
gc_profile_record *record = &objspace->profile.record[count];
|
||||||
|
|
||||||
|
sweep_time = getrusage_time() - record->gc_sweep_time;\
|
||||||
|
if (sweep_time < 0) sweep_time = 0;\
|
||||||
|
record->gc_sweep_time = sweep_time;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_set_malloc_info(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
if (objspace->profile.run) {
|
||||||
|
gc_profile_record *record = &objspace->profile.record[objspace->profile.count];
|
||||||
|
if (record) {
|
||||||
|
record->allocate_increase = malloc_increase;
|
||||||
|
record->allocate_limit = malloc_limit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_set_heap_info(rb_objspace_t *objspace, gc_profile_record *record)
|
||||||
|
{
|
||||||
|
size_t live = objspace->heap.live_num;
|
||||||
|
size_t total = heaps_used * HEAP_OBJ_LIMIT;
|
||||||
|
|
||||||
|
record->heap_use_slots = heaps_used;
|
||||||
|
record->heap_live_objects = live;
|
||||||
|
record->heap_free_objects = total - live;
|
||||||
|
record->heap_total_objects = total;
|
||||||
|
record->have_finalize = deferred_final_list ? Qtrue : Qfalse;
|
||||||
|
record->heap_use_size = live * sizeof(RVALUE);
|
||||||
|
record->heap_total_size = total * sizeof(RVALUE);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_inc_live_num(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
objspace->heap.live_num++;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
gc_prof_dec_live_num(rb_objspace_t *objspace)
|
||||||
|
{
|
||||||
|
objspace->heap.live_num--;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* !GC_PROFILE_MORE_DETAIL */
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* GC::Profiler.clear -> nil
|
||||||
|
*
|
||||||
|
* Clears the GC profiler data.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
gc_profile_clear(void)
|
||||||
|
{
|
||||||
|
rb_objspace_t *objspace = &rb_objspace;
|
||||||
|
MEMZERO(objspace->profile.record, gc_profile_record, objspace->profile.size);
|
||||||
|
objspace->profile.count = 0;
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* GC::Profiler.raw_data -> [Hash, ...]
|
* GC::Profiler.raw_data -> [Hash, ...]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user