mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Move GC.verify_compaction_references
[Bug #18779]
Define `GC.verify_compaction_references` as a built-in ruby method, according to GC compaction support via `GC::OPTS`.
This commit is contained in:
parent
dfc8060756
commit
b96a3a6fd2
Notes:
git
2022-06-02 18:24:31 +09:00
3 changed files with 29 additions and 48 deletions
46
gc.c
46
gc.c
|
@ -5135,11 +5135,13 @@ gc_unprotect_pages(rb_objspace_t *objspace, rb_heap_t *heap)
|
|||
static void gc_update_references(rb_objspace_t * objspace);
|
||||
static void invalidate_moved_page(rb_objspace_t *objspace, struct heap_page *page);
|
||||
|
||||
#ifndef GC_COMPACTION_SUPPORTED
|
||||
#if defined(__wasi__) /* WebAssembly doesn't support signals */
|
||||
# define GC_COMPACTION_SUPPORTED 0
|
||||
#else
|
||||
# define GC_COMPACTION_SUPPORTED 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if GC_COMPACTION_SUPPORTED
|
||||
static void
|
||||
|
@ -10533,45 +10535,10 @@ gc_compact(VALUE self)
|
|||
#endif
|
||||
|
||||
#if GC_COMPACTION_SUPPORTED
|
||||
/*
|
||||
* call-seq:
|
||||
* GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
|
||||
*
|
||||
* 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 self)
|
||||
gc_verify_compaction_references(rb_execution_context_t *ec, VALUE self, VALUE double_heap, VALUE toward_empty)
|
||||
{
|
||||
rb_objspace_t *objspace = &rb_objspace;
|
||||
VALUE kwargs, double_heap = Qfalse, toward_empty = Qfalse;
|
||||
static ID id_toward, id_double_heap, id_empty;
|
||||
|
||||
if (!id_toward) {
|
||||
id_toward = rb_intern("toward");
|
||||
id_double_heap = rb_intern("double_heap");
|
||||
id_empty = rb_intern("empty");
|
||||
}
|
||||
|
||||
rb_scan_args(argc, argv, ":", &kwargs);
|
||||
if (!NIL_P(kwargs)) {
|
||||
if (rb_hash_has_key(kwargs, ID2SYM(id_toward))) {
|
||||
VALUE toward = rb_hash_aref(kwargs, ID2SYM(id_toward));
|
||||
toward_empty = (toward == ID2SYM(id_empty)) ? Qtrue : Qfalse;
|
||||
}
|
||||
if (rb_hash_has_key(kwargs, ID2SYM(id_double_heap))) {
|
||||
double_heap = rb_hash_aref(kwargs, ID2SYM(id_double_heap));
|
||||
}
|
||||
}
|
||||
|
||||
/* Clear the heap. */
|
||||
gc_start_internal(NULL, self, Qtrue, Qtrue, Qtrue, Qfalse);
|
||||
|
@ -10602,7 +10569,7 @@ gc_verify_compaction_references(int argc, VALUE *argv, VALUE self)
|
|||
return gc_compact_stats(self);
|
||||
}
|
||||
#else
|
||||
# define gc_verify_compaction_references rb_f_notimplement
|
||||
# define gc_verify_compaction_references (VALUE (*)(rb_execution_context_t*, VALUE, VALUE, VALUE))rb_f_notimplement
|
||||
#endif
|
||||
|
||||
VALUE
|
||||
|
@ -14095,7 +14062,9 @@ Init_GC(void)
|
|||
rb_define_singleton_method(rb_mGC, "auto_compact", gc_get_auto_compact, 0);
|
||||
rb_define_singleton_method(rb_mGC, "auto_compact=", gc_set_auto_compact, 1);
|
||||
rb_define_singleton_method(rb_mGC, "latest_compact_info", gc_compact_stats, 0);
|
||||
rb_define_singleton_method(rb_mGC, "verify_compaction_references", gc_verify_compaction_references, -1);
|
||||
#if !GC_COMPACTION_SUPPORTED
|
||||
rb_define_singleton_method(rb_mGC, "verify_compaction_references", rb_f_notimplement, -1);
|
||||
#endif
|
||||
|
||||
#if GC_DEBUG_STRESS_TO_CLASS
|
||||
rb_define_singleton_method(rb_mGC, "add_stress_to_class", rb_gcdebug_add_stress_to_class, -1);
|
||||
|
@ -14119,6 +14088,7 @@ Init_GC(void)
|
|||
OPT(MALLOC_ALLOCATED_SIZE);
|
||||
OPT(MALLOC_ALLOCATED_SIZE_CHECK);
|
||||
OPT(GC_PROFILE_DETAIL_MEMORY);
|
||||
OPT(GC_COMPACTION_SUPPORTED);
|
||||
#undef OPT
|
||||
OBJ_FREEZE(opts);
|
||||
}
|
||||
|
|
20
gc.rb
20
gc.rb
|
@ -232,6 +232,26 @@ module GC
|
|||
Primitive.gc_latest_gc_info hash_or_key
|
||||
end
|
||||
|
||||
if respond_to?(:compact)
|
||||
# call-seq:
|
||||
# GC.verify_compaction_references(toward: nil, double_heap: false) -> hash
|
||||
#
|
||||
# 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)
|
||||
Primitive.gc_verify_compaction_references(double_heap, toward == :empty)
|
||||
end
|
||||
end
|
||||
|
||||
# call-seq:
|
||||
# GC.using_rvargc? -> true or false
|
||||
#
|
||||
|
|
|
@ -11,16 +11,7 @@ end
|
|||
class TestGCCompact < Test::Unit::TestCase
|
||||
module CompactionSupportInspector
|
||||
def supports_auto_compact?
|
||||
return false if /wasm/ =~ RUBY_PLATFORM
|
||||
return true unless defined?(Etc::SC_PAGE_SIZE)
|
||||
|
||||
begin
|
||||
return GC::INTERNAL_CONSTANTS[:HEAP_PAGE_SIZE] % Etc.sysconf(Etc::SC_PAGE_SIZE) == 0
|
||||
rescue NotImplementedError
|
||||
rescue ArgumentError
|
||||
end
|
||||
|
||||
true
|
||||
GC::OPTS.include?("GC_COMPACTION_SUPPORTED")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in a new issue