зеркало из https://github.com/github/ruby.git
* gc.c (garbage_collect): all GC is start from garbage_collect()
(or garbage_collect_body()). `garbage_collect()' accept additional two parameters `full_mark' and `immediate_sweep'. If `full_mark' is TRUE, then force it full gc (major gc), otherwise, it depends on status of object space. Now, it will be minor gc. If `immediate_sweep' is TRUE, then disable lazy sweep. To allocate free memory, `full_mark' and `immediate_sweep' should be TRUE. Otherwise, they should be FALSE. * gc.c (gc_prepare_free_objects): use `garbage_collect_body()'. * gc.c (slot_sweep, before_gc_sweep, after_gc_sweep): add logging code. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@40884 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
Родитель
e12df5ef40
Коммит
9e64703ec8
15
ChangeLog
15
ChangeLog
|
@ -1,3 +1,18 @@
|
||||||
|
Wed May 22 07:36:08 2013 Koichi Sasada <ko1@atdot.net>
|
||||||
|
|
||||||
|
* gc.c (garbage_collect): all GC is start from garbage_collect()
|
||||||
|
(or garbage_collect_body()). `garbage_collect()' accept additional
|
||||||
|
two parameters `full_mark' and `immediate_sweep'.
|
||||||
|
If `full_mark' is TRUE, then force it full gc (major gc), otherwise,
|
||||||
|
it depends on status of object space. Now, it will be minor gc.
|
||||||
|
If `immediate_sweep' is TRUE, then disable lazy sweep.
|
||||||
|
To allocate free memory, `full_mark' and `immediate_sweep' should be
|
||||||
|
TRUE. Otherwise, they should be FALSE.
|
||||||
|
|
||||||
|
* gc.c (gc_prepare_free_objects): use `garbage_collect_body()'.
|
||||||
|
|
||||||
|
* gc.c (slot_sweep, before_gc_sweep, after_gc_sweep): add logging code.
|
||||||
|
|
||||||
Tue May 21 22:47:06 2013 NARUSE, Yui <naruse@ruby-lang.org>
|
Tue May 21 22:47:06 2013 NARUSE, Yui <naruse@ruby-lang.org>
|
||||||
|
|
||||||
* ext/strscan/strscan.c (strscan_aref): support named captures.
|
* ext/strscan/strscan.c (strscan_aref): support named captures.
|
||||||
|
|
149
gc.c
149
gc.c
|
@ -106,7 +106,7 @@ static ruby_gc_params_t initial_params = {
|
||||||
|
|
||||||
#if USE_RGENGC
|
#if USE_RGENGC
|
||||||
/* RGENGC_DEBUG:
|
/* RGENGC_DEBUG:
|
||||||
* 1:
|
* 1: basic information
|
||||||
* 2: remember set operation
|
* 2: remember set operation
|
||||||
* 3: mark
|
* 3: mark
|
||||||
* 4:
|
* 4:
|
||||||
|
@ -450,7 +450,8 @@ static void aligned_free(void *);
|
||||||
static void init_mark_stack(mark_stack_t *stack);
|
static void init_mark_stack(mark_stack_t *stack);
|
||||||
|
|
||||||
static VALUE lazy_sweep_enable(void);
|
static VALUE lazy_sweep_enable(void);
|
||||||
static int garbage_collect(rb_objspace_t *, int reason);
|
static int garbage_collect(rb_objspace_t *, int full_mark, int immediate_sweep, int reason);
|
||||||
|
static int garbage_collect_body(rb_objspace_t *, int full_mark, int immediate_sweep, int reason);
|
||||||
static int gc_prepare_free_objects(rb_objspace_t *);
|
static int gc_prepare_free_objects(rb_objspace_t *);
|
||||||
static void mark_tbl(rb_objspace_t *, st_table *);
|
static void mark_tbl(rb_objspace_t *, st_table *);
|
||||||
static void rest_sweep(rb_objspace_t *);
|
static void rest_sweep(rb_objspace_t *);
|
||||||
|
@ -813,8 +814,7 @@ newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UNLIKELY(ruby_gc_stress && !ruby_disable_gc_stress)) {
|
if (UNLIKELY(ruby_gc_stress && !ruby_disable_gc_stress)) {
|
||||||
/* if (!garbage_collect(objspace)) { */
|
if (!garbage_collect(objspace, FALSE, FALSE, GPR_FLAG_NEWOBJ)) {
|
||||||
if (!gc_prepare_free_objects(objspace)) {
|
|
||||||
during_gc = 0;
|
during_gc = 0;
|
||||||
rb_memerror();
|
rb_memerror();
|
||||||
}
|
}
|
||||||
|
@ -860,7 +860,6 @@ newobj_of(VALUE klass, VALUE flags, VALUE v1, VALUE v2, VALUE v3)
|
||||||
rgengc_report(5, objspace, "newobj: %p (%s)\n", (void *)obj, obj_type_name(obj));
|
rgengc_report(5, objspace, "newobj: %p (%s)\n", (void *)obj, obj_type_name(obj));
|
||||||
|
|
||||||
#if USE_RGENGC && RGENGC_CHECK_MODE
|
#if USE_RGENGC && RGENGC_CHECK_MODE
|
||||||
if (RBASIC(obj)->flags) rb_bug("newobj: flags of %p (%s) is not zero (%-8lx).\n", (void *)obj, obj_type_name(obj), RBASIC(obj)->flags);
|
|
||||||
if (RVALUE_PROMOTED(obj)) rb_bug("newobj: %p (%s) is promoted.\n", (void *)obj, obj_type_name(obj));
|
if (RVALUE_PROMOTED(obj)) rb_bug("newobj: %p (%s) is promoted.\n", (void *)obj, obj_type_name(obj));
|
||||||
if (rgengc_remembered(objspace, (VALUE)obj)) rb_bug("newobj: %p (%s) is remembered.\n", (void *)obj, obj_type_name(obj));
|
if (rgengc_remembered(objspace, (VALUE)obj)) rb_bug("newobj: %p (%s) is remembered.\n", (void *)obj, obj_type_name(obj));
|
||||||
#endif
|
#endif
|
||||||
|
@ -2018,8 +2017,6 @@ count_objects(int argc, VALUE *argv, VALUE os)
|
||||||
return hash;
|
return hash;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
------------------------ Garbage Collection ------------------------
|
------------------------ Garbage Collection ------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -2182,6 +2179,7 @@ slot_sweep_major(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
|
||||||
static void
|
static void
|
||||||
slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
|
slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
|
||||||
{
|
{
|
||||||
|
rgengc_report(1, objspace, "slot_sweep: start\n");
|
||||||
gc_prof_sweep_slot_timer_start(objspace);
|
gc_prof_sweep_slot_timer_start(objspace);
|
||||||
{
|
{
|
||||||
#if USE_RGENGC
|
#if USE_RGENGC
|
||||||
|
@ -2196,6 +2194,7 @@ slot_sweep(rb_objspace_t *objspace, struct heaps_slot *sweep_slot)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
gc_prof_sweep_slot_timer_stop(objspace);
|
gc_prof_sweep_slot_timer_stop(objspace);
|
||||||
|
rgengc_report(1, objspace, "slot_sweep: end\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -2216,6 +2215,8 @@ ready_to_gc(rb_objspace_t *objspace)
|
||||||
static void
|
static void
|
||||||
before_gc_sweep(rb_objspace_t *objspace)
|
before_gc_sweep(rb_objspace_t *objspace)
|
||||||
{
|
{
|
||||||
|
rgengc_report(1, objspace, "before_gc_sweep\n");
|
||||||
|
|
||||||
objspace->heap.do_heap_free = (size_t)((heaps_used * HEAP_OBJ_LIMIT) * 0.65);
|
objspace->heap.do_heap_free = (size_t)((heaps_used * HEAP_OBJ_LIMIT) * 0.65);
|
||||||
objspace->heap.free_min = (size_t)((heaps_used * HEAP_OBJ_LIMIT) * 0.2);
|
objspace->heap.free_min = (size_t)((heaps_used * HEAP_OBJ_LIMIT) * 0.2);
|
||||||
if (objspace->heap.free_min < initial_free_min) {
|
if (objspace->heap.free_min < initial_free_min) {
|
||||||
|
@ -2238,15 +2239,19 @@ after_gc_sweep(rb_objspace_t *objspace)
|
||||||
{
|
{
|
||||||
size_t inc;
|
size_t inc;
|
||||||
|
|
||||||
|
rgengc_report(1, objspace, "after_gc_sweep\n");
|
||||||
|
|
||||||
gc_prof_set_malloc_info(objspace);
|
gc_prof_set_malloc_info(objspace);
|
||||||
rgengc_report(5, objspace, "after_gc_sweep: objspace->heap.free_num: %d, objspace->heap.free_min: %d\n",
|
rgengc_report(5, objspace, "after_gc_sweep: objspace->heap.free_num: %d, objspace->heap.free_min: %d\n",
|
||||||
objspace->heap.free_num, objspace->heap.free_min);
|
objspace->heap.free_num, objspace->heap.free_min);
|
||||||
|
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
inc = ATOMIC_SIZE_EXCHANGE(malloc_increase, 0);
|
inc = ATOMIC_SIZE_EXCHANGE(malloc_increase, 0);
|
||||||
|
|
||||||
if (inc > malloc_limit) {
|
if (inc > malloc_limit) {
|
||||||
malloc_limit +=
|
malloc_limit +=
|
||||||
(size_t)((inc - malloc_limit) * (double)objspace_live_num(objspace) / (heaps_used * HEAP_OBJ_LIMIT));
|
(size_t)((inc - malloc_limit) * (double)objspace_live_num(objspace) / (heaps_used * HEAP_OBJ_LIMIT));
|
||||||
|
@ -2287,13 +2292,11 @@ rest_sweep(rb_objspace_t *objspace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void gc_marks(rb_objspace_t *objspace, int minor_gc);
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gc_sweep(rb_objspace_t *objspace)
|
gc_sweep(rb_objspace_t *objspace, int immediate_sweep)
|
||||||
{
|
{
|
||||||
|
if (immediate_sweep) {
|
||||||
struct heaps_slot *next;
|
struct heaps_slot *next;
|
||||||
|
|
||||||
before_gc_sweep(objspace);
|
before_gc_sweep(objspace);
|
||||||
|
|
||||||
while (objspace->heap.sweep_slots) {
|
while (objspace->heap.sweep_slots) {
|
||||||
|
@ -2303,21 +2306,32 @@ gc_sweep(rb_objspace_t *objspace)
|
||||||
}
|
}
|
||||||
|
|
||||||
after_gc_sweep(objspace);
|
after_gc_sweep(objspace);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
before_gc_sweep(objspace);
|
||||||
|
lazy_sweep(objspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!has_free_object) {
|
||||||
|
/* there is no freespace after slot_sweep() */
|
||||||
|
/* TODO: [RGENGC] Should do major GC before adding hepas */
|
||||||
|
set_heaps_increment(objspace);
|
||||||
|
if (!heaps_increment(objspace)) {
|
||||||
during_gc = 0;
|
during_gc = 0;
|
||||||
|
rb_memerror();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
gc_prepare_free_objects(rb_objspace_t *objspace)
|
gc_prepare_free_objects(rb_objspace_t *objspace)
|
||||||
{
|
{
|
||||||
int res;
|
|
||||||
|
|
||||||
if (!GC_ENABLE_LAZY_SWEEP || objspace->flags.dont_lazy_sweep) {
|
if (!GC_ENABLE_LAZY_SWEEP || objspace->flags.dont_lazy_sweep) {
|
||||||
if (heaps_increment(objspace)) {
|
if (heaps_increment(objspace)) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return garbage_collect(objspace, GPR_FLAG_NEWOBJ);
|
return garbage_collect(objspace, FALSE, TRUE, GPR_FLAG_NEWOBJ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2326,9 +2340,8 @@ gc_prepare_free_objects(rb_objspace_t *objspace)
|
||||||
during_gc++;
|
during_gc++;
|
||||||
|
|
||||||
if (objspace->heap.sweep_slots) {
|
if (objspace->heap.sweep_slots) {
|
||||||
res = lazy_sweep(objspace);
|
if (lazy_sweep(objspace)) {
|
||||||
if (res) {
|
return TRUE;
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2338,30 +2351,7 @@ gc_prepare_free_objects(rb_objspace_t *objspace)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gc_prof_timer_start(objspace, GPR_FLAG_NEWOBJ | GPR_FLAG_MINOR);
|
return garbage_collect_body(objspace, 0, 0, GPR_FLAG_NEWOBJ);
|
||||||
{
|
|
||||||
gc_marks(objspace, TRUE);
|
|
||||||
|
|
||||||
before_gc_sweep(objspace);
|
|
||||||
if (!(res = lazy_sweep(objspace))) {
|
|
||||||
/* there is no freespace after slot_sweep() */
|
|
||||||
while (1) {
|
|
||||||
/* There is no empty RVALUE spaces */
|
|
||||||
/* TODO: [RGENGC] Should do major GC before adding hepas */
|
|
||||||
|
|
||||||
set_heaps_increment(objspace);
|
|
||||||
heaps_increment(objspace);
|
|
||||||
|
|
||||||
if (has_free_object) {
|
|
||||||
res = TRUE;
|
|
||||||
during_gc = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
gc_prof_timer_stop(objspace);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Marking stack */
|
/* Marking stack */
|
||||||
|
@ -2967,6 +2957,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr)
|
||||||
marking:
|
marking:
|
||||||
|
|
||||||
#if USE_RGENGC
|
#if USE_RGENGC
|
||||||
|
if (LIKELY(objspace->mark_func_data == 0)) {
|
||||||
if (RGENGC_CHECK_MODE && RVALUE_SHADY(obj) && RVALUE_PROMOTED(obj)) {
|
if (RGENGC_CHECK_MODE && RVALUE_SHADY(obj) && RVALUE_PROMOTED(obj)) {
|
||||||
rb_bug("gc_mark_children: (1) %p (%s) is shady and promoted.\n", (void *)obj, obj_type_name((VALUE)obj));
|
rb_bug("gc_mark_children: (1) %p (%s) is shady and promoted.\n", (void *)obj, obj_type_name((VALUE)obj));
|
||||||
}
|
}
|
||||||
|
@ -2993,6 +2984,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE ptr)
|
||||||
if (RGENGC_CHECK_MODE && RVALUE_SHADY(obj) && RVALUE_PROMOTED(obj)) {
|
if (RGENGC_CHECK_MODE && RVALUE_SHADY(obj) && RVALUE_PROMOTED(obj)) {
|
||||||
rb_bug("gc_mark_children: (2) %p (%s) is shady and promoted.\n", (void *)obj, obj_type_name((VALUE)obj));
|
rb_bug("gc_mark_children: (2) %p (%s) is shady and promoted.\n", (void *)obj, obj_type_name((VALUE)obj));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif /* USE_RGENGC */
|
#endif /* USE_RGENGC */
|
||||||
|
|
||||||
if (FL_TEST(obj, FL_EXIVAR)) {
|
if (FL_TEST(obj, FL_EXIVAR)) {
|
||||||
|
@ -3689,24 +3681,34 @@ rb_gc_unregister_address(VALUE *addr)
|
||||||
#define GC_NOTIFY 0
|
#define GC_NOTIFY 0
|
||||||
|
|
||||||
static int
|
static int
|
||||||
garbage_collect(rb_objspace_t *objspace, int reason)
|
garbage_collect_body(rb_objspace_t *objspace, int full_mark, int immediate_sweep, int reason)
|
||||||
{
|
{
|
||||||
if (GC_NOTIFY) printf("start garbage_collect()\n");
|
int minor_gc;
|
||||||
|
|
||||||
if (!heaps) {
|
if (ruby_gc_stress && !ruby_disable_gc_stress) {
|
||||||
return FALSE;
|
minor_gc = TRUE;
|
||||||
|
immediate_sweep = TRUE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (full_mark) {
|
||||||
|
minor_gc = FALSE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* TODO: count old object size and so on */
|
||||||
|
minor_gc = TRUE;
|
||||||
}
|
}
|
||||||
if (!ready_to_gc(objspace)) {
|
|
||||||
return TRUE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rest_sweep(objspace);
|
if (GC_ENABLE_LAZY_SWEEP || objspace->flags.dont_lazy_sweep) {
|
||||||
|
immediate_sweep = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
gc_prof_timer_start(objspace, reason);
|
gc_prof_timer_start(objspace, reason | (minor_gc ? GPR_FLAG_MINOR : 0));
|
||||||
{
|
{
|
||||||
during_gc++;
|
assert(during_gc > 0);
|
||||||
gc_marks(objspace, FALSE);
|
gc_marks(objspace, minor_gc);
|
||||||
gc_sweep(objspace);
|
gc_sweep(objspace, immediate_sweep);
|
||||||
|
during_gc = 0;
|
||||||
}
|
}
|
||||||
gc_prof_timer_stop(objspace);
|
gc_prof_timer_stop(objspace);
|
||||||
|
|
||||||
|
@ -3714,30 +3716,55 @@ garbage_collect(rb_objspace_t *objspace, int reason)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
garbage_collect(rb_objspace_t *objspace, int full_mark, int immediate_sweep, int reason)
|
||||||
|
{
|
||||||
|
if (GC_NOTIFY) printf("start garbage_collect(%d, %d, %d)\n", full_mark, immediate_sweep, reason);
|
||||||
|
|
||||||
|
if (!heaps) {
|
||||||
|
during_gc = 0;
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!ready_to_gc(objspace)) {
|
||||||
|
during_gc = 0;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
rest_sweep(objspace);
|
||||||
|
|
||||||
|
during_gc++;
|
||||||
|
|
||||||
|
return garbage_collect_body(objspace, full_mark, immediate_sweep, reason);
|
||||||
|
}
|
||||||
|
|
||||||
struct objspace_and_reason {
|
struct objspace_and_reason {
|
||||||
rb_objspace_t *objspace;
|
rb_objspace_t *objspace;
|
||||||
int reason;
|
int reason;
|
||||||
|
int full_mark;
|
||||||
|
int immediate_sweep;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
gc_with_gvl(void *ptr)
|
gc_with_gvl(void *ptr)
|
||||||
{
|
{
|
||||||
struct objspace_and_reason *oar = (struct objspace_and_reason *)ptr;
|
struct objspace_and_reason *oar = (struct objspace_and_reason *)ptr;
|
||||||
return (void *)(VALUE)garbage_collect(oar->objspace, oar->reason);
|
return (void *)(VALUE)garbage_collect(oar->objspace, oar->full_mark, oar->immediate_sweep, oar->reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
garbage_collect_with_gvl(rb_objspace_t *objspace, int reason)
|
garbage_collect_with_gvl(rb_objspace_t *objspace, int full_mark, int immediate_sweep, int reason)
|
||||||
{
|
{
|
||||||
if (dont_gc) return TRUE;
|
if (dont_gc) return TRUE;
|
||||||
if (ruby_thread_has_gvl_p()) {
|
if (ruby_thread_has_gvl_p()) {
|
||||||
return garbage_collect(objspace, reason);
|
return garbage_collect(objspace, full_mark, immediate_sweep, reason);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (ruby_native_thread_p()) {
|
if (ruby_native_thread_p()) {
|
||||||
struct objspace_and_reason oar;
|
struct objspace_and_reason oar;
|
||||||
oar.objspace = objspace;
|
oar.objspace = objspace;
|
||||||
oar.reason = reason;
|
oar.reason = reason;
|
||||||
|
oar.full_mark = full_mark;
|
||||||
|
oar.immediate_sweep = immediate_sweep;
|
||||||
return (int)(VALUE)rb_thread_call_with_gvl(gc_with_gvl, (void *)&oar);
|
return (int)(VALUE)rb_thread_call_with_gvl(gc_with_gvl, (void *)&oar);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -3751,7 +3778,7 @@ garbage_collect_with_gvl(rb_objspace_t *objspace, int reason)
|
||||||
int
|
int
|
||||||
rb_garbage_collect(void)
|
rb_garbage_collect(void)
|
||||||
{
|
{
|
||||||
return garbage_collect(&rb_objspace, GPR_FLAG_CAPI);
|
return garbage_collect(&rb_objspace, TRUE, TRUE, GPR_FLAG_CAPI);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef Init_stack
|
#undef Init_stack
|
||||||
|
@ -3783,7 +3810,7 @@ void
|
||||||
rb_gc(void)
|
rb_gc(void)
|
||||||
{
|
{
|
||||||
rb_objspace_t *objspace = &rb_objspace;
|
rb_objspace_t *objspace = &rb_objspace;
|
||||||
garbage_collect(objspace, GPR_FLAG_METHOD);
|
garbage_collect(objspace, TRUE, TRUE, GPR_FLAG_METHOD);
|
||||||
if (!finalizing) finalize_deferred(objspace);
|
if (!finalizing) finalize_deferred(objspace);
|
||||||
free_unused_heaps(objspace);
|
free_unused_heaps(objspace);
|
||||||
}
|
}
|
||||||
|
@ -4213,7 +4240,7 @@ vm_malloc_prepare(rb_objspace_t *objspace, size_t size)
|
||||||
|
|
||||||
if ((ruby_gc_stress && !ruby_disable_gc_stress) ||
|
if ((ruby_gc_stress && !ruby_disable_gc_stress) ||
|
||||||
(malloc_increase+size) > malloc_limit) {
|
(malloc_increase+size) > malloc_limit) {
|
||||||
garbage_collect_with_gvl(objspace, GPR_FLAG_MALLOC);
|
garbage_collect_with_gvl(objspace, 0, 0, GPR_FLAG_MALLOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
|
@ -4236,7 +4263,7 @@ vm_malloc_fixup(rb_objspace_t *objspace, void *mem, size_t size)
|
||||||
|
|
||||||
#define TRY_WITH_GC(alloc) do { \
|
#define TRY_WITH_GC(alloc) do { \
|
||||||
if (!(alloc) && \
|
if (!(alloc) && \
|
||||||
(!garbage_collect_with_gvl(objspace, GPR_FLAG_MALLOC) || \
|
(!garbage_collect_with_gvl(objspace, 1, 1, GPR_FLAG_MALLOC) || /* full mark && immediate sweep */ \
|
||||||
!(alloc))) { \
|
!(alloc))) { \
|
||||||
ruby_memerror(); \
|
ruby_memerror(); \
|
||||||
} \
|
} \
|
||||||
|
@ -4276,7 +4303,7 @@ vm_xrealloc(rb_objspace_t *objspace, void *ptr, size_t size)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (ruby_gc_stress && !ruby_disable_gc_stress)
|
if (ruby_gc_stress && !ruby_disable_gc_stress)
|
||||||
garbage_collect_with_gvl(objspace, GPR_FLAG_MALLOC);
|
garbage_collect_with_gvl(objspace, 0, 0, GPR_FLAG_MALLOC);
|
||||||
|
|
||||||
#if CALC_EXACT_MALLOC_SIZE
|
#if CALC_EXACT_MALLOC_SIZE
|
||||||
size += sizeof(size_t);
|
size += sizeof(size_t);
|
||||||
|
@ -4286,7 +4313,7 @@ vm_xrealloc(rb_objspace_t *objspace, void *ptr, size_t size)
|
||||||
|
|
||||||
mem = realloc(ptr, size);
|
mem = realloc(ptr, size);
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
if (garbage_collect_with_gvl(objspace, GPR_FLAG_MALLOC)) {
|
if (garbage_collect_with_gvl(objspace, 1, 1, GPR_FLAG_MALLOC)) {
|
||||||
mem = realloc(ptr, size);
|
mem = realloc(ptr, size);
|
||||||
}
|
}
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
|
|
Загрузка…
Ссылка в новой задаче