Skip to content
Merged
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
11 changes: 8 additions & 3 deletions compar.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,15 @@ cmp_lt(VALUE x, VALUE y)

/*
* call-seq:
* obj <= other -> true or false
* self <= other -> true or false
*
* Returns whether +self+ is "less than or equal to" +other+;
* equivalent to <tt>(self <=> other) <= 0</tt>:
*
* 'foo' <= 'foo' # => true
* 'foo' <= 'food' # => true
* 'food' <= 'foo' # => false
*
* Compares two objects based on the receiver's <code><=></code>
* method, returning true if it returns a value less than or equal to 0.
*/

static VALUE
Expand Down
19 changes: 11 additions & 8 deletions gc/mmtk/mmtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -462,14 +462,21 @@ void rb_gc_impl_set_params(void *objspace_ptr) { }

static VALUE gc_verify_internal_consistency(VALUE self) { return Qnil; }

#define MMTK_HEAP_COUNT 5
#define MMTK_MAX_OBJ_SIZE 640

static size_t heap_sizes[MMTK_HEAP_COUNT + 1] = {
40, 80, 160, 320, MMTK_MAX_OBJ_SIZE, 0
};

void
rb_gc_impl_init(void)
{
VALUE gc_constants = rb_hash_new();
rb_hash_aset(gc_constants, ID2SYM(rb_intern("BASE_SLOT_SIZE")), SIZET2NUM(sizeof(VALUE) * 5));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("RBASIC_SIZE")), SIZET2NUM(sizeof(struct RBasic)));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("RVALUE_OVERHEAD")), INT2NUM(0));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("RVARGC_MAX_ALLOCATE_SIZE")), LONG2FIX(640));
rb_hash_aset(gc_constants, ID2SYM(rb_intern("RVARGC_MAX_ALLOCATE_SIZE")), LONG2FIX(MMTK_MAX_OBJ_SIZE));
// Pretend we have 5 size pools
rb_hash_aset(gc_constants, ID2SYM(rb_intern("SIZE_POOL_COUNT")), LONG2FIX(5));
OBJ_FREEZE(gc_constants);
Expand All @@ -485,10 +492,6 @@ rb_gc_impl_init(void)
rb_define_singleton_method(rb_mGC, "verify_compaction_references", rb_f_notimplement, -1);
}

static size_t heap_sizes[6] = {
40, 80, 160, 320, 640, 0
};

