Skip to content

A few backports #195

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions bootstraptest/test_method.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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]'
2 changes: 0 additions & 2 deletions ext/socket/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
38 changes: 4 additions & 34 deletions ext/socket/raddrinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -461,15 +461,15 @@ 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 {
// It is said that pthread_create may fail spuriously, so we follow the JDK and retry several times.
//
// 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;
}
Expand All @@ -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;
}
Expand Down Expand Up @@ -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;
}
Expand Down
10 changes: 9 additions & 1 deletion hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 10 additions & 0 deletions test/ruby/test_hash.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
6 changes: 6 additions & 0 deletions tool/mk_builtin_loader.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down