aboutsummaryrefslogtreecommitdiffstats
path: root/transient_heap.c
diff options
context:
space:
mode:
authortenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-17 03:17:25 +0000
committertenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2019-04-17 03:17:25 +0000
commit3c55b643aec09bbe779dab25b2397947eded2b9b (patch)
treed7705428a035cd7c4384a0e34d59415bf3de9ca4 /transient_heap.c
parentfcd679ed11e3e801431f2f931dbe925edb8df0bf (diff)
downloadruby-3c55b643aec09bbe779dab25b2397947eded2b9b.tar.gz
Adding `GC.compact` and compacting GC support.
This commit adds the new method `GC.compact` and compacting GC support. Please see this issue for caveats: https://bugs.ruby-lang.org/issues/15626 [Feature #15626] git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@67576 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'transient_heap.c')
-rw-r--r--transient_heap.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/transient_heap.c b/transient_heap.c
index 55a796325f..334bd4f320 100644
--- a/transient_heap.c
+++ b/transient_heap.c
@@ -796,6 +796,56 @@ blocks_clear_marked_index(struct transient_heap_block* block)
}
}
+static void
+transient_heap_block_update_refs(struct transient_heap* theap, struct transient_heap_block* block)
+{
+ int i=0, n=0;
+
+ while (i<block->info.index) {
+ void *ptr = &block->buff[i];
+ struct transient_alloc_header *header = ptr;
+
+ unpoison_memory_region(header, sizeof *header, false);
+
+ void *poisoned = __asan_region_is_poisoned(header->obj, SIZEOF_VALUE);
+ unpoison_object(header->obj, false);
+
+ header->obj = rb_gc_new_location(header->obj);
+
+ if (poisoned) {
+ poison_object(header->obj);
+ }
+
+ i += header->size;
+ poison_memory_region(header, sizeof *header);
+ n++;
+ }
+}
+
+static void
+transient_heap_blocks_update_refs(struct transient_heap* theap, struct transient_heap_block *block, const char *type_str)
+{
+ while (block) {
+ transient_heap_block_update_refs(theap, block);
+ block = block->info.next_block;
+ }
+}
+
+void
+rb_transient_heap_update_references(void)
+{
+ struct transient_heap* theap = transient_heap_get();
+ int i;
+
+ transient_heap_blocks_update_refs(theap, theap->using_blocks, "using_blocks");
+ transient_heap_blocks_update_refs(theap, theap->marked_blocks, "marked_blocks");
+
+ for (i=0; i<theap->promoted_objects_index; i++) {
+ VALUE obj = theap->promoted_objects[i];
+ theap->promoted_objects[i] = rb_gc_new_location(obj);
+ }
+}
+
void
rb_transient_heap_start_marking(int full_marking)
{