size_t *
rb_gc_impl_heap_sizes(void *objspace_ptr)
{
Expand Down Expand Up @@ -609,8 +612,8 @@ rb_gc_impl_new_obj(void *objspace_ptr, void *cache_ptr, VALUE klass, VALUE flags
struct objspace *objspace = objspace_ptr;
struct MMTk_ractor_cache *ractor_cache = cache_ptr;

if (alloc_size > 640) rb_bug("too big");
for (int i = 0; i < 5; i++) {
if (alloc_size > MMTK_MAX_OBJ_SIZE) rb_bug("too big");
for (int i = 0; i < MMTK_HEAP_COUNT; i++) {
if (alloc_size == heap_sizes[i]) break;
if (alloc_size < heap_sizes[i]) {
alloc_size = heap_sizes[i];
Expand Down Expand Up @@ -658,7 +661,7 @@ rb_gc_impl_heap_id_for_size(void *objspace_ptr, size_t size)
bool
rb_gc_impl_size_allocatable_p(size_t size)
{
return size <= 640;
return size <= MMTK_MAX_OBJ_SIZE;
}

// Malloc
Expand Down
5 changes: 2 additions & 3 deletions hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -4888,10 +4888,9 @@ hash_le(VALUE hash1, VALUE hash2)

/*
* call-seq:
* self <= other_hash -> true or false
* self <= other -> true or false
*
* Returns +true+ if the entries of +self+ are a subset of the entries of +other_hash+,
* +false+ otherwise:
* Returns whether the entries of +self+ are a subset of the entries of +other+:
*
* h0 = {foo: 0, bar: 1}
* h1 = {foo: 0, bar: 1, baz: 2}
Expand Down
9 changes: 5 additions & 4 deletions numeric.c
Original file line number Diff line number Diff line change
Expand Up @@ -1738,7 +1738,8 @@ flo_lt(VALUE x, VALUE y)
* call-seq:
* self <= other -> true or false
*
* Returns +true+ if +self+ is numerically less than or equal to +other+:
* Returns whether the value of +self+ is less than or equal to the value of +other+;
* +other+ must be numeric, but may not be Complex:
*
* 2.0 <= 3 # => true
* 2.0 <= 3.0 # => true
Expand Down Expand Up @@ -5081,10 +5082,10 @@ fix_le(VALUE x, VALUE y)

/*
* call-seq:
* self <= real -> true or false
* self <= other -> true or false
*
* Returns +true+ if the value of +self+ is less than or equal to
* that of +other+:
* Returns whether the value of +self+ is less than or equal to the value of +other+;
* +other+ must be numeric, but may not be Complex:
*
* 1 <= 0 # => false
* 1 <= 1 # => true
Expand Down
27 changes: 15 additions & 12 deletions string.c
Original file line number Diff line number Diff line change
Expand Up @@ -4294,23 +4294,26 @@ rb_str_eql(VALUE str1, VALUE str2)

/*
* call-seq:
* self <=> other_string -> -1, 0, 1, or nil
* self <=> other -> -1, 0, 1, or nil
*
* Compares +self+ and +other_string+, returning:
* Compares +self+ and +other+,
* evaluating their _contents_, not their _lengths_.
*
* - -1 if +other_string+ is larger.
* - 0 if the two are equal.
* - 1 if +other_string+ is smaller.
* - +nil+ if the two are incomparable.
* Returns:
*
* - +-1+, if +self+ is smaller.
* - +0+, if the two are equal.
* - +1+, if +self+ is larger.
* - +nil+, if the two are incomparable.
*
* Examples:
*
* 'foo' <=> 'foo' # => 0
* 'foo' <=> 'food' # => -1
* 'food' <=> 'foo' # => 1
* 'FOO' <=> 'foo' # => -1
* 'foo' <=> 'FOO' # => 1
* 'foo' <=> 1 # => nil
* 'a' <=> 'b' # => -1
* 'a' <=> 'ab' # => -1
* 'a' <=> 'a' # => 0
* 'b' <=> 'a' # => 1
* 'ab' <=> 'a' # => 1
* 'a' <=> :a # => nil
*
* Related: see {Comparing}[rdoc-ref:String@Comparing].
*/
Expand Down
49 changes: 26 additions & 23 deletions test/fiber/test_scheduler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -287,33 +287,36 @@ def test_post_fork_fiber_blocking
end

def test_io_write_on_flush
fn = File.join(Dir.tmpdir, "ruby_test_io_write_on_flush_#{SecureRandom.hex}")
write_fd = nil
io_ops = nil
thread = Thread.new do
scheduler = IOScheduler.new
Fiber.set_scheduler scheduler
omit "skip this test because it makes CI fragile"
begin
fn = File.join(Dir.tmpdir, "ruby_test_io_write_on_flush_#{SecureRandom.hex}")
write_fd = nil
io_ops = nil
thread = Thread.new do
scheduler = IOScheduler.new
Fiber.set_scheduler scheduler

Fiber.schedule do
File.open(fn, 'w+') do |f|
write_fd = f.fileno
f << 'foo'
f.flush
f << 'bar'
Fiber.schedule do
File.open(fn, 'w+') do |f|
write_fd = f.fileno
f << 'foo'
f.flush
f << 'bar'
end
end
io_ops = scheduler.__io_ops__
end
io_ops = scheduler.__io_ops__
end
thread.join
assert_equal [
[:io_write, write_fd, 'foo'],
[:io_write, write_fd, 'bar']
], io_ops
thread.join
assert_equal [
[:io_write, write_fd, 'foo'],
[:io_write, write_fd, 'bar']
], io_ops

assert_equal 'foobar', IO.read(fn)
ensure
thread.kill rescue nil
FileUtils.rm_f(fn)
assert_equal 'foobar', IO.read(fn)
ensure
thread.kill rescue nil
FileUtils.rm_f(fn)
end
end

def test_io_read_error
Expand Down
12 changes: 12 additions & 0 deletions vm_method.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,10 +149,21 @@ vm_cc_table_dup_i(ID key, VALUE old_ccs_ptr, void *data)
{
VALUE new_table = (VALUE)data;
struct rb_class_cc_entries *old_ccs = (struct rb_class_cc_entries *)old_ccs_ptr;

if (METHOD_ENTRY_INVALIDATED(old_ccs->cme)) {
// Invalidated CME. This entry will be removed from the old table on
// the next GC mark, so it's unsafe (and undesirable) to copy
return ID_TABLE_CONTINUE;
}

size_t memsize = vm_ccs_alloc_size(old_ccs->capa);
struct rb_class_cc_entries *new_ccs = ruby_xcalloc(1, memsize);
rb_managed_id_table_insert(new_table, key, (VALUE)new_ccs);

// We hold the VM lock, so invalidation should not have happened between
// our earlier invalidation check and now.
VM_ASSERT(!METHOD_ENTRY_INVALIDATED(old_ccs->cme));

memcpy(new_ccs, old_ccs, memsize);

#if VM_CHECK_MODE > 0
Expand All @@ -169,6 +180,7 @@ vm_cc_table_dup_i(ID key, VALUE old_ccs_ptr, void *data)
VALUE
rb_vm_cc_table_dup(VALUE old_table)
{
ASSERT_vm_locking();
VALUE new_table = rb_vm_cc_table_create(rb_managed_id_table_size(old_table));
rb_managed_id_table_foreach(old_table, vm_cc_table_dup_i, (void *)new_table);
return new_table;
Expand Down