mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Moved GC.verify_compaction_references
to gc.rb
And fixed a segfault by coercion of `Qundef`, when any keyword argument without `toward:` option is given.
This commit is contained in:
parent
9b55a9649f
commit
af899503a6
3 changed files with 25 additions and 45 deletions
50
gc.c
50
gc.c
|
@ -8647,53 +8647,14 @@ gc_compact_after_gc(rb_objspace_t *objspace, int use_toward_empty, int use_doubl
|
|||
mjit_gc_exit_hook(); // unlock MJIT here, because `rb_gc()` calls `mjit_gc_start_hook()` again.
|
||||
}
|
||||
|
||||
/*
|
||||
* call-seq:
|
||||
* GC.verify_compaction_references -> nil
|
||||
*
|
||||
* Verify compaction reference consistency.
|
||||
*
|
||||
* This method is implementation specific. During compaction, objects that
|
||||
* were moved are replaced with T_MOVED objects. No object should have a
|
||||
* reference to a T_MOVED object after compaction.
|
||||
*
|
||||
* This function doubles the heap to ensure room to move all objects,
|
||||
* compacts the heap to make sure everything moves, updates all references,
|
||||
* then performs a full GC. If any object contains a reference to a T_MOVED
|
||||
* object, that object should be pushed on the mark stack, and will
|
||||
* make a SEGV.
|
||||
*/
|
||||
static VALUE
|
||||
gc_verify_compaction_references(int argc, VALUE *argv, VALUE mod)
|
||||
gc_verify_compaction_references(rb_execution_context_t *ec, VALUE mod, VALUE toward, VALUE double_heap)
|
||||
{
|
||||
rb_objspace_t *objspace = &rb_objspace;
|
||||
int use_toward_empty = FALSE;
|
||||
int use_double_pages = FALSE;
|
||||
|
||||
if (dont_gc) return Qnil;
|
||||
|
||||
VALUE opt = Qnil;
|
||||
static ID keyword_ids[2];
|
||||
VALUE kwvals[2];
|
||||
|
||||
kwvals[1] = Qtrue;
|
||||
|
||||
rb_scan_args(argc, argv, "0:", &opt);
|
||||
|
||||
if (!NIL_P(opt)) {
|
||||
if (!keyword_ids[0]) {
|
||||
keyword_ids[0] = rb_intern("toward");
|
||||
keyword_ids[1] = rb_intern("double_heap");
|
||||
}
|
||||
|
||||
rb_get_kwargs(opt, keyword_ids, 0, 2, kwvals);
|
||||
if (rb_intern("empty") == rb_sym2id(kwvals[0])) {
|
||||
use_toward_empty = TRUE;
|
||||
}
|
||||
if (kwvals[1] != Qundef && RTEST(kwvals[1])) {
|
||||
use_double_pages = TRUE;
|
||||
}
|
||||
}
|
||||
const ID id_empty = rb_intern("empty");
|
||||
const int use_toward_empty = NIL_P(toward) ? FALSE :
|
||||
(Check_Type(toward, T_SYMBOL), toward == ID2SYM(id_empty));
|
||||
const int use_double_pages = RTEST(double_heap);
|
||||
|
||||
gc_compact(objspace, use_toward_empty, use_double_pages, TRUE);
|
||||
return gc_compact_stats(objspace);
|
||||
|
@ -11926,7 +11887,6 @@ Init_GC(void)
|
|||
|
||||
/* internal methods */
|
||||
rb_define_singleton_method(rb_mGC, "verify_internal_consistency", gc_verify_internal_consistency_m, 0);
|
||||
rb_define_singleton_method(rb_mGC, "verify_compaction_references", gc_verify_compaction_references, -1);
|
||||
rb_define_singleton_method(rb_mGC, "verify_transient_heap_internal_consistency", gc_verify_transient_heap_internal_consistency, 0);
|
||||
#if MALLOC_ALLOCATED_SIZE
|
||||
rb_define_singleton_method(rb_mGC, "malloc_allocated_size", gc_malloc_allocated_size, 0);
|
||||
|
|
18
gc.rb
18
gc.rb
|
@ -166,6 +166,24 @@ module GC
|
|||
def self.compact
|
||||
__builtin_rb_gc_compact
|
||||
end
|
||||
|
||||
# call-seq:
|
||||
# GC.verify_compaction_references(toward: nil, double_heap: nil) -> nil
|
||||
#
|
||||
# Verify compaction reference consistency.
|
||||
#
|
||||
# This method is implementation specific. During compaction, objects that
|
||||
# were moved are replaced with T_MOVED objects. No object should have a
|
||||
# reference to a T_MOVED object after compaction.
|
||||
#
|
||||
# This function doubles the heap to ensure room to move all objects,
|
||||
# compacts the heap to make sure everything moves, updates all references,
|
||||
# then performs a full GC. If any object contains a reference to a T_MOVED
|
||||
# object, that object should be pushed on the mark stack, and will
|
||||
# make a SEGV.
|
||||
def self.verify_compaction_references(toward: nil, double_heap: false)
|
||||
__builtin_gc_verify_compaction_references(toward, double_heap)
|
||||
end
|
||||
end
|
||||
|
||||
module ObjectSpace
|
||||
|
|
|
@ -39,6 +39,8 @@ class TestGCCompact < Test::Unit::TestCase
|
|||
hash = list_of_objects.hash
|
||||
GC.verify_compaction_references(toward: :empty)
|
||||
assert_equal hash, list_of_objects.hash
|
||||
GC.verify_compaction_references(double_heap: false)
|
||||
assert_equal hash, list_of_objects.hash
|
||||
end
|
||||
|
||||
def walk_ast ast
|
||||
|
|
Loading…
Reference in a new issue