Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/master' into Ractor-Local-GC-v…
Browse files Browse the repository at this point in the history
…ersion-3
  • Loading branch information
rm155 committed Sep 19, 2024
2 parents 6dcf834 + d9981be commit 0a9f91d
Show file tree
Hide file tree
Showing 31 changed files with 126 additions and 55 deletions.
2 changes: 1 addition & 1 deletion bootstraptest/test_eval.rb
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ def initialize &b
}

%w[break next redo].each do |keyword|
assert_match %r"Can't escape from eval with #{keyword}\b", %{
assert_match %r"Invalid #{keyword}\b", %{
$stderr = STDOUT
begin
eval "0 rescue #{keyword}"
Expand Down
10 changes: 3 additions & 7 deletions class.c
Original file line number Diff line number Diff line change
Expand Up @@ -1398,7 +1398,6 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super
iclass = rb_include_class_new(module, super_class);
c = RCLASS_SET_SUPER(c, iclass);
RCLASS_SET_INCLUDER(iclass, klass);
add_subclass = TRUE;
if (module != RCLASS_ORIGIN(module)) {
if (!origin_stack) origin_stack = rb_ary_hidden_new(2);
VALUE origin[2] = {iclass, RCLASS_ORIGIN(module)};
Expand All @@ -1409,14 +1408,11 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super
RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass);
RICLASS_SET_ORIGIN_SHARED_MTBL(iclass);
rb_ary_resize(origin_stack, origin_len);
add_subclass = FALSE;
}

if (add_subclass) {
VALUE m = module;
if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m);
rb_module_add_to_subclasses_list(m, iclass);
}
VALUE m = module;
if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m);
rb_module_add_to_subclasses_list(m, iclass);

