* gc.c: pack boolean values into rb_objspace_t::flags with bit fields
to improve cache locality. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47461 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
dba3498944
commit
c5e13c3270
@ -1,3 +1,8 @@
|
|||||||
|
Tue Sep 9 11:39:41 2014 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* gc.c: pack boolean values into rb_objspace_t::flags with bit fields
|
||||||
|
to improve cache locality.
|
||||||
|
|
||||||
Tue Sep 9 11:11:05 2014 Koichi Sasada <ko1@atdot.net>
|
Tue Sep 9 11:11:05 2014 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
* test/ruby/test_object.rb: extend timeout.
|
* test/ruby/test_object.rb: extend timeout.
|
||||||
|
78
gc.c
78
gc.c
@ -464,10 +464,25 @@ typedef struct rb_objspace {
|
|||||||
#endif
|
#endif
|
||||||
} malloc_params;
|
} malloc_params;
|
||||||
|
|
||||||
enum gc_stat stat;
|
struct {
|
||||||
size_t marked_objects;
|
enum gc_stat stat : 2;
|
||||||
|
unsigned int immediate_sweep : 1;
|
||||||
|
unsigned int dont_gc : 1;
|
||||||
|
unsigned int dont_incremental : 1;
|
||||||
|
unsigned int during_gc : 1;
|
||||||
|
#if USE_RGENGC
|
||||||
|
unsigned int during_minor_gc : 1;
|
||||||
|
#endif
|
||||||
|
#if GC_ENABLE_INCREMENTAL_MARK
|
||||||
|
unsigned int during_incremental_marking : 1;
|
||||||
|
#endif
|
||||||
|
} flags;
|
||||||
|
|
||||||
int immediate_sweep;
|
struct {
|
||||||
|
rb_atomic_t finalizing;
|
||||||
|
} atomic_flags;
|
||||||
|
|
||||||
|
size_t marked_objects;
|
||||||
|
|
||||||
rb_heap_t eden_heap;
|
rb_heap_t eden_heap;
|
||||||
rb_heap_t tomb_heap; /* heap for zombies and ghosts */
|
rb_heap_t tomb_heap; /* heap for zombies and ghosts */
|
||||||
@ -490,12 +505,6 @@ typedef struct rb_objspace {
|
|||||||
VALUE deferred_final;
|
VALUE deferred_final;
|
||||||
} heap_pages;
|
} heap_pages;
|
||||||
|
|
||||||
struct {
|
|
||||||
int dont_gc;
|
|
||||||
int dont_incremental;
|
|
||||||
int during_gc;
|
|
||||||
rb_atomic_t finalizing;
|
|
||||||
} flags;
|
|
||||||
st_table *finalizer_table;
|
st_table *finalizer_table;
|
||||||
mark_stack_t mark_stack;
|
mark_stack_t mark_stack;
|
||||||
struct {
|
struct {
|
||||||
@ -555,7 +564,6 @@ typedef struct rb_objspace {
|
|||||||
#if USE_RGENGC
|
#if USE_RGENGC
|
||||||
struct {
|
struct {
|
||||||
VALUE parent_object;
|
VALUE parent_object;
|
||||||
int during_minor_gc;
|
|
||||||
int need_major_gc;
|
int need_major_gc;
|
||||||
size_t last_major_gc;
|
size_t last_major_gc;
|
||||||
size_t remembered_shady_object_count;
|
size_t remembered_shady_object_count;
|
||||||
@ -575,12 +583,6 @@ typedef struct rb_objspace {
|
|||||||
#endif
|
#endif
|
||||||
} rgengc;
|
} rgengc;
|
||||||
#endif /* USE_RGENGC */
|
#endif /* USE_RGENGC */
|
||||||
|
|
||||||
#if USE_RINCGC
|
|
||||||
struct {
|
|
||||||
int during_incremental_marking;
|
|
||||||
} rincgc;
|
|
||||||
#endif
|
|
||||||
} rb_objspace_t;
|
} rb_objspace_t;
|
||||||
|
|
||||||
|
|
||||||
@ -680,16 +682,16 @@ VALUE *ruby_initial_gc_stress_ptr = &rb_objspace.gc_stress;
|
|||||||
#define heap_tomb (&objspace->tomb_heap)
|
#define heap_tomb (&objspace->tomb_heap)
|
||||||
#define dont_gc objspace->flags.dont_gc
|
#define dont_gc objspace->flags.dont_gc
|
||||||
#define during_gc objspace->flags.during_gc
|
#define during_gc objspace->flags.during_gc
|
||||||
#define finalizing objspace->flags.finalizing
|
#define finalizing objspace->atomic_flags.finalizing
|
||||||
#define finalizer_table objspace->finalizer_table
|
#define finalizer_table objspace->finalizer_table
|
||||||
#define global_list objspace->global_list
|
#define global_list objspace->global_list
|
||||||
#define ruby_gc_stress objspace->gc_stress
|
#define ruby_gc_stress objspace->gc_stress
|
||||||
|
|
||||||
#define is_marking(objspace) ((objspace)->stat == marking)
|
#define is_marking(objspace) ((objspace)->flags.stat == marking)
|
||||||
#define is_sweeping(objspace) ((objspace)->stat == sweeping)
|
#define is_sweeping(objspace) ((objspace)->flags.stat == sweeping)
|
||||||
#define is_full_marking(objspace) ((objspace)->rgengc.during_minor_gc == FALSE)
|
#define is_full_marking(objspace) ((objspace)->flags.during_minor_gc == FALSE)
|
||||||
#if GC_ENABLE_INCREMENTAL_MARK
|
#if GC_ENABLE_INCREMENTAL_MARK
|
||||||
#define is_incremental_marking(objspace) ((objspace)->rincgc.during_incremental_marking != FALSE)
|
#define is_incremental_marking(objspace) ((objspace)->flags.during_incremental_marking != FALSE)
|
||||||
#else
|
#else
|
||||||
#define is_incremental_marking(objspace) 0
|
#define is_incremental_marking(objspace) 0
|
||||||
#endif
|
#endif
|
||||||
@ -743,7 +745,7 @@ static int ready_to_gc(rb_objspace_t *objspace);
|
|||||||
|
|
||||||
static int garbage_collect(rb_objspace_t *, int full_mark, int immediate_mark, int immediate_sweep, int reason);
|
static int garbage_collect(rb_objspace_t *, int full_mark, int immediate_mark, int immediate_sweep, int reason);
|
||||||
|
|
||||||
static int gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark, const int immediate_sweep, int reason);
|
static int gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark, const unsigned int immediate_sweep, int reason);
|
||||||
static void gc_rest(rb_objspace_t *objspace);
|
static void gc_rest(rb_objspace_t *objspace);
|
||||||
static inline void gc_enter(rb_objspace_t *objspace, const char *event);
|
static inline void gc_enter(rb_objspace_t *objspace, const char *event);
|
||||||
static inline void gc_exit(rb_objspace_t *objspace, const char *event);
|
static inline void gc_exit(rb_objspace_t *objspace, const char *event);
|
||||||
@ -3185,7 +3187,7 @@ gc_sweep_start(rb_objspace_t *objspace)
|
|||||||
rb_heap_t *heap;
|
rb_heap_t *heap;
|
||||||
size_t total_limit_slot;
|
size_t total_limit_slot;
|
||||||
|
|
||||||
objspace->stat = sweeping;
|
objspace->flags.stat = sweeping;
|
||||||
|
|
||||||
/* sweep unlinked method entries */
|
/* sweep unlinked method entries */
|
||||||
if (GET_VM()->unlinked_method_entry_list) {
|
if (GET_VM()->unlinked_method_entry_list) {
|
||||||
@ -3240,7 +3242,7 @@ gc_sweep_finish(rb_objspace_t *objspace)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_END_SWEEP, 0);
|
gc_event_hook(objspace, RUBY_INTERNAL_EVENT_GC_END_SWEEP, 0);
|
||||||
objspace->stat = none;
|
objspace->flags.stat = none;
|
||||||
|
|
||||||
#if RGENGC_CHECK_MODE >= 2
|
#if RGENGC_CHECK_MODE >= 2
|
||||||
gc_verify_internal_consistency(Qnil);
|
gc_verify_internal_consistency(Qnil);
|
||||||
@ -3332,7 +3334,7 @@ gc_sweep_continue(rb_objspace_t *objspace, rb_heap_t *heap)
|
|||||||
static void
|
static void
|
||||||
gc_sweep(rb_objspace_t *objspace)
|
gc_sweep(rb_objspace_t *objspace)
|
||||||
{
|
{
|
||||||
const int immediate_sweep = objspace->immediate_sweep;
|
const unsigned int immediate_sweep = objspace->flags.immediate_sweep;
|
||||||
|
|
||||||
gc_report(1, objspace, "gc_sweep: immediate: %d\n", immediate_sweep);
|
gc_report(1, objspace, "gc_sweep: immediate: %d\n", immediate_sweep);
|
||||||
|
|
||||||
@ -4818,13 +4820,13 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark)
|
|||||||
{
|
{
|
||||||
/* start marking */
|
/* start marking */
|
||||||
gc_report(1, objspace, "gc_marks_start: (%s)\n", full_mark ? "full" : "minor");
|
gc_report(1, objspace, "gc_marks_start: (%s)\n", full_mark ? "full" : "minor");
|
||||||
objspace->stat = marking;
|
objspace->flags.stat = marking;
|
||||||
|
|
||||||
#if USE_RGENGC
|
#if USE_RGENGC
|
||||||
objspace->rgengc.old_object_count_at_gc_start = objspace->rgengc.old_object_count;
|
objspace->rgengc.old_object_count_at_gc_start = objspace->rgengc.old_object_count;
|
||||||
|
|
||||||
if (full_mark) {
|
if (full_mark) {
|
||||||
objspace->rgengc.during_minor_gc = FALSE;
|
objspace->flags.during_minor_gc = FALSE;
|
||||||
objspace->marked_objects = 0;
|
objspace->marked_objects = 0;
|
||||||
objspace->profile.major_gc_count++;
|
objspace->profile.major_gc_count++;
|
||||||
objspace->rgengc.remembered_shady_object_count = 0;
|
objspace->rgengc.remembered_shady_object_count = 0;
|
||||||
@ -4833,7 +4835,7 @@ gc_marks_start(rb_objspace_t *objspace, int full_mark)
|
|||||||
rgengc_mark_and_rememberset_clear(objspace, heap_eden);
|
rgengc_mark_and_rememberset_clear(objspace, heap_eden);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
objspace->rgengc.during_minor_gc = TRUE;
|
objspace->flags.during_minor_gc = TRUE;
|
||||||
objspace->marked_objects = objspace->rgengc.old_object_count; /* OLD objects are already marked */
|
objspace->marked_objects = objspace->rgengc.old_object_count; /* OLD objects are already marked */
|
||||||
objspace->profile.minor_gc_count++;
|
objspace->profile.minor_gc_count++;
|
||||||
rgengc_rememberset_mark(objspace, heap_eden);
|
rgengc_rememberset_mark(objspace, heap_eden);
|
||||||
@ -4928,7 +4930,7 @@ gc_marks_finish(rb_objspace_t *objspace)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
objspace->rincgc.during_incremental_marking = FALSE;
|
objspace->flags.during_incremental_marking = FALSE;
|
||||||
/* check children of all marked wb-unprotected objects */
|
/* check children of all marked wb-unprotected objects */
|
||||||
gc_marks_wb_unprotected_objects(objspace);
|
gc_marks_wb_unprotected_objects(objspace);
|
||||||
}
|
}
|
||||||
@ -5758,16 +5760,16 @@ garbage_collect(rb_objspace_t *objspace, int full_mark, int immediate_mark, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark, const int immediate_sweep, int reason)
|
gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark, const unsigned int immediate_sweep, int reason)
|
||||||
{
|
{
|
||||||
int do_full_mark = full_mark;
|
int do_full_mark = full_mark;
|
||||||
objspace->immediate_sweep = immediate_sweep;
|
objspace->flags.immediate_sweep = immediate_sweep;
|
||||||
|
|
||||||
if (!heap_pages_used) return FALSE; /* heap is not ready */
|
if (!heap_pages_used) return FALSE; /* heap is not ready */
|
||||||
if (!ready_to_gc(objspace)) return TRUE; /* GC is not allowed */
|
if (!ready_to_gc(objspace)) return TRUE; /* GC is not allowed */
|
||||||
|
|
||||||
if (RGENGC_CHECK_MODE) {
|
if (RGENGC_CHECK_MODE) {
|
||||||
assert(objspace->stat == none);
|
assert(objspace->flags.stat == none);
|
||||||
assert(!is_lazy_sweeping(heap_eden));
|
assert(!is_lazy_sweeping(heap_eden));
|
||||||
assert(!is_incremental_marking(objspace));
|
assert(!is_incremental_marking(objspace));
|
||||||
#if RGENGC_CHECK_MODE >= 2
|
#if RGENGC_CHECK_MODE >= 2
|
||||||
@ -5784,7 +5786,7 @@ gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark,
|
|||||||
do_full_mark = TRUE;
|
do_full_mark = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
objspace->immediate_sweep = !(flag & (1<<gc_stress_no_immediate_sweep));
|
objspace->flags.immediate_sweep = !(flag & (1<<gc_stress_no_immediate_sweep));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
#if USE_RGENGC
|
#if USE_RGENGC
|
||||||
@ -5804,22 +5806,22 @@ gc_start(rb_objspace_t *objspace, const int full_mark, const int immediate_mark,
|
|||||||
|
|
||||||
#if GC_ENABLE_INCREMENTAL_MARK
|
#if GC_ENABLE_INCREMENTAL_MARK
|
||||||
if (!GC_ENABLE_INCREMENTAL_MARK || objspace->flags.dont_incremental || immediate_mark) {
|
if (!GC_ENABLE_INCREMENTAL_MARK || objspace->flags.dont_incremental || immediate_mark) {
|
||||||
objspace->rincgc.during_incremental_marking = FALSE;
|
objspace->flags.during_incremental_marking = FALSE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
objspace->rincgc.during_incremental_marking = do_full_mark;
|
objspace->flags.during_incremental_marking = do_full_mark;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!GC_ENABLE_LAZY_SWEEP || objspace->flags.dont_incremental) {
|
if (!GC_ENABLE_LAZY_SWEEP || objspace->flags.dont_incremental) {
|
||||||
objspace->immediate_sweep = TRUE;
|
objspace->flags.immediate_sweep = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objspace->immediate_sweep) reason |= GPR_FLAG_IMMEDIATE_SWEEP;
|
if (objspace->flags.immediate_sweep) reason |= GPR_FLAG_IMMEDIATE_SWEEP;
|
||||||
|
|
||||||
gc_report(1, objspace, "gc_start(%d, %d, %d, reason: %d) => %d, %d, %d\n",
|
gc_report(1, objspace, "gc_start(%d, %d, %d, reason: %d) => %d, %d, %d\n",
|
||||||
full_mark, immediate_mark, immediate_sweep, reason,
|
full_mark, immediate_mark, immediate_sweep, reason,
|
||||||
do_full_mark, !is_incremental_marking(objspace), objspace->immediate_sweep);
|
do_full_mark, !is_incremental_marking(objspace), objspace->flags.immediate_sweep);
|
||||||
|
|
||||||
objspace->profile.count++;
|
objspace->profile.count++;
|
||||||
objspace->profile.latest_gc_info = reason;
|
objspace->profile.latest_gc_info = reason;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user