Skip to content

Commit

Permalink
[GR-39230] Backports for 22.2
Browse files Browse the repository at this point in the history
PullRequest: truffleruby/3431
  • Loading branch information
eregon committed Jul 13, 2022
2 parents e3f9cae + bef8d1a commit 56ecb19
Show file tree
Hide file tree
Showing 17 changed files with 292 additions and 64 deletions.
21 changes: 4 additions & 17 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,3 @@
# 22.3.0

New features:


Bug fixes:


Compatibility:


Performance:


Changes:


# 22.2.0

New features:
Expand All @@ -40,6 +23,8 @@ Bug fixes:
* Fix `/#{...}/o` to evaluate only once per context when splitting happens (@eregon).
* Fix `Kernel#sprintf` formatting of floats to be like CRuby (@aardvark179).
* Fix `Process.egid=` to accept `String`s (#2615, @ngtban)
* Fix optional assignment to only evaluate index arguments once (#2658, @aardvark179).
* Fix `StringIO` to set position correctly after reading multi-byte characters (#2207, @aardvark179).

Compatibility:

Expand All @@ -61,13 +46,15 @@ Compatibility:
* Use `$PAGER` for `--help` and `--help*`, similar to CRuby (#2542, @Strech).
* Ensure all headers are warnings-free (#2662, @eregon).
* All `IO` instances should have `T_FILE` as their `rb_type()`, not only `File` instances (#2662, @eregon).
* Make `rb_fd_select` retry on `EINTR` (#1584, @aardvark179).

Performance:

* Reimplement `Float#to_s` for better performance (#1584, @aardvark179).
* Improve reference processing by making C object free functions and other finalizers more lightweight (@aardvark179).
* Improve performance of `RSTRING_PTR` for interned strings (@aardvark179).
* Cache constant argument formats used with `rb_scan_args_kw` (@aardvark179).
* Report polymorphism inside `Hash#[]` to recover performance (@aardvark179).

Changes:

Expand Down
2 changes: 1 addition & 1 deletion ci.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ local part_definitions = {
bench_machine: ["x52"] + self.normal_machine + ["no_frequency_scaling"],
},
docker: {
image: "phx.ocir.io/oraclelabs2/c_graal/buildslave:buildslave_ol7",
image: "buildslave_ol7",
mount_modules: true,
},
},
Expand Down
20 changes: 10 additions & 10 deletions common.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@
"jdks": {
"openjdk11": {"name": "openjdk", "version": "11.0.11+9", "platformspecific": true },
"oraclejdk11": {"name": "oraclejdk", "version": "11.0.11+9", "platformspecific": true },
"labsjdk-ce-11": {"name": "labsjdk", "version": "ce-11.0.16+5-jvmci-22.2-b03", "platformspecific": true },
"labsjdk-ce-11-llvm": {"name": "labsjdk", "version": "ce-11.0.16+5-jvmci-22.2-b03-sulong", "platformspecific": true },
"labsjdk-ee-11": {"name": "labsjdk", "version": "ee-11.0.16+9-jvmci-22.2-b03", "platformspecific": true },
"labsjdk-ee-11-llvm": {"name": "labsjdk", "version": "ee-11.0.16+9-jvmci-22.2-b03-sulong", "platformspecific": true },
"labsjdk-ce-11": {"name": "labsjdk", "version": "ce-11.0.16+7-jvmci-22.2-b04", "platformspecific": true },
"labsjdk-ce-11-llvm": {"name": "labsjdk", "version": "ce-11.0.16+7-jvmci-22.2-b04-sulong", "platformspecific": true },
"labsjdk-ee-11": {"name": "labsjdk", "version": "ee-11.0.16+11-jvmci-22.2-b05", "platformspecific": true },
"labsjdk-ee-11-llvm": {"name": "labsjdk", "version": "ee-11.0.16+11-jvmci-22.2-b05-sulong", "platformspecific": true },

"oraclejdk17": {"name": "oraclejdk", "version": "17.0.1+12", "platformspecific": true },
"labsjdk-ce-17": {"name": "labsjdk", "version": "ce-17.0.4+5-jvmci-22.2-b03", "platformspecific": true },
"labsjdk-ce-17Debug": {"name": "labsjdk", "version": "ce-17.0.4+5-jvmci-22.2-b03-debug", "platformspecific": true },
"labsjdk-ce-17-llvm": {"name": "labsjdk", "version": "ce-17.0.4+5-jvmci-22.2-b03-sulong", "platformspecific": true },
"labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.4+9-jvmci-22.2-b03", "platformspecific": true },
"labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.4+9-jvmci-22.2-b03-debug", "platformspecific": true },
"labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.4+9-jvmci-22.2-b03-sulong", "platformspecific": true }
"labsjdk-ce-17": {"name": "labsjdk", "version": "ce-17.0.4+7-jvmci-22.2-b04", "platformspecific": true },
"labsjdk-ce-17Debug": {"name": "labsjdk", "version": "ce-17.0.4+7-jvmci-22.2-b04-debug", "platformspecific": true },
"labsjdk-ce-17-llvm": {"name": "labsjdk", "version": "ce-17.0.4+7-jvmci-22.2-b04-sulong", "platformspecific": true },
"labsjdk-ee-17": {"name": "labsjdk", "version": "ee-17.0.4+11-jvmci-22.2-b05", "platformspecific": true },
"labsjdk-ee-17Debug": {"name": "labsjdk", "version": "ee-17.0.4+11-jvmci-22.2-b05-debug", "platformspecific": true },
"labsjdk-ee-17-llvm": {"name": "labsjdk", "version": "ee-17.0.4+11-jvmci-22.2-b05-sulong", "platformspecific": true }
},

"COMMENT.devkits" : "The devkits versions reflect those used to build the JVMCI JDKs (e.g., see devkit_platform_revisions in <jdk>/make/conf/jib-profiles.js)",
Expand Down
2 changes: 1 addition & 1 deletion lib/cext/ABI_check.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
5
6
4 changes: 2 additions & 2 deletions lib/truffle/stringio.rb
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ def each_byte
d = @__data__
string = d.string

while d.pos < string.length
while d.pos < string.bytesize
check_readable
byte = string.getbyte d.pos
d.pos += 1
Expand Down Expand Up @@ -468,7 +468,7 @@ def read(length = nil, buffer = nil)
buffer.replace str if buffer
end

d.pos += str.length
d.pos += str.bytesize
str
end

Expand Down
11 changes: 3 additions & 8 deletions lib/truffle/truffle/openssl-prefix.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,6 @@

# Set OPENSSL_PREFIX in ENV to find the OpenSSL headers

module Truffle
OPENSSL_PREFIX_WAS_SET = ENV.key?('OPENSSL_PREFIX')
end

search_homebrew = -> homebrew {
if prefix = "#{homebrew}/opt/[email protected]" and Dir.exist?(prefix)
prefix
Expand All @@ -20,10 +16,9 @@ module Truffle
end
}

macOS = RUBY_PLATFORM.include?('darwin')

if macOS && !ENV['OPENSSL_PREFIX']
if prefix = search_homebrew.call('/usr/local')
if Truffle::Platform.darwin? && !ENV['OPENSSL_PREFIX']
default_homebrew_prefix = Truffle::System.host_cpu == 'aarch64' ? '/opt/homebrew' : '/usr/local'
if prefix = search_homebrew.call(default_homebrew_prefix)
# found
else
homebrew = `brew --prefix 2>/dev/null`.strip
Expand Down
4 changes: 2 additions & 2 deletions mx.truffleruby/suite.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
{
"name": "regex",
"subdir": True,
"version": "f33384d85f86bc5f4fd1a92d9d734309c64d381d",
"version": "105d87b99fc5879433f9b1c54040200530f9c1aa",
"urls": [
{"url": "https://github.com/oracle/graal.git", "kind": "git"},
{"url": "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind": "binary"},
Expand All @@ -16,7 +16,7 @@
{
"name": "sulong",
"subdir": True,
"version": "f33384d85f86bc5f4fd1a92d9d734309c64d381d",
"version": "105d87b99fc5879433f9b1c54040200530f9c1aa",
"urls": [
{"url": "https://github.com/oracle/graal.git", "kind": "git"},
{"url": "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind": "binary"},
Expand Down
38 changes: 38 additions & 0 deletions spec/ruby/language/optional_assignments_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,44 @@ def []=(k, v)
(@b[:k] ||= 12).should == 12
end

it 'correctly handles a splatted argument for the index' do
(@b[*[:k]] ||= 12).should == 12
end

it "evaluates the index precisely once" do
ary = [:x, :y]
@a[:x] = 15
@a[ary.pop] ||= 25
ary.should == [:x]
@a.should == { x: 15, y: 25 }
end

it "evaluates the index arguments in the correct order" do
ary = Class.new(Array) do
def [](x, y)
super(x + 3 * y)
end

def []=(x, y, value)
super(x + 3 * y, value)
end
end.new
ary[0, 0] = 1
ary[1, 0] = 1
ary[2, 0] = nil
ary[3, 0] = 1
ary[4, 0] = 1
ary[5, 0] = 1
ary[6, 0] = nil

foo = [0, 2]

ary[foo.pop, foo.pop] ||= 2

ary[2, 0].should == 2
ary[6, 0].should == nil
end

it 'returns the assigned value, not the result of the []= method with +=' do
@b[:k] = 17
(@b[:k] += 12).should == 29
Expand Down
6 changes: 6 additions & 0 deletions spec/ruby/library/stringio/shared/read.rb
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@
@io.send(@method)
@io.pos.should eql(7)
end

it "correctly update the current position in bytes when multi-byte characters are used" do
@io.print("example\u03A3") # Overwrite the original string with 8 characters containing 9 bytes.
@io.send(@method)
@io.pos.should eql(9)
end
end

describe :stringio_read_nil, shared: true do
Expand Down
139 changes: 137 additions & 2 deletions src/main/c/cext/fd.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
*/
#include <truffleruby-impl.h>
#include <fcntl.h>
#include <errno.h>
#include <ruby/thread.h>
#include <time.h>

// For howmany()
#ifdef HAVE_SYS_PARAM_H
Expand Down Expand Up @@ -105,6 +107,65 @@ void rb_fd_dup(rb_fdset_t *dst, const rb_fdset_t *src) {
memcpy(dst->fdset, src->fdset, size);
}

void rb_fd_init_copy(rb_fdset_t *dst, rb_fdset_t *src) {
size_t size = howmany(rb_fd_max(src), NFDBITS) * sizeof(fd_mask);

if (size < sizeof(fd_set)) {
size = sizeof(fd_set);
}
dst->maxfd = src->maxfd;
dst->fdset = xmalloc(size);
memcpy(dst->fdset, src->fdset, size);
}

static bool timespec_subtract(struct timespec *result, struct timespec x, struct timespec y) {
/* Perform the carry for the later subtraction by updating y. */
if (x.tv_nsec < y.tv_nsec) {
long nsec = (y.tv_nsec - x.tv_nsec) / 1000000000 + 1;
y.tv_nsec -= 1000000000 * nsec;
y.tv_sec += nsec;
}
if (x.tv_nsec - y.tv_nsec > 1000000000) {
long nsec = (x.tv_nsec - y.tv_nsec) / 1000000000;
y.tv_nsec += 1000000000 * nsec;
y.tv_sec -= nsec;
}

/* Compute the time remaining to wait.
tv_nsec is certainly positive. */
result->tv_sec = x.tv_sec - y.tv_sec;
result->tv_nsec = x.tv_nsec - y.tv_nsec;

/* Return 1 if result is negative. */
return x.tv_sec < y.tv_sec;
}

static bool timeval_subtract(struct timeval *result, struct timeval x, struct timeval y) {
/* Perform the carry for the later subtraction by updating y. */
if (x.tv_usec < y.tv_usec) {
long usec = (y.tv_usec - x.tv_usec) / 1000000 + 1;
y.tv_usec -= 1000000 * usec;
y.tv_sec += usec;
}
if (x.tv_usec - y.tv_usec > 1000000) {
long usec = (x.tv_usec - y.tv_usec) / 1000000;
y.tv_usec += 1000000 * usec;
y.tv_sec -= usec;
}

/* Compute the time remaining to wait.
tv_usec is certainly positive. */
result->tv_sec = x.tv_sec - y.tv_sec;
result->tv_usec = x.tv_usec - y.tv_usec;

/* Return 1 if result is negative. */
return x.tv_sec < y.tv_sec;
}

static int should_retry(int result) {
return (result < 0) && (errno == EINTR);
}

int rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *exceptfds, struct timeval *timeout) {
fd_set *r = NULL, *w = NULL, *e = NULL;
if (readfds) {
Expand All @@ -122,21 +183,90 @@ int rb_fd_select(int n, rb_fdset_t *readfds, rb_fdset_t *writefds, rb_fdset_t *e
return select(n, r, w, e, timeout);
}


// NOTE: MRI's version has more fields
struct select_set {
int max;
rb_fdset_t *rset;
rb_fdset_t *wset;
rb_fdset_t *eset;
rb_fdset_t *orig_rset;
rb_fdset_t *orig_wset;
rb_fdset_t *orig_eset;
struct timeval *timeout;
struct timeval *orig_timeout;
};

static inline void restore_fds(rb_fdset_t *dst, rb_fdset_t *src) {
if (dst) {
rb_fd_dup(dst, src);
}
}

static bool update_timeout(struct timeval *timeout, struct timeval *orig_timeout, struct timespec *starttime) {
struct timespec currenttime;
struct timespec difftime;
struct timeval difftimeout;
bool timeleft = true;
if (timeout) {
clock_gettime(CLOCK_MONOTONIC, &currenttime);
timespec_subtract(&difftime, currenttime, *starttime);
difftimeout.tv_sec = difftime.tv_sec;
difftimeout.tv_usec = difftime.tv_nsec / 1000;
timeleft = timeval_subtract(timeout, *orig_timeout, difftimeout);
}

return timeleft;
}

static void* rb_thread_fd_select_blocking(void *data) {
struct select_set *set = (struct select_set*)data;
int result = rb_fd_select(set->max, set->rset, set->wset, set->eset, set->timeout);
struct timespec starttime;

if (set->timeout) {
clock_gettime(CLOCK_MONOTONIC, &starttime);
}

int result = 0;
bool timeleft = true;
do {
restore_fds(set->rset, set->orig_rset);
restore_fds(set->wset, set->orig_wset);
restore_fds(set->eset, set->orig_eset);
timeleft = update_timeout(set->timeout, set->orig_timeout, &starttime);
if (!timeleft) {
break;
}
result = rb_fd_select(set->max, set->rset, set->wset, set->eset, set->timeout);
} while (should_retry(result));
return (void*)(long)result;
}

static void* rb_thread_fd_select_internal(void *sets) {
return rb_thread_call_without_gvl(rb_thread_fd_select_blocking, sets, RUBY_UBF_IO, 0);
}

static void rb_thread_fd_select_set_free(struct select_set *sets) {
if (sets->orig_rset) {
rb_fd_term(sets->orig_rset);
}
if (sets->orig_wset) {
rb_fd_term(sets->orig_wset);
}
if (sets->orig_eset) {
rb_fd_term(sets->orig_eset);
}
}

static void fd_init_copy(rb_fdset_t *dst, int max, rb_fdset_t *src) {
if (src) {
rb_fd_resize(max - 1, src);
if (dst != src) {
rb_fd_init_copy(dst, src);
}
}
}

int rb_thread_fd_select(int max, rb_fdset_t *read, rb_fdset_t *write, rb_fdset_t *except, struct timeval *timeout) {
// NOTE: MRI has more logic in here
struct select_set set;
Expand All @@ -145,7 +275,12 @@ int rb_thread_fd_select(int max, rb_fdset_t *read, rb_fdset_t *write, rb_fdset_t
set.wset = write;
set.eset = except;
set.timeout = timeout;
fd_init_copy(set.orig_rset, set.max, set.rset);
fd_init_copy(set.orig_wset, set.max, set.wset);
fd_init_copy(set.orig_eset, set.max, set.eset);
struct timeval orig_timeval = *timeout;
set.orig_timeout = &orig_timeval;

void* result = rb_thread_call_without_gvl(rb_thread_fd_select_blocking, (void*)(&set), RUBY_UBF_IO, 0);
void* result = rb_ensure(rb_thread_fd_select_internal, (VALUE)&set, rb_thread_fd_select_set_free, (VALUE)&set);
return (int)(long)result;
}
3 changes: 2 additions & 1 deletion src/main/c/openssl/extconf.rb
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ def find_openssl_library

# TruffleRuby: do not perform all checks again if extconf.h already exists
extconf_h = "#{__dir__}/extconf.h"
if File.exist?(extconf_h) && File.mtime(extconf_h) >= File.mtime(__FILE__ ) && !Truffle::OPENSSL_PREFIX_WAS_SET
in_development = ENV.key?('MX_HOME')
if in_development && File.exist?(extconf_h) && File.mtime(extconf_h) >= File.mtime(__FILE__)
$extconf_h = extconf_h
else
### START of checks
Expand Down
Loading

0 comments on commit 56ecb19

Please sign in to comment.