Switch is_pointer_to_heap
to use library bsearch
This commit switches from a custom implemented bsearch algorithm to use the one provided by the C standard library. Because `is_pointer_to_heap` will only return true if the pointer being searched for is a valid slot starting address within the heap page body, we've extracted the bsearch call site into a more general function so we can use it elsewhere. The new function `heap_page_for_ptr` returns the heap page for any heap page pointer, regardless of whether that is at the start of a slot or in the middle of one. We then use this function as the basis of `is_pointer_to_heap`.
This commit is contained in:
parent
615e9b2865
commit
ad007bc6ea
Notes:
git
2022-01-05 00:28:13 +09:00
59
gc.c
59
gc.c
@ -2797,13 +2797,49 @@ rb_objspace_data_type_name(VALUE obj)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ptr_in_page_body_p(const void *ptr, const void *memb)
|
||||||
|
{
|
||||||
|
struct heap_page *page = *(struct heap_page **)memb;
|
||||||
|
uintptr_t p_body = (uintptr_t)GET_PAGE_BODY(page->start);
|
||||||
|
|
||||||
|
if ((uintptr_t)ptr >= p_body) {
|
||||||
|
return (uintptr_t)ptr < (p_body + HEAP_PAGE_SIZE) ? 0 : 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PUREFUNC(static inline struct heap_page * heap_page_for_ptr(rb_objspace_t *objspace, uintptr_t ptr);)
|
||||||
|
static inline struct heap_page *
|
||||||
|
heap_page_for_ptr(rb_objspace_t *objspace, uintptr_t ptr)
|
||||||
|
{
|
||||||
|
struct heap_page **res;
|
||||||
|
|
||||||
|
if (ptr < (uintptr_t)heap_pages_lomem ||
|
||||||
|
ptr > (uintptr_t)heap_pages_himem) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = bsearch((void *)ptr, heap_pages_sorted,
|
||||||
|
(size_t)heap_allocated_pages, sizeof(struct heap_page *),
|
||||||
|
ptr_in_page_body_p);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
return *res;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PUREFUNC(static inline int is_pointer_to_heap(rb_objspace_t *objspace, void *ptr);)
|
PUREFUNC(static inline int is_pointer_to_heap(rb_objspace_t *objspace, void *ptr);)
|
||||||
static inline int
|
static inline int
|
||||||
is_pointer_to_heap(rb_objspace_t *objspace, void *ptr)
|
is_pointer_to_heap(rb_objspace_t *objspace, void *ptr)
|
||||||
{
|
{
|
||||||
register RVALUE *p = RANY(ptr);
|
register RVALUE *p = RANY(ptr);
|
||||||
register struct heap_page *page;
|
register struct heap_page *page;
|
||||||
register size_t hi, lo, mid;
|
|
||||||
|
|
||||||
RB_DEBUG_COUNTER_INC(gc_isptr_trial);
|
RB_DEBUG_COUNTER_INC(gc_isptr_trial);
|
||||||
|
|
||||||
@ -2813,31 +2849,22 @@ is_pointer_to_heap(rb_objspace_t *objspace, void *ptr)
|
|||||||
if ((VALUE)p % sizeof(RVALUE) != 0) return FALSE;
|
if ((VALUE)p % sizeof(RVALUE) != 0) return FALSE;
|
||||||
RB_DEBUG_COUNTER_INC(gc_isptr_align);
|
RB_DEBUG_COUNTER_INC(gc_isptr_align);
|
||||||
|
|
||||||
/* check if p looks like a pointer using bsearch*/
|
page = heap_page_for_ptr(objspace, (uintptr_t)ptr);
|
||||||
lo = 0;
|
if (page) {
|
||||||
hi = heap_allocated_pages;
|
GC_ASSERT(page == GET_HEAP_PAGE(ptr));
|
||||||
while (lo < hi) {
|
|
||||||
mid = (lo + hi) / 2;
|
|
||||||
page = heap_pages_sorted[mid];
|
|
||||||
if (page->start <= p) {
|
|
||||||
if ((uintptr_t)p < ((uintptr_t)page->start + (page->total_slots * page->slot_size))) {
|
|
||||||
RB_DEBUG_COUNTER_INC(gc_isptr_maybe);
|
|
||||||
|
|
||||||
|
RB_DEBUG_COUNTER_INC(gc_isptr_maybe);
|
||||||
if (page->flags.in_tomb) {
|
if (page->flags.in_tomb) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
if ((uintptr_t)p < ((uintptr_t)page->start)) return FALSE;
|
||||||
|
if ((uintptr_t)p >= ((uintptr_t)page->start + (page->total_slots * page->slot_size))) return FALSE;
|
||||||
if ((NUM_IN_PAGE(p) * sizeof(RVALUE)) % page->slot_size != 0) return FALSE;
|
if ((NUM_IN_PAGE(p) * sizeof(RVALUE)) % page->slot_size != 0) return FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lo = mid + 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
hi = mid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user