if (BUILTIN_TYPE(klass) == T_MODULE && FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
VALUE refined_class =
Expand Down
6 changes: 6 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -2751,6 +2751,12 @@ AS_CASE([$coroutine_type], [yes|''], [
[aarch64-freebsd*], [
coroutine_type=arm64
],
[powerpc64-freebsd*], [
coroutine_type=ppc64le
],
[powerpc64le-freebsd*], [
coroutine_type=ppc64le
],
[x86_64-netbsd*], [
coroutine_type=amd64
],
Expand Down
8 changes: 4 additions & 4 deletions gc.c
Original file line number Diff line number Diff line change
Expand Up @@ -586,7 +586,6 @@ typedef struct gc_function_map {
void (*ractor_cache_free)(void *objspace_ptr, void *cache);
void (*set_params)(void *objspace_ptr);
void (*init)(void);
void (*initial_stress_set)(VALUE flag);
size_t *(*size_pool_sizes)(void *objspace_ptr);
// Shutdown
void (*shutdown_free_objects)(void *objspace_ptr);
Expand Down Expand Up @@ -729,7 +728,6 @@ ruby_external_gc_init(void)
load_external_gc_func(ractor_cache_free);
load_external_gc_func(set_params);
load_external_gc_func(init);
load_external_gc_func(initial_stress_set);
load_external_gc_func(size_pool_sizes);
// Shutdown
load_external_gc_func(shutdown_free_objects);
Expand Down Expand Up @@ -820,7 +818,6 @@ ruby_external_gc_init(void)
# define rb_gc_impl_ractor_cache_free rb_gc_functions.ractor_cache_free
# define rb_gc_impl_set_params rb_gc_functions.set_params
# define rb_gc_impl_init rb_gc_functions.init
# define rb_gc_impl_initial_stress_set rb_gc_functions.initial_stress_set
# define rb_gc_impl_size_pool_sizes rb_gc_functions.size_pool_sizes
// Shutdown
# define rb_gc_impl_shutdown_free_objects rb_gc_functions.shutdown_free_objects
Expand Down Expand Up @@ -899,6 +896,8 @@ ruby_external_gc_init(void)
# define rb_gc_impl_copy_attributes rb_gc_functions.copy_attributes
#endif

static VALUE initial_stress = Qfalse;

void *
rb_objspace_alloc(rb_ractor_t *ractor)
{
Expand All @@ -913,6 +912,7 @@ rb_objspace_alloc(rb_ractor_t *ractor)

rb_gc_impl_objspace_init(objspace, ractor);
rb_objspace_gate_init(objspace);
rb_gc_impl_stress_set(objspace, initial_stress);

rb_objspace_gc_enable(ractor->local_objspace);
return objspace;
Expand Down Expand Up @@ -3718,7 +3718,7 @@ gc_stress_set_m(rb_execution_context_t *ec, VALUE self, VALUE flag)
void
rb_gc_initial_stress_set(VALUE flag)
{
rb_gc_impl_initial_stress_set(flag);
initial_stress = flag;
}

size_t *
Expand Down
8 changes: 6 additions & 2 deletions gc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -311,13 +311,17 @@ def self.config hash = nil
# call-seq:
# GC.latest_gc_info -> hash
# GC.latest_gc_info(hash) -> hash
# GC.latest_gc_info(:major_by) -> :malloc
# GC.latest_gc_info(key) -> value
#
# Returns information about the most recent garbage collection.
#
# If the optional argument, hash, is given,
# If the argument +hash+ is given and is a Hash object,
# it is overwritten and returned.
# This is intended to avoid probe effect.
#
# If the argument +key+ is given and is a Symbol object,
# it returns the value associated with the key.
# This is equivalent to <tt>GC.latest_gc_info[key]</tt>.
def self.latest_gc_info hash_or_key = nil
if hash_or_key == nil
hash_or_key = {}
Expand Down
11 changes: 0 additions & 11 deletions gc/default.c
Original file line number Diff line number Diff line change
Expand Up @@ -1654,14 +1654,6 @@ minimum_slots_for_size_pool(rb_objspace_t *objspace, rb_size_pool_t *size_pool)
return gc_params.size_pool_init_slots[size_pool_idx];
}

static VALUE initial_stress = Qfalse;

void
rb_gc_impl_initial_stress_set(VALUE flag)
{
initial_stress = flag;
}

static int
object_id_cmp(st_data_t x, st_data_t y)
{
Expand Down Expand Up @@ -10405,9 +10397,6 @@ objspace_setup(rb_objspace_t *objspace, rb_ractor_t *ractor)
ractor->local_objspace = objspace;
objspace->ractor = ractor;

objspace->flags.gc_stressful = RTEST(initial_stress);
objspace->gc_stress_mode = initial_stress;

objspace->flags.measure_gc = true;
malloc_limit = gc_params.malloc_limit_min;
objspace->finalize_deferred_pjob = rb_postponed_job_preregister(0, gc_finalize_deferred, NULL);
Expand Down
1 change: 0 additions & 1 deletion gc/gc_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ GC_IMPL_FN void *rb_gc_impl_ractor_cache_alloc(void *objspace_ptr);
GC_IMPL_FN void rb_gc_impl_ractor_cache_free(void *objspace_ptr, void *cache);
GC_IMPL_FN void rb_gc_impl_set_params(void *objspace_ptr);
GC_IMPL_FN void rb_gc_impl_init(void);
GC_IMPL_FN void rb_gc_impl_initial_stress_set(VALUE flag);
GC_IMPL_FN size_t *rb_gc_impl_size_pool_sizes(void *objspace_ptr);
// Shutdown
GC_IMPL_FN void rb_gc_impl_shutdown_free_objects(void *objspace_ptr);
Expand Down
20 changes: 10 additions & 10 deletions lib/set.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#
# set.rb - defines the Set class
#
# Copyright (c) 2002-2023 Akinori MUSHA <knu@iDaemons.org>
# Copyright (c) 2002-2024 Akinori MUSHA <knu@iDaemons.org>
#
# Documentation by Akinori MUSHA and Gavin Sinclair.
#
Expand Down Expand Up @@ -335,7 +335,7 @@ def replace(enum)
end
end

# Converts the set to an array. The order of elements is uncertain.
# Returns an array containing all elements in the set.
#
# Set[1, 2].to_a #=> [1, 2]
# Set[1, 'c', :s].to_a #=> [1, "c", :s]
Expand Down Expand Up @@ -540,22 +540,22 @@ def delete?(o)
# Deletes every element of the set for which block evaluates to
# true, and returns self. Returns an enumerator if no block is
# given.
def delete_if
def delete_if(&block)
block_given? or return enum_for(__method__) { size }
# @hash.delete_if should be faster, but using it breaks the order
# of enumeration in subclasses.
select { |o| yield o }.each { |o| @hash.delete(o) }
# Instead of directly using @hash.delete_if, perform enumeration
# using self.each that subclasses may override.
select(&block).each { |o| @hash.delete(o) }
self
end

# Deletes every element of the set for which block evaluates to
# false, and returns self. Returns an enumerator if no block is
# given.
def keep_if
def keep_if(&block)
block_given? or return enum_for(__method__) { size }
# @hash.keep_if should be faster, but using it breaks the order of
# enumeration in subclasses.
reject { |o| yield o }.each { |o| @hash.delete(o) }
# Instead of directly using @hash.keep_if, perform enumeration
# using self.each that subclasses may override.
reject(&block).each { |o| @hash.delete(o) }
self
end

Expand Down
2 changes: 1 addition & 1 deletion parse.y
Original file line number Diff line number Diff line change
Expand Up @@ -1836,7 +1836,7 @@ clear_block_exit(struct parser_params *p, bool error)
{
rb_node_exits_t *exits = p->exits;
if (!exits) return;
if (error && !compile_for_eval) {
if (error) {
for (NODE *e = RNODE(exits); (e = RNODE_EXITS(e)->nd_chain) != 0; ) {
switch (nd_type(e)) {
case NODE_BREAK:
Expand Down
6 changes: 3 additions & 3 deletions prism/prism.c
Original file line number Diff line number Diff line change
Expand Up @@ -18852,12 +18852,12 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
switch (keyword.type) {
case PM_TOKEN_KEYWORD_BREAK: {
pm_node_t *node = (pm_node_t *) pm_break_node_create(parser, &keyword, arguments.arguments);
if (!parser->parsing_eval) parse_block_exit(parser, node);
parse_block_exit(parser, node);
return node;
}
case PM_TOKEN_KEYWORD_NEXT: {
pm_node_t *node = (pm_node_t *) pm_next_node_create(parser, &keyword, arguments.arguments);
if (!parser->parsing_eval) parse_block_exit(parser, node);
parse_block_exit(parser, node);
return node;
}
case PM_TOKEN_KEYWORD_RETURN: {
Expand Down Expand Up @@ -19574,7 +19574,7 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, b
parser_lex(parser);

pm_node_t *node = (pm_node_t *) pm_redo_node_create(parser, &parser->previous);
if (!parser->parsing_eval) parse_block_exit(parser, node);
parse_block_exit(parser, node);

return node;
}
Expand Down
6 changes: 3 additions & 3 deletions prism_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -7275,7 +7275,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
throw_flag = 0;
}
else if (ISEQ_BODY(ip)->type == ISEQ_TYPE_EVAL) {
COMPILE_ERROR(iseq, location.line, "Can't escape from eval with break");
COMPILE_ERROR(iseq, location.line, "Invalid break");
return;
}
else {
Expand Down Expand Up @@ -9047,7 +9047,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
break;
}
else if (ISEQ_BODY(ip)->type == ISEQ_TYPE_EVAL) {
COMPILE_ERROR(iseq, location.line, "Can't escape from eval with next");
COMPILE_ERROR(iseq, location.line, "Invalid next");
return;
}

Expand Down Expand Up @@ -9300,7 +9300,7 @@ pm_compile_node(rb_iseq_t *iseq, const pm_node_t *node, LINK_ANCHOR *const ret,
break;
}
else if (ISEQ_BODY(ip)->type == ISEQ_TYPE_EVAL) {
COMPILE_ERROR(iseq, location.line, "Can't escape from eval with redo");
COMPILE_ERROR(iseq, location.line, "Invalid redo");
return;
}

Expand Down
10 changes: 8 additions & 2 deletions process.c
Original file line number Diff line number Diff line change
Expand Up @@ -4234,9 +4234,15 @@ rb_fork_ruby(int *status)
child.error = err = errno;

disable_child_handler_fork_parent(&old); /* yes, bad name */
rb_thread_release_fork_lock();
if (
#if defined(__FreeBSD__)
pid != 0 &&
#endif
true) {
rb_thread_release_fork_lock();
}
if (pid == 0) {
rb_thread_reset_fork_lock();
rb_thread_reset_fork_lock();
}
after_fork_ruby(pid);

Expand Down
6 changes: 3 additions & 3 deletions spec/ruby/core/thread/thread_variable_get_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,18 @@

it "raises a TypeError if the key is neither Symbol nor String when thread variables are already set" do
@t.thread_variable_set(:a, 49)
-> { @t.thread_variable_get(123) }.should raise_error(TypeError, "123 is not a symbol")
-> { @t.thread_variable_get(123) }.should raise_error(TypeError, /123 is not a symbol/)
end

ruby_version_is '3.4' do
it "raises a TypeError if the key is neither Symbol nor String when no thread variables are set" do
-> { @t.thread_variable_get(123) }.should raise_error(TypeError, "123 is not a symbol")
-> { @t.thread_variable_get(123) }.should raise_error(TypeError, /123 is not a symbol/)
end

it "raises a TypeError if the key is neither Symbol nor String without calling #to_sym" do
key = mock('key')
key.should_not_receive(:to_sym)
-> { @t.thread_variable_get(key) }.should raise_error(TypeError, "#{key.inspect} is not a symbol")
-> { @t.thread_variable_get(key) }.should raise_error(TypeError, /#{Regexp.escape(key.inspect)} is not a symbol/)
end
end
end
4 changes: 2 additions & 2 deletions spec/ruby/core/thread/thread_variable_set_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@
end

it "raises a TypeError if the key is neither Symbol nor String, nor responds to #to_str" do
-> { @t.thread_variable_set(123, 1) }.should raise_error(TypeError, '123 is not a symbol')
-> { @t.thread_variable_set(123, 1) }.should raise_error(TypeError, /123 is not a symbol/)
end

it "does not try to convert the key with #to_sym" do
key = mock('key')
key.should_not_receive(:to_sym)
-> { @t.thread_variable_set(key, 42) }.should raise_error(TypeError, "#{key.inspect} is not a symbol")
-> { @t.thread_variable_set(key, 42) }.should raise_error(TypeError, /#{Regexp.quote(key.inspect)} is not a symbol/)
end
end
6 changes: 3 additions & 3 deletions spec/ruby/core/thread/thread_variable_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,18 +43,18 @@

it "raises a TypeError if the key is neither Symbol nor String when thread variables are already set" do
@t.thread_variable_set(:a, 49)
-> { @t.thread_variable?(123) }.should raise_error(TypeError, "123 is not a symbol")
-> { @t.thread_variable?(123) }.should raise_error(TypeError, /123 is not a symbol/)
end

ruby_version_is '3.4' do
it "raises a TypeError if the key is neither Symbol nor String when no thread variables are set" do
-> { @t.thread_variable?(123) }.should raise_error(TypeError, "123 is not a symbol")
-> { @t.thread_variable?(123) }.should raise_error(TypeError, /123 is not a symbol/)
end

it "raises a TypeError if the key is neither Symbol nor String without calling #to_sym" do
key = mock('key')
key.should_not_receive(:to_sym)
-> { @t.thread_variable?(key) }.should raise_error(TypeError, "#{key.inspect} is not a symbol")
-> { @t.thread_variable?(key) }.should raise_error(TypeError, /#{Regexp.escape(key.inspect)} is not a symbol/)
end
end
end
2 changes: 1 addition & 1 deletion string.c
Original file line number Diff line number Diff line change
Expand Up @@ -12408,7 +12408,7 @@ string_for_symbol(VALUE name)
if (!RB_TYPE_P(name, T_STRING)) {
VALUE tmp = rb_check_string_type(name);
if (NIL_P(tmp)) {
rb_raise(rb_eTypeError, "%+"PRIsVALUE" is not a symbol",
rb_raise(rb_eTypeError, "%+"PRIsVALUE" is not a symbol nor a string",
name);
}
name = tmp;
Expand Down
6 changes: 6 additions & 0 deletions test/ruby/test_eval.rb
Original file line number Diff line number Diff line change
Expand Up @@ -535,6 +535,12 @@ def test_file_encoding
assert_equal(fname, eval("__FILE__", nil, fname, 1))
end

def test_eval_invalid_block_exit_bug_20597
assert_raise(SyntaxError){eval("break if false")}
assert_raise(SyntaxError){eval("next if false")}
assert_raise(SyntaxError){eval("redo if false")}
end

def test_eval_location_fstring
o = Object.new
o.instance_eval "def foo() end", "generated code"
Expand Down
29 changes: 29 additions & 0 deletions test/ruby/test_super.rb
Original file line number Diff line number Diff line change
Expand Up @@ -633,6 +633,35 @@ def test_public_zsuper_with_prepend
}
end

def test_super_with_included_prepended_module_method_caching_bug_20716
a = Module.new do
def test(*args)
super
end
end

b = Module.new do
def test(a)
a
end
end

c = Class.new

b.prepend(a)
c.include(b)

assert_equal(1, c.new.test(1))

b.class_eval do
def test
:test
end
end

assert_equal(:test, c.new.test)
end

class TestFor_super_with_modified_rest_parameter_base
def foo *args
args
Expand Down
Loading

0 comments on commit 0a9f91d

Please sign in to comment.