summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-02-22 02:00:40 +0000
committerko1 <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2015-02-22 02:00:40 +0000
commit513fefdd1f0feb68fe4bd9a233dd1cbfeb7390ba (patch)
treeed3117b603aee6d088707bc2e895ac2131ccf5ad /gc.c
parent6c801fc58f39085ea5e71fc9b07e4fa52427b5e5 (diff)
* gc.c (rb_objspace_call_finalizer): control GC execution during
force firnalizations at the end of interpreter process. [Bug #10768] 1) Prohibit incremental GC while running Ruby-level finalizers to avoid any danger. 2) Prohibit GC while invoking T_DATA/T_FILE data structure because these operations break object relations consistency. This patch can introduce another memory consuming issue because Ruby-level finalizers can run after (2), GC is disabled. However, basically object consistency was broken at (2) as I described above. So that running Ruby-level finalizers contains danger originally. Because of this point, I need to suggest to remove these 3 lines (invoking remaining finalizers). And add a rule to add that finalizers should not add new finalizers, or say there is no guarantee to invoke finalizers that added by another finalizer. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@49684 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c21
1 files changed, 9 insertions, 12 deletions
diff --git a/gc.c b/gc.c
index e35c1664ad..c84da503ea 100644
--- a/gc.c
+++ b/gc.c
@@ -1209,10 +1209,8 @@ static void heap_page_free(rb_objspace_t *objspace, struct heap_page *page);
void
rb_objspace_free(rb_objspace_t *objspace)
{
-#if 0
if (is_lazy_sweeping(heap_eden))
rb_bug("lazy sweeping underway when freeing object space");
-#endif
if (objspace->profile.records) {
free(objspace->profile.records);
@@ -2568,6 +2566,10 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
finalize_deferred(objspace);
assert(heap_pages_deferred_final == 0);
+ gc_rest(objspace);
+ /* prohibit incremental GC */
+ objspace->flags.dont_incremental = 1;
+
/* force to run finalizer */
while (finalizer_table->num_entries) {
struct force_finalize_list *list = 0;
@@ -2582,10 +2584,13 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
}
}
- /* finalizers are part of garbage collection */
+ /* prohibit GC because force T_DATA finalizers can break an object graph consistency */
+ dont_gc = 1;
+
+ /* running data/file finalizers are part of garbage collection */
gc_enter(objspace, "rb_objspace_call_finalizer");
- /* run data object's finalizers */
+ /* run data/file object's finalizers */
for (i = 0; i < heap_allocated_pages; i++) {
p = heap_pages_sorted[i]->start; pend = p + heap_pages_sorted[i]->total_slots;
while (p < pend) {
@@ -2625,14 +2630,6 @@ rb_objspace_call_finalizer(rb_objspace_t *objspace)
st_free_table(finalizer_table);
finalizer_table = 0;
ATOMIC_SET(finalizing, 0);
-
-#if 0
- /*
- * finish any lazy sweeps that may have been started
- * when finalizing the objects in the heap
- */
- gc_rest(objspace);
-#endif
}
static inline int