[前][次][番号順一覧][スレッド一覧]

ruby-changes:58889

From: John <ko1@a...>
Date: Sat, 23 Nov 2019 05:42:58 +0900 (JST)
Subject: [ruby-changes:58889] 8e743fad4e (master): Count pinned slots using only bitmap

https://git.ruby-lang.org/ruby.git/commit/?id=8e743fad4e

From 8e743fad4e9124bd59bb5f14473cb188db9d3c34 Mon Sep 17 00:00:00 2001
From: John Hawthorn <john@h...>
Date: Thu, 21 Nov 2019 11:05:48 -0800
Subject: Count pinned slots using only bitmap

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.

diff --git a/gc.c b/gc.c
index d2b4330..9cc230b 100644
--- a/gc.c
+++ b/gc.c
@@ -620,6 +620,7 @@ enum { https://github.com/ruby/ruby/blob/trunk/gc.c#L620
     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;
@@ -7698,32 +7699,11 @@ init_cursors(rb_objspace_t *objspace, struct heap_cursor *free, struct heap_curs https://github.com/ruby/ruby/blob/trunk/gc.c#L7699
 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;
-- 
cgit v0.10.2


--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]