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

ruby-changes:55982

From: Aaron <ko1@a...>
Date: Tue, 4 Jun 2019 05:39:25 +0900 (JST)
Subject: [ruby-changes:55982] Aaron Patterson: 4eb1c2365c (trunk): Unpin objects that `proc` references

https://git.ruby-lang.org/ruby.git/commit/?id=4eb1c2365c

From 4eb1c2365cd2745b58eb835ea1e26cc33a1238b1 Mon Sep 17 00:00:00 2001
From: Aaron Patterson <tenderlove@r...>
Date: Thu, 30 May 2019 12:08:06 -0700
Subject: Unpin objects that `proc` references

This commit adds compaction support to method and proc objects.  It just
unpins references and implements the "compact" callback and updates
references.

diff --git a/proc.c b/proc.c
index 5ac26be..de60a8c 100644
--- a/proc.c
+++ b/proc.c
@@ -25,6 +25,9 @@ https://github.com/ruby/ruby/blob/trunk/proc.c#L25
 # define NO_CLOBBERED(v) (v)
 #endif
 
+#define UPDATE_TYPED_REFERENCE(_type, _ref) *(_type*)&_ref = (_type)rb_gc_location((VALUE)_ref)
+#define UPDATE_REFERENCE(_ref) UPDATE_TYPED_REFERENCE(VALUE, _ref)
+
 const rb_cref_t *rb_vm_cref_in_context(VALUE self, VALUE cbase);
 
 struct METHOD {
@@ -58,23 +61,51 @@ block_mark(const struct rb_block *block) https://github.com/ruby/ruby/blob/trunk/proc.c#L61
       case block_type_ifunc:
 	{
 	    const struct rb_captured_block *captured = &block->as.captured;
-	    RUBY_MARK_UNLESS_NULL(captured->self);
-	    RUBY_MARK_UNLESS_NULL((VALUE)captured->code.val);
+	    RUBY_MARK_NO_PIN_UNLESS_NULL(captured->self);
+	    RUBY_MARK_NO_PIN_UNLESS_NULL((VALUE)captured->code.val);
 	    if (captured->ep && captured->ep[VM_ENV_DATA_INDEX_ENV] != Qundef /* cfunc_proc_t */) {
 		RUBY_MARK_UNLESS_NULL(VM_ENV_ENVVAL(captured->ep));
 	    }
 	}
 	break;
       case block_type_symbol:
-	RUBY_MARK_UNLESS_NULL(block->as.symbol);
+	RUBY_MARK_NO_PIN_UNLESS_NULL(block->as.symbol);
+	break;
+      case block_type_proc:
+	RUBY_MARK_NO_PIN_UNLESS_NULL(block->as.proc);
+	break;
+    }
+}
+
+static void
+block_compact(struct rb_block *block)
+{
+    switch (block->type) {
+      case block_type_iseq:
+      case block_type_ifunc:
+	{
+	    struct rb_captured_block *captured = &block->as.captured;
+            captured->self = rb_gc_location(captured->self);
+            captured->code.val = rb_gc_location(captured->code.val);
+	}
+	break;
+      case block_type_symbol:
+        block->as.symbol = rb_gc_location(block->as.symbol);
 	break;
       case block_type_proc:
-	RUBY_MARK_UNLESS_NULL(block->as.proc);
+        block->as.proc = rb_gc_location(block->as.proc);
 	break;
     }
 }
 
 static void
+proc_compact(void *ptr)
+{
+    rb_proc_t *proc = ptr;
+    block_compact((struct rb_block *)&proc->block);
+}
+
+static void
 proc_mark(void *ptr)
 {
     rb_proc_t *proc = ptr;
@@ -102,6 +133,7 @@ static const rb_data_type_t proc_data_type = { https://github.com/ruby/ruby/blob/trunk/proc.c#L133
 	proc_mark,
 	RUBY_TYPED_DEFAULT_FREE,
 	proc_memsize,
+	proc_compact,
     },
     0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED
 };
@@ -260,10 +292,19 @@ binding_mark(void *ptr) https://github.com/ruby/ruby/blob/trunk/proc.c#L292
 
     RUBY_MARK_ENTER("binding");
     block_mark(&bind->block);
-    rb_gc_mark(bind->pathobj);
+    rb_gc_mark_no_pin(bind->pathobj);
     RUBY_MARK_LEAVE("binding");
 }
 
+static void
+binding_compact(void *ptr)
+{
+    rb_binding_t *bind = ptr;
+
+    block_compact((struct rb_block *)&bind->block);
+    UPDATE_REFERENCE(bind->pathobj);
+}
+
 static size_t
 binding_memsize(const void *ptr)
 {
@@ -276,6 +317,7 @@ const rb_data_type_t ruby_binding_data_type = { https://github.com/ruby/ruby/blob/trunk/proc.c#L317
 	binding_mark,
 	binding_free,
 	binding_memsize,
+	binding_compact,
     },
     0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
 };
@@ -1316,10 +1358,20 @@ static void https://github.com/ruby/ruby/blob/trunk/proc.c#L1358
 bm_mark(void *ptr)
 {
     struct METHOD *data = ptr;
-    rb_gc_mark(data->recv);
-    rb_gc_mark(data->klass);
-    rb_gc_mark(data->iclass);
-    rb_gc_mark((VALUE)data->me);
+    rb_gc_mark_no_pin(data->recv);
+    rb_gc_mark_no_pin(data->klass);
+    rb_gc_mark_no_pin(data->iclass);
+    rb_gc_mark_no_pin((VALUE)data->me);
+}
+
+static void
+bm_compact(void *ptr)
+{
+    struct METHOD *data = ptr;
+    UPDATE_REFERENCE(data->recv);
+    UPDATE_REFERENCE(data->klass);
+    UPDATE_REFERENCE(data->iclass);
+    UPDATE_TYPED_REFERENCE(rb_method_entry_t *, data->me);
 }
 
 static size_t
@@ -1334,6 +1386,7 @@ static const rb_data_type_t method_data_type = { https://github.com/ruby/ruby/blob/trunk/proc.c#L1386
 	bm_mark,
 	RUBY_TYPED_DEFAULT_FREE,
 	bm_memsize,
+	bm_compact,
     },
     0, 0, RUBY_TYPED_FREE_IMMEDIATELY
 };
-- 
cgit v0.10.2


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

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