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
2 changes: 1 addition & 1 deletion .github/actions/setup/directories/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ runs:
run: |
ruby tool/missing-baseruby.bat --verbose
bash tool/gen-sources.bash up
echo RUBY_DUMP_AST=true >> "$GITHUB_ENV"
echo RUBY_DUMP_AST=./dump_ast-required-unexpectedly >> "$GITHUB_ENV"

- if: steps.which.outputs.sudo
shell: bash
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tarball-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ jobs:
env:
ARCHNAME: ${{ inputs.archname }}
PREFIX: ${{ matrix.prefix || '/usr/local' }}
RUBY_DUMP_AST: ./dump_ast-required-unexpectedly
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tarball-non-development.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
runs-on: ubuntu-24.04
env:
ruby_prefix: /tmp/ruby-snapshot
RUBY_DUMP_AST: ./dump_ast-required-unexpectedly
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tarball-ubuntu.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ jobs:
runs-on: ${{ matrix.os }}
env:
ARCHNAME: ${{ inputs.archname }}
RUBY_DUMP_AST: ./dump_ast-required-unexpectedly
steps:
- uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/tarball-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ jobs:
OS_VER: windows-${{ matrix.os }}
VCPKG_DEFAULT_TRIPLET: x64-windows
FEED_URL: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
RUBY_DUMP_AST: ./dump_ast-required-unexpectedly
NoDefaultCurrentDirectoryInExePath: 1
steps:
- run: md build
Expand Down
2 changes: 1 addition & 1 deletion array.c
Original file line number Diff line number Diff line change
Expand Up @@ -1943,7 +1943,7 @@ rb_ary_aref1(VALUE ary, VALUE arg)
default:
if (step == 0) rb_raise(rb_eArgError, "slice step cannot be zero");
len = ary_subseq_len(ary, beg, len);
if (len == 0) return ary_new(klass, 0);
if (len <= 0) return ary_new(klass, 0);
if (step == 1) return ary_make_partial(ary, klass, beg, len);
return ary_make_partial_step(ary, klass, beg, len, step);
}
Expand Down
152 changes: 110 additions & 42 deletions file.c
Original file line number Diff line number Diff line change
Expand Up @@ -1866,14 +1866,22 @@ rb_file_directory_p(VALUE obj, VALUE fname)
}

/*
* :markup: markdown
*
* call-seq:
* File.pipe?(filepath) -> true or false
* File.pipe?(path) -> true or false
*
* Returns +true+ if +filepath+ points to a pipe, +false+ otherwise:
* Returns whether the entry at the given `path` is a pipe:
*
* File.mkfifo('tmp/fifo')
* File.pipe?('tmp/fifo') # => true
* File.pipe?('t.txt') # => false
* ```ruby
* File.pipe?('doc/syntax/') # => false # Directory.
* File.pipe?('doc/maintainers.md') # => false # Regular file.
* File.pipe?('nosuch') # => false # Non-existent.
* path = '/tmp/foo'
* File.mkfifo(path)
* File.pipe?(path) # => true
* File.delete(path) # Clean up.
* ```
*
*/

Expand Down Expand Up @@ -2082,14 +2090,25 @@ rb_file_exist_p(VALUE obj, VALUE fname)
}

/*
* :markup: markdown
*
* call-seq:
* File.readable?(file_name) -> true or false
* File.readable?(path) -> true or false
*
* Returns <code>true</code> if the named file is readable by the effective
* user and group id of this process. See eaccess(3).
* Returns whether the entry at the given `path`
* exists and is readable by the owner and group of the current process;
* see [Permissions](rdoc-ref:file/filesystem_modes.md@Permissions):
*
* ```ruby
* path = '/tmp/secret.txt'
* File.write(path, 'foo')
* File.readable?(path) # => true
* File.chmod(0o000, path)
* File.readable?(path) # => false
* File.delete(path) # Clean up.
* File.readable?('nosuch') # => false
* ```
*
* Note that some OS-level security features may cause this to return true
* even though the file is not readable by the effective user/group.
*/

static VALUE
Expand All @@ -2099,14 +2118,13 @@ rb_file_readable_p(VALUE obj, VALUE fname)
}

/*
* call-seq:
* File.readable_real?(file_name) -> true or false
* :markup: markdown
*
* Returns <code>true</code> if the named file is readable by the real
* user and group id of this process. See access(3).
* call-seq:
* File.readable_real?(path) -> true or false
*
* Note that some OS-level security features may cause this to return true
* even though the file is not readable by the real user/group.
* Like File.readable?, but checks against the real user and group ids
* instead of the effective ids.
*/

