summaryrefslogtreecommitdiff
path: root/gc.c
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2019-05-27 14:37:48 +0900
committerKoichi Sasada <ko1@atdot.net>2019-05-27 14:53:37 +0900
commit61da57c76a9e32a4154dac8f24f9b860d65b320d (patch)
tree386639d4f0a0bff2504b436b32620b2814a2cafb /gc.c
parentea6e284d86ccbc2d1ed5637acd0940a12b58b672 (diff)
is_pointer_to_heap() checks also tomb or not.
is_pointer_to_heap(obj) checks this obj belong to a heap page. However, this function returns TRUE even if the page is tomb page. This is re-commit of [712c027524]. heap_page_add_freeobj() should not use is_pointer_to_heap(), but should check more explicitly.
Diffstat (limited to 'gc.c')
-rw-r--r--gc.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/gc.c b/gc.c
index d60c052993..ba0d7e00db 100644
--- a/gc.c
+++ b/gc.c
@@ -1495,9 +1495,14 @@ heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj
page->freelist = p;
asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
- if (RGENGC_CHECK_MODE && !is_pointer_to_heap(objspace, p)) {
- rb_bug("heap_page_add_freeobj: %p is not rvalue.", (void *)p);
+ if (RGENGC_CHECK_MODE &&
+ /* obj should belong to page */
+ !(&page->start[0] <= (RVALUE *)obj &&
+ (RVALUE *)obj < &page->start[page->total_slots] &&
+ obj % sizeof(RVALUE) == 0)) {
+ rb_bug("heap_page_add_freeobj: %p is not rvalue.", (void *)p);
}
+
asan_poison_object(obj);
gc_report(3, objspace, "heap_page_add_freeobj: add %p to freelist\n", (void *)obj);
@@ -2213,7 +2218,13 @@ is_pointer_to_heap(rb_objspace_t *objspace, void *ptr)
if (page->start <= p) {
if (p < page->start + page->total_slots) {
RB_DEBUG_COUNTER_INC(gc_isptr_maybe);
- return TRUE;
+
+ if (page->flags.in_tomb) {
+ return FALSE;
+ }
+ else {
+ return TRUE;
+ }
}
lo = mid + 1;
}