Skip to content

Commit

Permalink
Count pinned slots using only bitmap
Browse files Browse the repository at this point in the history
This is significantly faster than checking BUILTIN_TYPEs because we
access significantly less memory. We also use popcount to count entire
words at a time.

The only functional difference from the previous implementation is that
T_ZOMBIE objects will no longer be counted. However those are temporary
objects which should be small in number, and this method has always been
an estimate.
  • Loading branch information
jhawthorn authored and tenderlove committed Nov 22, 2019
1 parent 26fd8d9 commit 8e743fa
Showing 1 changed file with 4 additions and 24 deletions.
28 changes: 4 additions & 24 deletions gc.c
Expand Up @@ -620,6 +620,7 @@ enum {
BITS_SIZE = sizeof(bits_t),
BITS_BITLENGTH = ( BITS_SIZE * CHAR_BIT )
};
#define popcount_bits rb_popcount_intptr

struct heap_page_header {
struct heap_page *page;
Expand Down Expand Up @@ -7698,32 +7699,11 @@ init_cursors(rb_objspace_t *objspace, struct heap_cursor *free, struct heap_curs
static int
count_pinned(struct heap_page *page)
{
RVALUE *pstart = page->start;
RVALUE *pend = pstart + page->total_slots;
int pinned = 0;
int i;

VALUE v = (VALUE)pstart;
for (; v != (VALUE)pend; v += sizeof(RVALUE)) {
void *poisoned = asan_poisoned_object_p(v);
asan_unpoison_object(v, false);

switch (BUILTIN_TYPE(v)) {
case T_NONE:
break;
case T_ZOMBIE:
pinned++;
break;
default:
if (RVALUE_PINNED(v)) {
pinned++;
}
break;
}

if (poisoned) {
GC_ASSERT(BUILTIN_TYPE(v) == T_NONE);
asan_poison_object(v);
}
for (i = 0; i < HEAP_PAGE_BITMAP_LIMIT; i++) {
pinned += popcount_bits(page->pinned_bits[i]);
}

return pinned;
Expand Down

0 comments on commit 8e743fa

Please sign in to comment.