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-2
  • Loading branch information
rm155 committed Dec 14, 2023
2 parents 1d91675 + a79a1d3 commit c73d618
Show file tree
Hide file tree
Showing 89 changed files with 1,639 additions and 671 deletions.
8 changes: 5 additions & 3 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ The following bundled gems are updated.
* test-unit 3.6.1
* rexml 3.2.6
* rss 0.3.0
* net-ftp 0.3.0
* net-ftp 0.3.2
* net-imap 0.4.8
* net-smtp 0.4.0
* rbs 3.3.2
Expand Down Expand Up @@ -275,7 +275,9 @@ changelog for details of the default gems or bundled gems.
* `racc` is promoted to bundled gems.
* You need to add `racc` to your `Gemfile` if you use `racc` under bundler environment.
* `ext/readline` is retired
* We have `reline` that is pure Ruby implementation compatible with `ext/readline` API. We rely on `reline` in the future. If you need to use `ext/readline`, you can install `ext/readline` via rubygems.org with `gem install readline-ext`.
* We have `reline` that is pure Ruby implementation compatible with `ext/readline` API.
We rely on `reline` in the future. If you need to use `ext/readline`, you can install
`ext/readline` via rubygems.org with `gem install readline-ext`.
* We no longer need to install libraries like `libreadline` or `libedit`.
## C API updates
Expand Down Expand Up @@ -343,7 +345,7 @@ changelog for details of the default gems or bundled gems.
* `ratio_in_yjit` stat produced by `--yjit-stats` is now available in release builds,
a special stats or dev build is no longer required to access most stats.
* Exit tracing option now supports sampling
* `--trace-exits-sample-rate=N`
* `--yjit-trace-exits-sample-rate=N`
* More thorough testing and multiple bug fixes
* `--yjit-stats=quiet` is added to avoid printing stats on exit.
* `--yjit-perf` is added to facilitate profiling with Linux perf.
Expand Down
1 change: 1 addition & 0 deletions common.mk
Original file line number Diff line number Diff line change
Expand Up @@ -8542,6 +8542,7 @@ load.$(OBJEXT): $(top_srcdir)/internal/dir.h
load.$(OBJEXT): $(top_srcdir)/internal/error.h
load.$(OBJEXT): $(top_srcdir)/internal/file.h
load.$(OBJEXT): $(top_srcdir)/internal/gc.h
load.$(OBJEXT): $(top_srcdir)/internal/hash.h
load.$(OBJEXT): $(top_srcdir)/internal/imemo.h
load.$(OBJEXT): $(top_srcdir)/internal/load.h
load.$(OBJEXT): $(top_srcdir)/internal/parse.h
Expand Down
10 changes: 5 additions & 5 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -3916,26 +3916,26 @@ AC_SUBST(CARGO_BUILD_ARGS)dnl for selecting Rust build profiles
AC_SUBST(YJIT_LIBS)dnl for optionally building the Rust parts of YJIT
AC_SUBST(YJIT_OBJ)dnl for optionally building the C parts of YJIT
dnl Currently, RJIT only supports Unix x86_64 platforms.
dnl RJIT supports only x86_64 platforms, but allows arm64/aarch64 for custom JITs.
RJIT_TARGET_OK=no
AS_IF([test "$cross_compiling" = no],
AS_CASE(["$target_cpu-$target_os"],
[*android*], [
RJIT_TARGET_OK=no
],
[x86_64-darwin*], [
[arm64-darwin*|aarch64-darwin*|x86_64-darwin*], [
RJIT_TARGET_OK=yes
],
[x86_64-*linux*], [
[arm64-*linux*|aarch64-*linux*|x86_64-*linux*], [
RJIT_TARGET_OK=yes
],
[x86_64-*bsd*], [
[arm64-*bsd*|aarch64-*bsd*|x86_64-*bsd*], [
RJIT_TARGET_OK=yes
]
)
)
dnl Build RJIT on Unix x86_64 platforms or if --enable-rjit is specified.
dnl Build RJIT on supported platforms or if --enable-rjit is specified.
AC_ARG_ENABLE(rjit,
AS_HELP_STRING([--enable-rjit],
[enable pure-Ruby JIT compiler. enabled by default on Unix x86_64 platforms]),
Expand Down
70 changes: 49 additions & 21 deletions dln.c
Original file line number Diff line number Diff line change
Expand Up @@ -419,33 +419,63 @@ dln_open(const char *file)
static void *
dln_sym(void *handle, const char *symbol)
{
void *func;
const char *error;

#if defined(_WIN32)
char message[1024];
return GetProcAddress(handle, symbol);
#elif defined(USE_DLN_DLOPEN)
return dlsym(handle, symbol);
#endif
}

static void *
dln_sym_func(void *handle, const char *symbol)
{
void *func = dln_sym(handle, symbol);

func = GetProcAddress(handle, symbol);
if (func == NULL) {
const char *error;
#if defined(_WIN32)
char message[1024];
error = dln_strerror();
goto failed;
}

#elif defined(USE_DLN_DLOPEN)
func = dlsym(handle, symbol);
if (func == NULL) {
const size_t errlen = strlen(error = dln_strerror()) + 1;
error = memcpy(ALLOCA_N(char, errlen), error, errlen);
goto failed;
}
#endif

dln_loaderror("%s - %s", error, symbol);
}
return func;

failed:
dln_loaderror("%s - %s", error, symbol);
}

#define dln_sym_callable(rettype, argtype, handle, symbol) \
(*(rettype (*)argtype)dln_sym_func(handle, symbol))
#endif

void *
dln_symbol(void *handle, const char *symbol)
{
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
if (EXTERNAL_PREFIX[0]) {
const size_t symlen = strlen(symbol);
char *const tmp = ALLOCA_N(char, symlen + sizeof(EXTERNAL_PREFIX));
if (!tmp) dln_memerror();
memcpy(tmp, EXTERNAL_PREFIX, sizeof(EXTERNAL_PREFIX) - 1);
memcpy(tmp + sizeof(EXTERNAL_PREFIX) - 1, symbol, symlen + 1);
symbol = tmp;
}
if (handle == NULL) {
# if defined(USE_DLN_DLOPEN)
handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL);
# elif defined(_WIN32)
handle = rb_libruby_handle();
# else
return NULL;
# endif
}
return dln_sym(handle, symbol);
#else
return NULL;
#endif
}


#if defined(RUBY_DLN_CHECK_ABI) && defined(USE_DLN_DLOPEN)
static bool
Expand All @@ -464,20 +494,18 @@ dln_load(const char *file)

#ifdef RUBY_DLN_CHECK_ABI
typedef unsigned long long abi_version_number;
typedef abi_version_number abi_version_func(void);
abi_version_func *abi_version_fct = (abi_version_func *)dln_sym(handle, EXTERNAL_PREFIX "ruby_abi_version");
abi_version_number binary_abi_version = (*abi_version_fct)();
abi_version_number binary_abi_version =
dln_sym_callable(abi_version_number, (void), handle, EXTERNAL_PREFIX "ruby_abi_version")();
if (binary_abi_version != ruby_abi_version() && abi_check_enabled_p()) {
dln_loaderror("incompatible ABI version of binary - %s", file);
}
#endif

char *init_fct_name;
init_funcname(&init_fct_name, file);
void (*init_fct)(void) = (void(*)(void))dln_sym(handle, init_fct_name);

/* Call the init code */
(*init_fct)();
dln_sym_callable(void, (void), handle, init_fct_name)();

return handle;

Expand Down
1 change: 1 addition & 0 deletions dln.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ RUBY_SYMBOL_EXPORT_BEGIN
char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
void *dln_load(const char*);
void *dln_symbol(void*,const char*);

RUBY_SYMBOL_EXPORT_END

Expand Down
9 changes: 9 additions & 0 deletions dmydln.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,12 @@ dln_load(const char *file)

UNREACHABLE_RETURN(NULL);
}

NORETURN(void *dln_symbol(void*,const char*));
void*
dln_symbol(void *handle, const char *symbol)
{
rb_loaderror("this executable file can't load extension libraries");

UNREACHABLE_RETURN(NULL);
}
10 changes: 6 additions & 4 deletions doc/yjit/yjit.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,15 +165,17 @@ The machine code generated for a given method can be printed by adding `puts Rub
YJIT supports all command-line options supported by upstream CRuby, but also adds a few YJIT-specific options:

- `--yjit`: enable YJIT (disabled by default)
- `--yjit-exec-mem-size=N`: size of the executable memory block to allocate, in MiB (default 64 MiB)
- `--yjit-call-threshold=N`: number of calls after which YJIT begins to compile a function (default 30)
- `--yjit-cold-threshold=N`: number of global calls after which an ISEQ is considered cold and not
compiled, lower values mean less code is compiled (default 200K)
- `--yjit-exec-mem-size=N`: size of the executable memory block to allocate, in MiB (default 64 MiB)
- `--yjit-code-gc`: enable code GC (disabled by default as of Ruby 3.3)
compiled, lower values mean less code is compiled (default 200K)
- `--yjit-stats`: print statistics after the execution of a program (incurs a run-time cost)
- `--yjit-stats=quiet`: gather statistics while running a program but don't print them. Stats are accessible through `RubyVM::YJIT.runtime_stats`. (incurs a run-time cost)
- `--yjit-disable`: disable YJIT despite other `--yjit*` flags for lazily enabling it with `RubyVM::YJIT.enable`
- `--yjit-code-gc`: enable code GC (disabled by default as of Ruby 3.3)
- `--yjit-perf`: enable frame pointers and profiling with the `perf` tool
- `--yjit-trace-exits`: produce a Marshal dump of backtraces from specific exits. Automatically enables `--yjit-stats`
- `--yjit-perf`: Enable frame pointers and profiling with the `perf` tool
- `--yjit-trace-exits-sample-rate=N`: trace exit locations only every Nth occurrence

Note that there is also an environment variable `RUBY_YJIT_ENABLE` which can be used to enable YJIT.
This can be useful for some deployment scripts where specifying an extra command-line option to Ruby is not practical.
Expand Down
1 change: 1 addition & 0 deletions ext/-test-/load/resolve_symbol_resolver/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create_makefile('-test-/load/resolve_symbol_resolver')
50 changes: 50 additions & 0 deletions ext/-test-/load/resolve_symbol_resolver/resolve_symbol_resolver.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#include <ruby.h>
#include "ruby/internal/intern/load.h"

typedef VALUE(*target_func)(VALUE);

static target_func rst_any_method;

VALUE
rsr_any_method(VALUE klass)
{
return rst_any_method((VALUE)NULL);
}

VALUE
rsr_try_resolve_fname(VALUE klass)
{
target_func rst_something_missing =
(target_func) rb_ext_resolve_symbol("-test-/load/resolve_symbol_missing", "rst_any_method");
if (rst_something_missing == NULL) {
// This should be done in Init_*, so the error is LoadError
rb_raise(rb_eLoadError, "symbol not found: missing fname");
}
return Qtrue;
}

VALUE
rsr_try_resolve_sname(VALUE klass)
{
target_func rst_something_missing =
(target_func)rb_ext_resolve_symbol("-test-/load/resolve_symbol_target", "rst_something_missing");
if (rst_something_missing == NULL) {
// This should be done in Init_*, so the error is LoadError
rb_raise(rb_eLoadError, "symbol not found: missing sname");
}
return Qtrue;
}

void
Init_resolve_symbol_resolver(void)
{
VALUE mod = rb_define_module("ResolveSymbolResolver");
rb_define_singleton_method(mod, "any_method", rsr_any_method, 0);
rb_define_singleton_method(mod, "try_resolve_fname", rsr_try_resolve_fname, 0);
rb_define_singleton_method(mod, "try_resolve_sname", rsr_try_resolve_sname, 0);

rst_any_method = (target_func)rb_ext_resolve_symbol("-test-/load/resolve_symbol_target", "rst_any_method");
if (rst_any_method == NULL) {
rb_raise(rb_eLoadError, "resolve_symbol_target is not loaded");
}
}
1 change: 1 addition & 0 deletions ext/-test-/load/resolve_symbol_target/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create_makefile('-test-/load/resolve_symbol_target')
15 changes: 15 additions & 0 deletions ext/-test-/load/resolve_symbol_target/resolve_symbol_target.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <ruby.h>
#include "resolve_symbol_target.h"

VALUE
rst_any_method(VALUE klass)
{
return rb_str_new_cstr("from target");
}

void
Init_resolve_symbol_target(void)
{
VALUE mod = rb_define_module("ResolveSymbolTarget");
rb_define_singleton_method(mod, "any_method", rst_any_method, 0);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
LIBRARY resolve_symbol_target
EXPORTS
Init_resolve_symbol_target
rst_any_method
4 changes: 4 additions & 0 deletions ext/-test-/load/resolve_symbol_target/resolve_symbol_target.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <ruby.h>
#include "ruby/internal/dllexport.h"

RUBY_EXTERN VALUE rst_any_method(VALUE);
1 change: 1 addition & 0 deletions ext/-test-/load/stringify_symbols/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create_makefile('-test-/load/stringify_symbols')
29 changes: 29 additions & 0 deletions ext/-test-/load/stringify_symbols/stringify_symbols.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include <ruby.h>
#include "ruby/internal/intern/load.h"
#include "ruby/util.h"

#if SIZEOF_INTPTR_T == SIZEOF_LONG_LONG
# define UINTPTR2NUM ULL2NUM
#elif SIZEOF_INTPTR_T == SIZEOF_LONG
# define UINTPTR2NUM ULONG2NUM
#else
# define UINTPTR2NUM UINT2NUM
#endif

static VALUE
stringify_symbol(VALUE klass, VALUE fname, VALUE sname)
{
void *ptr = rb_ext_resolve_symbol(StringValueCStr(fname), StringValueCStr(sname));
if (ptr == NULL) {
return Qnil;
}
uintptr_t uintptr = (uintptr_t)ptr;
return UINTPTR2NUM(uintptr);
}

void
Init_stringify_symbols(void)
{
VALUE mod = rb_define_module("StringifySymbols");
rb_define_singleton_method(mod, "stringify_symbol", stringify_symbol, 2);
}
1 change: 1 addition & 0 deletions ext/-test-/load/stringify_target/extconf.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
create_makefile('-test-/load/stringify_target')
15 changes: 15 additions & 0 deletions ext/-test-/load/stringify_target/stringify_target.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <ruby.h>
#include "stringify_target.h"

VALUE
stt_any_method(VALUE klass)
{
return rb_str_new_cstr("from target");
}

void
Init_stringify_target(void)
{
VALUE mod = rb_define_module("StringifyTarget");
rb_define_singleton_method(mod, "any_method", stt_any_method, 0);
}
4 changes: 4 additions & 0 deletions ext/-test-/load/stringify_target/stringify_target.def
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
LIBRARY stringify_target
EXPORTS
Init_stringify_target
stt_any_method
4 changes: 4 additions & 0 deletions ext/-test-/load/stringify_target/stringify_target.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#include <ruby.h>
#include "ruby/internal/dllexport.h"

RUBY_EXTERN VALUE stt_any_method(VALUE);
Loading

0 comments on commit c73d618

Please sign in to comment.