diff --git a/gc/mmtk/src/scanning.rs b/gc/mmtk/src/scanning.rs index be834bdd0bde95..355a2e7759584a 100644 --- a/gc/mmtk/src/scanning.rs +++ b/gc/mmtk/src/scanning.rs @@ -4,6 +4,7 @@ use crate::upcalls; use crate::utils::ChunkedVecCollector; use crate::Ruby; use crate::RubySlot; +use mmtk::memory_manager; use mmtk::scheduler::GCWork; use mmtk::scheduler::GCWorker; use mmtk::scheduler::WorkBucketStage; @@ -53,6 +54,19 @@ impl Scanning for VMScanning { mmtk::memory_manager::is_mmtk_object(target_object.to_raw_address()).is_some(), "Destination is not an MMTk object. Src: {object} dst: {target_object}" ); + + debug_assert!( + // If we are in a moving GC, all objects should be pinned by PinningRegistry. + // If it is requested that target_object be pinned but it is not pinned, then + // it is a bug because it could be moved. + if crate::mmtk().get_plan().current_gc_may_move_object() && pin { + memory_manager::is_pinned(target_object) + } else { + true + }, + "Object {object} is trying to pin {target_object}" + ); + let forwarded_target = object_tracer.trace_object(target_object); if forwarded_target != target_object { trace!(" Forwarded target {target_object} -> {forwarded_target}"); diff --git a/hash.c b/hash.c index c4e8512f64c458..b0de8e943355af 100644 --- a/hash.c +++ b/hash.c @@ -1497,6 +1497,10 @@ rb_hash_new_capa(long capa) static VALUE hash_copy(VALUE ret, VALUE hash) { + if (rb_hash_compare_by_id_p(hash)) { + rb_gc_register_pinning_obj(ret); + } + if (RHASH_AR_TABLE_P(hash)) { if (RHASH_AR_TABLE_P(ret)) { ar_copy(ret, hash); diff --git a/test/ruby/test_call.rb b/test/ruby/test_call.rb index 1b30ed34d8826f..dd1936c4e2689e 100644 --- a/test/ruby/test_call.rb +++ b/test/ruby/test_call.rb @@ -123,6 +123,25 @@ def self.f(*a); a end assert_equal([1, 2, {kw: 3}], f(*a, kw: 3)) end + def test_forward_argument_init + o = Object.new + def o.simple_forward_argument_init(a=eval('b'), b=1) + [a, b] + end + + def o.complex_forward_argument_init(a=eval('b'), b=eval('kw'), kw: eval('kw2'), kw2: 3) + [a, b, kw, kw2] + end + + def o.keyword_forward_argument_init(a: eval('b'), b: eval('kw'), kw: eval('kw2'), kw2: 3) + [a, b, kw, kw2] + end + + assert_equal [nil, 1], o.simple_forward_argument_init + assert_equal [nil, nil, 3, 3], o.complex_forward_argument_init + assert_equal [nil, nil, 3, 3], o.keyword_forward_argument_init + end + def test_call_bmethod_proc pr = proc{|sym| sym} define_singleton_method(:a, &pr) diff --git a/thread_sync.c b/thread_sync.c index 72341762399a8f..3227bab8435b1a 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -1043,12 +1043,8 @@ rb_queue_initialize(int argc, VALUE *argv, VALUE self) initial_capa *= 2; } ring_buffer_init(q, initial_capa); - - const VALUE *initial_ptr = RARRAY_CONST_PTR(initial); - - for (long index = 0; index < len; index++) { - ring_buffer_push(self, q, initial_ptr[index]); - } + MEMCPY(q->buffer, RARRAY_CONST_PTR(initial), VALUE, len); + q->len = len; } else { ring_buffer_init(q, QUEUE_INITIAL_CAPA); diff --git a/vm_args.c b/vm_args.c index 8d4042e35566ae..458710e59e3688 100644 --- a/vm_args.c +++ b/vm_args.c @@ -245,7 +245,6 @@ args_setup_opt_parameters(struct args_info *args, int opt_max, VALUE *locals) i = opt_max; } else { - int j; i = args->argc; args->argc = 0; @@ -257,11 +256,6 @@ args_setup_opt_parameters(struct args_info *args, int opt_max, VALUE *locals) locals[i] = argv[args->rest_index]; } } - - /* initialize by nil */ - for (j=i; j