static VALUE
Expand Down Expand Up @@ -2381,14 +2399,27 @@ rb_file_size_p(VALUE obj, VALUE fname)
}

/*
* :markup: markdown
*
* call-seq:
* File.owned?(file_name) -> true or false
* File.owned?(object) -> true or false
*
* Returns <code>true</code> if the named file exists and the
* effective user id of the calling process is the owner of
* the file.
* Returns whether the given `object` represents a filesystem entry or IO object
* that exists and is owned by the user of the current process:
*
* ```ruby
* filepath = 'doc/t.tmp'
* File.write(filepath, 'foo')
* File.owned?(filepath) # => true
* File.delete(filepath) # Clean up.
* dirpath = 'doc/tmp'
* Dir.mkdir(dirpath)
* File.owned?(dirpath) # => true
* Dir.rmdir(dirpath) # Clean up.
* File.owned?($stdin) # => true
* File.owned?('/etc') # => false
* ```
*
* _file_name_ can be an IO object.
*/

static VALUE
Expand Down Expand Up @@ -3851,11 +3882,11 @@ rb_file_s_symlink(VALUE klass, VALUE from, VALUE to)
* by the [symbolic link](rdoc-ref:file/symbolic_links.md) at `link_path`:
*
* ```ruby
* filepath = 'README.md'
* linkpath = 'foo'
* filepath = 'doc/maintainers.md'
* linkpath = '/tmp/link'
* File.symlink(filepath, linkpath)
* File.readlink(linkpath) # => "README.md"
* File.unlink(linkpath) # Clean up.
* File.readlink(linkpath) # => "doc/maintainers.md"
* File.delete(linkpath) # Clean up.
* ```
*
* Raises Errno::EINVAL if the entry referenced by `link_path`
Expand Down Expand Up @@ -6817,11 +6848,22 @@ rb_stat_d(VALUE obj)
}

/*
* :markup: markdown
*
* call-seq:
* stat.pipe? -> true or false
* stat.pipe? -> true or false
*
* Returns whether the entry at the path in `self` is a pipe:
*
* ```ruby
* File.stat('doc/syntax/').pipe? # => false # Directory .
* File.stat('doc/maintainers.md').pipe? # => false # Regular file.
* path = '/tmp/foo'
* File.mkfifo(path)
* File.stat(path).pipe? # => true
* File.delete(path) # Clean up.
* ```
*
* Returns <code>true</code> if the operating system supports pipes and
* <i>stat</i> is a pipe; <code>false</code> otherwise.
*/

static VALUE
Expand Down Expand Up @@ -6930,14 +6972,31 @@ rb_stat_c(VALUE obj)
}

/*
* :markup: markdown
*
* call-seq:
* stat.owned? -> true or false
* owned? -> true or false
*
* Returns <code>true</code> if the effective user id of the process is
* the same as the owner of <i>stat</i>.
* Returns whether `self` represents a filesystem entry that,
* at the time `self` was created,
* existed and was owned by the user of the current process;
* see [Snapshot](rdoc-ref:File::Stat@Snapshot):
*
* File.stat("testfile").owned? #=> true
* File.stat("/etc/passwd").owned? #=> false
* ```ruby
* filepath = 'doc/t.tmp'
* File.write(filepath, 'foo')
* filestat = File.stat(filepath)
* filestat.owned? # => true
* File.delete(filepath)
* filestat.owned? # => true # Snapshot unchanged.
* dirpath = 'doc/tmp'
* Dir.mkdir(dirpath)
* dirstat = File.stat(dirpath)
* dirstat.owned? # => true
* Dir.rmdir(dirpath)
* dirstat.owned? # => true # Snapshot unchanged.
* File.stat('/etc').owned? # => false
* ```
*
*/

Expand Down Expand Up @@ -6981,13 +7040,23 @@ rb_stat_grpowned(VALUE obj)
}

/*
* :markup: markdown
*
* call-seq:
* stat.readable? -> true or false
* readable? -> true or false
*
* Returns <code>true</code> if <i>stat</i> is readable by the
* effective user id of this process.
* Returns whether the entry represented by `self`
* exists and is readable by the owner and group of the current process;
* see [Permissions](rdoc-ref:file/filesystem_modes.md@Permissions):
*
* File.stat("testfile").readable? #=> true
* ```ruby
* path = '/tmp/secret.txt'
* File.write(path, 'foo')
* File.stat(path).readable? # => true
* File.chmod(0o000, path)
* File.stat(path).readable? # => false
* File.delete(path) # Clean up.
* ```
*
*/

