Poison / verify the freelist
This commit just adds poisoning around the freelist to help debugging. Also verify that the freelist only contains T_NONE objects when checking the heap integrity git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67416 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
f28be7e02d
commit
4283fb42bc
34
gc.c
34
gc.c
@ -1425,9 +1425,12 @@ static inline void
|
|||||||
heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj)
|
heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj)
|
||||||
{
|
{
|
||||||
RVALUE *p = (RVALUE *)obj;
|
RVALUE *p = (RVALUE *)obj;
|
||||||
|
unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
|
||||||
|
|
||||||
p->as.free.flags = 0;
|
p->as.free.flags = 0;
|
||||||
p->as.free.next = page->freelist;
|
p->as.free.next = page->freelist;
|
||||||
page->freelist = p;
|
page->freelist = p;
|
||||||
|
__asan_poison_memory_region(&page->freelist, sizeof(RVALUE*));
|
||||||
|
|
||||||
if (RGENGC_CHECK_MODE && !is_pointer_to_heap(objspace, p)) {
|
if (RGENGC_CHECK_MODE && !is_pointer_to_heap(objspace, p)) {
|
||||||
rb_bug("heap_page_add_freeobj: %p is not rvalue.", (void *)p);
|
rb_bug("heap_page_add_freeobj: %p is not rvalue.", (void *)p);
|
||||||
@ -1440,23 +1443,30 @@ heap_page_add_freeobj(rb_objspace_t *objspace, struct heap_page *page, VALUE obj
|
|||||||
static inline void
|
static inline void
|
||||||
heap_add_freepage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
|
heap_add_freepage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
|
||||||
{
|
{
|
||||||
|
unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
|
||||||
if (page->freelist) {
|
if (page->freelist) {
|
||||||
page->free_next = heap->free_pages;
|
page->free_next = heap->free_pages;
|
||||||
heap->free_pages = page;
|
heap->free_pages = page;
|
||||||
}
|
}
|
||||||
|
poison_memory_region(&page->freelist, sizeof(RVALUE*));
|
||||||
}
|
}
|
||||||
|
|
||||||
#if GC_ENABLE_INCREMENTAL_MARK
|
#if GC_ENABLE_INCREMENTAL_MARK
|
||||||
static inline int
|
static inline int
|
||||||
heap_add_poolpage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
|
heap_add_poolpage(rb_objspace_t *objspace, rb_heap_t *heap, struct heap_page *page)
|
||||||
{
|
{
|
||||||
|
unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
|
||||||
if (page->freelist) {
|
if (page->freelist) {
|
||||||
page->free_next = heap->pooled_pages;
|
page->free_next = heap->pooled_pages;
|
||||||
heap->pooled_pages = page;
|
heap->pooled_pages = page;
|
||||||
objspace->rincgc.pooled_slots += page->free_slots;
|
objspace->rincgc.pooled_slots += page->free_slots;
|
||||||
|
poison_memory_region(&page->freelist, sizeof(RVALUE*));
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
poison_memory_region(&page->freelist, sizeof(RVALUE*));
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1585,6 +1595,7 @@ heap_page_allocate(rb_objspace_t *objspace)
|
|||||||
}
|
}
|
||||||
page->free_slots = limit;
|
page->free_slots = limit;
|
||||||
|
|
||||||
|
poison_memory_region(&page->freelist, sizeof(RVALUE*));
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1594,8 +1605,10 @@ heap_page_resurrect(rb_objspace_t *objspace)
|
|||||||
struct heap_page *page = 0, *next;
|
struct heap_page *page = 0, *next;
|
||||||
|
|
||||||
list_for_each_safe(&heap_tomb->pages, page, next, page_node) {
|
list_for_each_safe(&heap_tomb->pages, page, next, page_node) {
|
||||||
|
unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
|
||||||
if (page->freelist != NULL) {
|
if (page->freelist != NULL) {
|
||||||
heap_unlink_page(objspace, heap_tomb, page);
|
heap_unlink_page(objspace, heap_tomb, page);
|
||||||
|
poison_memory_region(&page->freelist, sizeof(RVALUE*));
|
||||||
return page;
|
return page;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1754,8 +1767,10 @@ heap_get_freeobj_from_next_freepage(rb_objspace_t *objspace, rb_heap_t *heap)
|
|||||||
heap->using_page = page;
|
heap->using_page = page;
|
||||||
|
|
||||||
GC_ASSERT(page->free_slots != 0);
|
GC_ASSERT(page->free_slots != 0);
|
||||||
|
unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
|
||||||
p = page->freelist;
|
p = page->freelist;
|
||||||
page->freelist = NULL;
|
page->freelist = NULL;
|
||||||
|
poison_memory_region(&page->freelist, sizeof(RVALUE*));
|
||||||
page->free_slots = 0;
|
page->free_slots = 0;
|
||||||
unpoison_object((VALUE)p, true);
|
unpoison_object((VALUE)p, true);
|
||||||
return p;
|
return p;
|
||||||
@ -3745,11 +3760,15 @@ gc_sweep_start_heap(rb_objspace_t *objspace, rb_heap_t *heap)
|
|||||||
objspace->rincgc.pooled_slots = 0;
|
objspace->rincgc.pooled_slots = 0;
|
||||||
#endif
|
#endif
|
||||||
if (heap->using_page) {
|
if (heap->using_page) {
|
||||||
RVALUE **p = &heap->using_page->freelist;
|
struct heap_page *page = heap->using_page;
|
||||||
|
unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
|
||||||
|
|
||||||
|
RVALUE **p = &page->freelist;
|
||||||
while (*p) {
|
while (*p) {
|
||||||
p = &(*p)->as.free.next;
|
p = &(*p)->as.free.next;
|
||||||
}
|
}
|
||||||
*p = heap->freelist;
|
*p = heap->freelist;
|
||||||
|
poison_memory_region(&page->freelist, sizeof(RVALUE*));
|
||||||
heap->using_page = NULL;
|
heap->using_page = NULL;
|
||||||
}
|
}
|
||||||
heap->freelist = NULL;
|
heap->freelist = NULL;
|
||||||
@ -5445,6 +5464,19 @@ gc_verify_heap_pages_(rb_objspace_t *objspace, struct list_head *head)
|
|||||||
struct heap_page *page = 0;
|
struct heap_page *page = 0;
|
||||||
|
|
||||||
list_for_each(head, page, page_node) {
|
list_for_each(head, page, page_node) {
|
||||||
|
unpoison_memory_region(&page->freelist, sizeof(RVALUE*), false);
|
||||||
|
RVALUE *p = page->freelist;
|
||||||
|
while(p) {
|
||||||
|
RVALUE *prev = p;
|
||||||
|
unpoison_object(p, false);
|
||||||
|
if (BUILTIN_TYPE(p) != T_NONE) {
|
||||||
|
fprintf(stderr, "freelist slot expected to be T_NONE but was: %s\n", obj_info((VALUE)p));
|
||||||
|
}
|
||||||
|
p = p->as.free.next;
|
||||||
|
poison_object(prev);
|
||||||
|
}
|
||||||
|
poison_memory_region(&page->freelist, sizeof(RVALUE*));
|
||||||
|
|
||||||
if (page->flags.has_remembered_objects == FALSE) {
|
if (page->flags.has_remembered_objects == FALSE) {
|
||||||
remembered_old_objects += gc_verify_heap_page(objspace, page, Qfalse);
|
remembered_old_objects += gc_verify_heap_page(objspace, page, Qfalse);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user