diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb index 04c9eb2d11425e..964bf39d98b801 100644 --- a/bootstraptest/test_method.rb +++ b/bootstraptest/test_method.rb @@ -1190,3 +1190,12 @@ def test2 o, args, block test2 o1, [], block $result.join } + +assert_equal 'ok', %q{ + def foo + binding + ["ok"].first + end + foo + foo +}, '[Bug #20178]' diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb index 544bed5298cfc6..4e8536fc606bc0 100644 --- a/ext/socket/extconf.rb +++ b/ext/socket/extconf.rb @@ -706,8 +706,6 @@ def %(s) s || self end have_func("pthread_create") have_func("pthread_detach") - have_func("pthread_attr_setaffinity_np") - have_func("sched_getcpu") $VPATH << '$(topdir)' << '$(top_srcdir)' create_makefile("socket") diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index 9747f940369967..560312741f6820 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -461,7 +461,7 @@ cancel_getaddrinfo(void *ptr) } static int -do_pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg) +do_pthread_create(pthread_t *th, void *(*start_routine) (void *), void *arg) { int limit = 3, ret; do { @@ -469,7 +469,7 @@ do_pthread_create(pthread_t *th, const pthread_attr_t *attr, void *(*start_routi // // https://bugs.openjdk.org/browse/JDK-8268605 // https://github.com/openjdk/jdk/commit/e35005d5ce383ddd108096a3079b17cb0bcf76f1 - ret = pthread_create(th, attr, start_routine, arg); + ret = pthread_create(th, 0, start_routine, arg); } while (ret == EAGAIN && limit-- > 0); return ret; } @@ -489,23 +489,8 @@ rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hint return EAI_MEMORY; } - pthread_attr_t attr; - if (pthread_attr_init(&attr) != 0) { - free_getaddrinfo_arg(arg); - return EAI_AGAIN; - } -#if defined(HAVE_PTHREAD_ATTR_SETAFFINITY_NP) && defined(HAVE_SCHED_GETCPU) - cpu_set_t tmp_cpu_set; - CPU_ZERO(&tmp_cpu_set); - int cpu = sched_getcpu(); - if (cpu < CPU_SETSIZE) { - CPU_SET(cpu, &tmp_cpu_set); - pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &tmp_cpu_set); - } -#endif - pthread_t th; - if (do_pthread_create(&th, &attr, do_getaddrinfo, arg) != 0) { + if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) { free_getaddrinfo_arg(arg); return EAI_AGAIN; } @@ -716,23 +701,8 @@ rb_getnameinfo(const struct sockaddr *sa, socklen_t salen, return EAI_MEMORY; } - pthread_attr_t attr; - if (pthread_attr_init(&attr) != 0) { - free_getnameinfo_arg(arg); - return EAI_AGAIN; - } -#if defined(HAVE_PTHREAD_ATTR_SETAFFINITY_NP) && defined(HAVE_SCHED_GETCPU) - cpu_set_t tmp_cpu_set; - CPU_ZERO(&tmp_cpu_set); - int cpu = sched_getcpu(); - if (cpu < CPU_SETSIZE) { - CPU_SET(cpu, &tmp_cpu_set); - pthread_attr_setaffinity_np(&attr, sizeof(cpu_set_t), &tmp_cpu_set); - } -#endif - pthread_t th; - if (do_pthread_create(&th, 0, do_getnameinfo, arg) != 0) { + if (do_pthread_create(&th, do_getnameinfo, arg) != 0) { free_getnameinfo_arg(arg); return EAI_AGAIN; } diff --git a/hash.c b/hash.c index 78e9d9a2d60c8b..b15d856ee19c36 100644 --- a/hash.c +++ b/hash.c @@ -1557,7 +1557,15 @@ hash_copy(VALUE ret, VALUE hash) static VALUE hash_dup_with_compare_by_id(VALUE hash) { - return hash_copy(copy_compare_by_id(rb_hash_new(), hash), hash); + VALUE dup = hash_alloc_flags(rb_cHash, 0, Qnil, RHASH_ST_TABLE_P(hash)); + if (RHASH_ST_TABLE_P(hash)) { + RHASH_SET_ST_FLAG(dup); + } + else { + RHASH_UNSET_ST_FLAG(dup); + } + + return hash_copy(dup, hash); } static VALUE diff --git a/test/ruby/test_hash.rb b/test/ruby/test_hash.rb index 70daea0ef19150..c72b256bab39aa 100644 --- a/test/ruby/test_hash.rb +++ b/test/ruby/test_hash.rb @@ -1458,6 +1458,16 @@ def test_compare_by_identity assert_predicate(h.dup, :compare_by_identity?, bug8703) end + def test_compare_by_identy_memory_leak + assert_no_memory_leak([], "", "#{<<~"begin;"}\n#{<<~'end;'}", "[Bug #20145]", rss: true) + begin; + h = { 1 => 2 }.compare_by_identity + 1_000_000.times do + h.select { false } + end + end; + end + def test_same_key bug9646 = '[ruby-dev:48047] [Bug #9646] Infinite loop at Hash#each' h = @cls[a=[], 1] diff --git a/tool/mk_builtin_loader.rb b/tool/mk_builtin_loader.rb index 5ab427ca9b2931..95600e6a3bdc55 100644 --- a/tool/mk_builtin_loader.rb +++ b/tool/mk_builtin_loader.rb @@ -263,11 +263,17 @@ def collect_iseq iseq_ary def generate_cexpr(ofile, lineno, line_file, body_lineno, text, locals, func_name) f = StringIO.new + + # Avoid generating fetches of lvars we don't need. This is imperfect as it + # will match text inside strings or other false positives. + local_candidates = text.scan(/[a-zA-Z_][a-zA-Z0-9_]*/) + f.puts '{' lineno += 1 # locals is nil outside methods locals&.reverse_each&.with_index{|param, i| next unless Symbol === param + next unless local_candidates.include?(param.to_s) f.puts "MAYBE_UNUSED(const VALUE) #{param} = rb_vm_lvar(ec, #{-3 - i});" lineno += 1 }