diff options
author | tenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-04-17 03:17:25 +0000 |
---|---|---|
committer | tenderlove <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2019-04-17 03:17:25 +0000 |
commit | 3c55b643aec09bbe779dab25b2397947eded2b9b (patch) | |
tree | d7705428a035cd7c4384a0e34d59415bf3de9ca4 /transient_heap.c | |
parent | fcd679ed11e3e801431f2f931dbe925edb8df0bf (diff) |
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.c | 50 |
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) { |