Expand All @@ -7014,14 +7083,13 @@ rb_stat_r(VALUE obj)
}

/*
* :markup: markdown
*
* call-seq:
* stat.readable_real? -> true or false
*
* Returns <code>true</code> if <i>stat</i> is readable by the real
* user id of this process.
*
* File.stat("testfile").readable_real? #=> true
*
* Like #readable?, but checks against the real user and group ids
* instead of the effective ids.
*/

static VALUE
Expand Down
24 changes: 20 additions & 4 deletions gc/mmtk/src/heap/ruby_heap_trigger.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub struct RubyHeapTriggerConfig {
pub struct RubyHeapTrigger {
/// Target number of heap pages
target_heap_pages: AtomicUsize,
pending_pages: AtomicUsize,
}

impl GCTriggerPolicy<Ruby> for RubyHeapTrigger {
Expand All @@ -40,10 +41,20 @@ impl GCTriggerPolicy<Ruby> for RubyHeapTrigger {
plan.collection_required(space_full, space)
}

fn on_pending_allocation(&self, pages: usize) {
self.pending_pages.fetch_add(pages, Ordering::SeqCst);
}

fn on_pause_end(&self, mmtk: &'static MMTK<Ruby>) {
if let Some(plan) = mmtk.get_plan().generational() {
if plan.is_current_gc_nursery() {
return;
let pending_pages = self.pending_pages.swap(0, Ordering::SeqCst);

// Nursery GCs don't resize the heap, unless a failed allocation is
// waiting on us to make room for it.
if pending_pages == 0 {
if let Some(plan) = mmtk.get_plan().generational() {
if plan.is_current_gc_nursery() {
return;
}
}
}

Expand All @@ -53,14 +64,17 @@ impl GCTriggerPolicy<Ruby> for RubyHeapTrigger {
(used_pages as f64 * (1.0 + Self::get_config().heap_pages_min_ratio)) as usize;
let target_max =
(used_pages as f64 * (1.0 + Self::get_config().heap_pages_max_ratio)) as usize;
// Grow the heap by the goal ratio over the live size, plus whatever
// is needed to fit allocations that failed and triggered this GC.
let new_target = (((used_pages as f64) * (1.0 + Self::get_config().heap_pages_goal_ratio))
as usize)
.saturating_add(pending_pages)
.clamp(
Self::get_config().min_heap_pages,
Self::get_config().max_heap_pages,
);

if used_pages < target_min || used_pages > target_max {
if pending_pages > 0 || used_pages < target_min || used_pages > target_max {
self.target_heap_pages.store(new_target, Ordering::Relaxed);
}
}
Expand Down Expand Up @@ -88,6 +102,7 @@ impl Default for RubyHeapTrigger {

Self {
target_heap_pages: AtomicUsize::new(min_heap_pages),
pending_pages: AtomicUsize::new(0),
}
}
}
Expand Down Expand Up @@ -122,6 +137,7 @@ mod tests {

RubyHeapTrigger {
target_heap_pages: AtomicUsize::new(target_heap_pages),
pending_pages: AtomicUsize::new(0),
}
}

Expand Down
8 changes: 2 additions & 6 deletions lib/fileutils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -715,7 +715,7 @@ def cp_lr(src, dest, noop: nil, verbose: nil,
# Keyword arguments:
#
# - <tt>force: true</tt> - overwrites +dest+ if it exists.
# - <tt>relative: false</tt> - create links relative to +dest+.
# - <tt>relative: true</tt> - create links relative to +dest+.
# - <tt>noop: true</tt> - does not create links.
# - <tt>verbose: true</tt> - prints an equivalent command:
#
Expand Down Expand Up @@ -783,7 +783,7 @@ def ln_sr(src, dest, target_directory: true, force: nil, noop: nil, verbose: nil
n = real_ddirs.size - i
n -= 1 unless target_directory
link2 = fu_clean_components(*Array.new([n, 0].max, '..'), *real_sdirs[i..-1])
link1 = link2 if link1.size > link2.size
link1 = link2 if !link2.empty? and link1.size > link2.size
end
s = File.join(link1)
fu_output_message [cmd, s, d].flatten.join(' ') if verbose
Expand Down Expand Up @@ -2066,10 +2066,6 @@ def fu_windows?; true end #:nodoc:
def fu_windows?; false end #:nodoc:
end

def fu_copy_stream0(src, dest, blksize = nil) #:nodoc:
IO.copy_stream(src, dest)
end

def fu_stream_blksize(*streams) #:nodoc:
streams.each do |s|
next unless s.respond_to?(:stat)
Expand Down
Loading