Commit graph

262 commits

Author SHA1 Message Date
U.Nakamura
881088e06f merge revision(s) 4329554f17: [Backport #19985]
[Bug #19985] Raise LoadError with the converted feature name

	`Kernel#require` converts feature name objects that have the `to_path`
	method such as `Pathname`, but had used the original object on error
	and had resulted in an unexpected `TypeError`.
	---
	 load.c                    | 14 +++++++++++---
	 test/ruby/test_require.rb | 26 +++++++++++++++++++++-----
	 2 files changed, 32 insertions(+), 8 deletions(-)
2023-11-06 20:22:27 +09:00
U.Nakamura
8a8d889ca2 merge revision(s) 1f115f141d: [Backport #19246]
Speed up rebuilding the loaded feature index

	Rebuilding the loaded feature index slowed down with the bug fix
	for #17885 in 79a4484a07.  The
	slowdown was extreme if realpath emulation was used, but even when
	not emulated, it could be about 10x slower.

	This adds loaded_features_realpath_map to rb_vm_struct. This is a
	hidden hash mapping loaded feature paths to realpaths. When
	rebuilding the loaded feature index, look at this hash to get
	cached realpath values, and skip calling rb_check_realpath if a
	cached value is found.

	Fixes [Bug #19246]
	---
	 load.c    | 27 +++++++++++++++++++++++----
	 vm.c      |  2 ++
	 vm_core.h |  1 +
	 3 files changed, 26 insertions(+), 4 deletions(-)
2023-09-05 20:48:57 +09:00
nagachika
5c5a1135b2 merge revision(s) 790cf4b6d0: [Backport #19115]
Fix autoload status of statically linked extensions

	Previously, for statically-linked extensions, we used
	`vm->loading_table` to delay calling the init function until the
	extensions are required. This caused the extensions to look like they
	are in the middle of being loaded even before they're required.
	(`rb_feature_p()` returned true with a loading path output.) Combined
	with autoload, queries like `defined?(CONST)` and `Module#autoload?`
	were confused by this and returned nil incorrectly. RubyGems uses
	`defined?` to detect if OpenSSL is available and failed when OpenSSL was
	available in builds using `--with-static-linked-ext`.

	Use a dedicated table for the init functions instead of adding them to
	the loading table. This lets us remove some logic from non-EXTSTATIC
	builds.

	[Bug #19115]
	---
	 load.c                     | 55 +++++++++++++++++++++++++++++++++++-----------
	 test/ruby/test_autoload.rb | 18 +++++++++++++++
	 vm.c                       |  3 +++
	 vm_core.h                  |  9 ++++++++
	 4 files changed, 72 insertions(+), 13 deletions(-)
2023-03-25 14:25:37 +09:00
nagachika
26b3f0b6a9 merge revision(s) 8ce2fb9bbbaea14737c84385b1573f743a30f773,3a0f6ce1d31eefd8af01b50f3632a64d64e8f8c1: [Backport #19415]
Only emit circular dependency warning for owned thread shields [Bug
	 #19415]

	If multiple threads attemps to load the same file concurrently
	it's not a circular dependency issue.

	So we check that the existing ThreadShield is owner by the current
	fiber before warning about circular dependencies.
	---
	 internal/thread.h                                     |  1 +
	 load.c                                                |  3 ++-
	 spec/ruby/core/kernel/shared/require.rb               | 11 +++++++++++
	 spec/ruby/fixtures/code/concurrent_require_fixture.rb |  4 ++++
	 test/ruby/test_require.rb                             |  3 ---
	 thread.c                                              | 11 +++++++++++
	 6 files changed, 29 insertions(+), 4 deletions(-)
	 create mode 100644 spec/ruby/fixtures/code/concurrent_require_fixture.rb

	Use Thread.pass until thread.stop? to wait for thread to block

	[Bug #19415]

	It should be more reliable
	---
	 spec/ruby/fixtures/code/concurrent_require_fixture.rb | 2 +-
	 1 file changed, 1 insertion(+), 1 deletion(-)
2023-03-21 15:32:44 +09:00
nagachika
012015d762 merge revision(s) b8f0dc59d5: [Backport #18599]
rb_provide_feature: Prevent $LOADED_FEATURES from being copied

	[Bug #18599]

	`vm->loaded_features` and `vm->loaded_features_snapshot` both share the
	same root. When a feature is pushed into `loaded_features`, the sharing
	is broken and `loaded_features` is copied.

	So an application requiring 1000 files, will allocate 1000 arrays of
	increasing size, which is very wasteful.

	To avoid this, we first clear the snapshot, so that `loaded_features`
	can directly be pushed into.

	Co-Authored-By: Peter Zhu <peter.zhu@shopify.com>
	---
	 load.c | 4 ++++
	 1 file changed, 4 insertions(+)
2022-11-13 17:07:58 +09:00
NARUSE, Yui
807dd04792 merge revision(s) c79d2e5474: [Backport #18562]
Fix TAG_THROW through require [Bug #18562]

	Previously this was being incorrectly swapped with TAG_RAISE in the next
	line. This would end up checking the T_IMEMO throw_data to the exception
	handling (which calls Module#===). This happened to not break existing
	tests because Module#=== returned false when klass is NULL.

	This commit handles throw from require correctly by jumping to the tag
	retaining the TAG_THROW state.
	---
	 load.c                      |  2 +-
	 test/ruby/test_exception.rb | 21 +++++++++++++++++++++
	 2 files changed, 22 insertions(+), 1 deletion(-)
2022-02-07 20:08:50 +09:00
Jeremy Evans
b35b7a1ef2 Allow Kernel#load to load code into a specified module
Instead of always using a new anonymous module for Kernel#load if
the wrap argument is not false/nil, use the given module if a module
is provided.

Implements [Feature #6210]
2021-11-17 22:43:40 -08:00
Nobuyoshi Nakada
a4876a563d Pass the VM pointer as an argument 2021-10-10 23:34:16 +09:00
Nobuyoshi Nakada
076f2e9d3e
Make volatile the variable will be taken out from EC_EXEC_TAG 2021-10-08 15:44:47 +09:00
Jeremy Evans
e4d85d3a2d Revert rescue around internal realpath call on Solaris
Solaris CI still has a problem even with these commits, so it doesn't
appear to fix the issue.  Reverting both 84e8e2a39b
and bfd2f159f0.
2021-10-04 10:51:52 -07:00
Jeremy Evans
3381fa5458 Only rescue realpath calls during require on Solaris
Remove temporary skip of test_no_curdir to see if this fixes the
problem.
2021-10-04 07:43:24 -09:00
Jeremy Evans
d9b7403746 Use a rescue around the internal realpath call for each loaded feature
This appears to be only necessary on Solaris, but this commit
enables it unconditionally to test breakage.  The following
commit will switch to only enabling it on Solaris.
2021-10-04 07:43:24 -09:00
Jeremy Evans
79a4484a07 Do not load file with same realpath twice when requiring
This fixes issues with paths being loaded twice in certain cases
when symlinks are used.

It took me multiple attempts to get this working.  My original
attempt tried to convert paths to realpaths before adding them
to $LOADED_FEATURES.  Unfortunately, this doesn't work well
with the loaded feature index, which is based off load paths
and not realpaths. While I was able to get require working, I'm
fairly sure the loaded feature index was not being used as
expected, which would have significant performance implications.
Additionally, I was never able to get that approach working with
autoload when autoloading a non-realpath file. It also broke
some specs.

This takes a more conservative approach. Directly before loading the
file, if the file with the same realpath has been required, the
loading of the file is skipped. The realpaths are stored as
fstrings in a hidden hash.

When rebuilding the loaded feature index, the hash of realpaths
is also rebuilt.  I'm guessing this makes rebuilding process
slower, but I don think that is a hot path. In general, modifying
loaded features is only done when reloading, and that tends to be
in non-production environments.

Change test_require_with_loaded_features_pop test to use 30 threads
and 300 iterations, instead of 4 threads and 1000 iterations.
I saw only sporadic failures with 4/1000, but consistent failures
30/300 threads. These failures were due to the fact that the
concurrent deletions from $LOADED_FEATURES in other threads can
result in rb_ary_entry returning nil when rebuilding the loaded
features index.

To avoid concurrency issues when rebuilding the loaded features
index, the building of the index itself is left alone, and
afterwards, a separate loop is done on a copy of the loaded feature
snapshot in order to rebuild the realpaths hash.

Fixes [Bug #17885]
2021-10-02 05:51:29 -09:00
Jeremy Evans
3f7da458a7 Make encoding loading not issue warning
Instead of relying on setting an unsetting ruby_verbose, which is
not thread-safe, restructure require_internal and load_lock to
accept a warn argument for whether to warn, and add
rb_require_internal_silent to require without warnings.  Use
rb_require_internal_silent when loading encoding.

Note this does not modify ruby_debug and errinfo handling, those
remain thread-unsafe.

Also silent requires when loading transcoders.
2021-10-02 05:51:29 -09:00
Jeremy Evans
162ad65fdd Revert "Do not load file with same realpath twice when requiring"
This reverts commit ddb85c5d2b.

This commit causes unexpected warnings in TestTranscode#test_loading_race
occasionally in CI.
2021-09-18 17:37:35 -07:00
Jeremy Evans
ddb85c5d2b Do not load file with same realpath twice when requiring
This fixes issues with paths being loaded twice in certain cases
when symlinks are used.

It took me multiple attempts to get this working.  My original
attempt tried to convert paths to realpaths before adding them
to $LOADED_FEATURES.  Unfortunately, this doesn't work well
with the loaded feature index, which is based off load paths
and not realpaths. While I was able to get require working, I'm
fairly sure the loaded feature index was not being used as
expected, which would have significant performance implications.
Additionally, I was never able to get that approach working with
autoload when autoloading a non-realpath file. It also broke
some specs.

This takes a more conservative approach. Directly before loading the
file, if the file with the same realpath has been required, the
loading of the file is skipped. The realpaths are stored as
fstrings in a hidden hash.

When rebuilding the loaded feature index, the hash of realpaths
is also rebuilt.  I'm guessing this makes rebuilding process
slower, but I don think that is a hot path. In general, modifying
loaded features is only done when reloading, and that tends to be
in non-production environments.

Change test_require_with_loaded_features_pop test to use 30 threads
and 300 iterations, instead of 4 threads and 1000 iterations.
I saw only sporadic failures with 4/1000, but consistent failures
30/300 threads. These failures were due to the fact that the
concurrent deletions from $LOADED_FEATURES in other threads can
result in rb_ary_entry returning nil when rebuilding the loaded
features index.

To avoid concurrency issues when rebuilding the loaded features
index, the building of the index itself is left alone, and
afterwards, a separate loop is done on a copy of the loaded feature
snapshot in order to rebuild the realpaths hash.

Fixes [Bug #17885]
2021-09-18 07:05:23 -09:00
Nobuyoshi Nakada
ddb32e6616
[Bug #18173] Update loaded_features_index
If $LOADED_FEATURES is changed in the just required file, also the
index table needs to be updated before loaded_features_snapshot is
reset.  If the snapshot is reset without updating the table, the
name of the added feature will not be found.
2021-09-16 18:48:20 +09:00
S-H-GAMELINKS
af5826a25e Replace RB_TYPE_P macro to FIXNUM_P and RB_INTEGER_TYPE_P macro 2021-09-12 11:16:09 +09:00
Nobuyoshi Nakada
b76ad15ed0
Remove stale DLEXT2
Actually disabled at 181a3a2af5 in
2004,  it has remained in config.status and been carried over to
rbconfig.rb.
2021-09-10 14:51:56 +09:00
S.H
378e8cdad6
Using RBOOL macro 2021-08-02 12:06:44 +09:00
Jeremy Evans
345db8f2aa Avoid pointless attempts to open .so file if already required
When attempting to require a file without an extension that has
already been required or provided with an .so extension, only
look for files with an .rb extension. There is no point in
trying to find files with an .so extension, since we already
know one has been loaded.

Previously, attempting to require such a file scanned the load
path twice, once for .rb and once for .so.  Now it only scans
once for .rb.  The scan once for .rb cannot be avoided, since
the .rb file would take precedence and should be loaded if it
exists.

Fixes [Bug #10902]
2021-07-28 12:29:45 +09:00
Nobuyoshi Nakada
b360588cd3
Sort feature index arrays by the priority of file types [Bug #15856]
When looking for libraries to load with a feature name without
extension, `.rb` files are given priority. However, since the
feature index arrays were not in that order of priority, but in
the order in which they were loaded, a lower priority extension
library might be returned. In that case, the `.rb` file had to be
searched for again from the `$LOAD_PATH`, resulting in poor
performance.
2021-07-24 23:59:07 +09:00
Nobuyoshi Nakada
803eb1ee83
Get rid of type aliasing 2021-07-18 19:22:21 +09:00
Nobuyoshi Nakada
70833fab7f
Suppress gcc11 clobbered warning 2021-06-14 23:24:17 +09:00
Samuel Williams
25921fe1d6 Revert "Suppress gcc11 clobbered warning"
This reverts commit f0f9e77b65.
2021-06-14 22:07:59 +12:00
Nobuyoshi Nakada
635e1c5282
Pack values to preserve 2021-06-14 14:10:21 +09:00
Nobuyoshi Nakada
f0f9e77b65
Suppress gcc11 clobbered warning 2021-06-14 14:09:43 +09:00
David Rodríguez
02151dad1b $LOAD_PATH.resolve_feature_path should not raise
I think it's more friendly and easier to work with to return `nil` when
the feature is not found in the $LOAD_PATH.
2021-02-16 18:11:13 +09:00
Nobuyoshi Nakada
b72f613210
Suppress a "clobbered" warning by gcc on macOS 2020-12-11 01:17:15 +09:00
Koichi Sasada
182fb73c40 rb_ext_ractor_safe() to declare ractor-safe ext
C extensions can violate the ractor-safety, so only ractor-safe
C extensions (C methods) can run on non-main ractors.
rb_ext_ractor_safe(true) declares that the successive
defined methods are ractor-safe. Otherwiwze, defined methods
checked they are invoked in main ractor and raise an error
if invoked at non-main ractors.

[Feature #17307]
2020-12-01 15:44:18 +09:00
Stefan Stüben
8c2e5bbf58 Don't redefine #rb_intern over and over again 2020-10-21 12:45:18 +09:00
Nobuyoshi Nakada
6944b927bd
rb_class_real never returns Qnil 2020-10-09 11:49:13 +09:00
Jeremy Evans
e1bbb9ea9c Document that Kernel#load will load relative to current directory [ci skip]
Update and format the Kernel#load documentation to separate the
three cases (absolute path, explicit relative path, other), and
also document that it raises LoadError on failure.

Fixes [Bug #16988]
2020-07-09 14:47:13 -07:00
卜部昌平
6575766ea0 search_required: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
卜部昌平
e551dfda9f rb_feature_p: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a
branch is definitely a bad idea.  Better refactor.
2020-06-29 11:05:41 +09:00
MSP-Greg
4cb8b49d41 [DOC] relative filename Kernel#.require and Kernel#.load [ci skip] 2020-06-01 09:20:57 +09:00
Nobuyoshi Nakada
e10798b3a3
[DOC] refined Kernel#.require and Kernel#.load [ci skip] 2020-05-30 22:04:49 +09:00
Nobuyoshi Nakada
0d30f42813
[DOC] mentioned "explicit relative path" [ci skip]
`Kernel#.require` and `Kernel#.load` do not search also "explicit
relative path" files, not only absolute paths, in the load path.
2020-05-30 01:09:16 +09:00
Jeremy Evans
5a9d2da76e Remove deprecated rb_require_safe 2020-04-30 10:32:27 -07:00
Nobuyoshi Nakada
7d6903dc47
Add the loaded feature after no exception raised
Retrying after rescued `require` should try to load the same
library again.  [Bug #16607]
2020-02-04 16:10:39 +09:00
卜部昌平
5e22f873ed decouple internal.h headers
Saves comitters' daily life by avoid #include-ing everything from
internal.h to make each file do so instead.  This would significantly
speed up incremental builds.

We take the following inclusion order in this changeset:

1.  "ruby/config.h", where _GNU_SOURCE is defined (must be the very
    first thing among everything).
2.  RUBY_EXTCONF_H if any.
3.  Standard C headers, sorted alphabetically.
4.  Other system headers, maybe guarded by #ifdef
5.  Everything else, sorted alphabetically.

Exceptions are those win32-related headers, which tend not be self-
containing (headers have inclusion order dependencies).
2019-12-26 20:45:12 +09:00
Nobuyoshi Nakada
14a17063a1
Fixed stack overflow [Bug #16382]
Get rid of infinite recursion in expanding a load path to the real
path while loading a transcoder.
2019-12-03 08:51:50 +09:00
Koichi Sasada
a5fe08fdd9 care about TAG_FATAL.
TAG_FATAL represents interpreter closing state and ec->errinfo
contains FIXNUM (eTerminateSignal, etc). If we need to change the
state, then errinfo is also changed because TAG_RAISE assumes that
ec->errinfo contains a Exception object.

Without this patch, TAG_FATAL is ignored and no ec->errinfo change
so that it causes critical issue.
[Bug #16177]
2019-11-19 16:56:56 +09:00
Jeremy Evans
c5c05460ac Warn on access/modify of $SAFE, and remove effects of modifying $SAFE
This removes the security features added by $SAFE = 1, and warns for access
or modification of $SAFE from Ruby-level, as well as warning when calling
all public C functions related to $SAFE.

This modifies some internal functions that took a safe level argument
to no longer take the argument.

rb_require_safe now warns, rb_require_string has been added as a
version that takes a VALUE and does not warn.

One public C function that still takes a safe level argument and that
this doesn't warn for is rb_eval_cmd.  We may want to consider
adding an alternative method that does not take a safe level argument,
and warn for rb_eval_cmd.
2019-11-18 01:00:25 +02:00
卜部昌平
c9ffe751d1 delete unused functions
Looking at the list of symbols inside of libruby-static.a, I found
hundreds of functions that are defined, but used from nowhere.

There can be reasons for each of them (e.g. some functions are
specific to some platform, some are useful when debugging, etc).
However it seems the functions deleted here exist for no reason.

This changeset reduces the size of ruby binary from 26,671,456
bytes to 26,592,864 bytes on my machine.
2019-11-14 20:35:48 +09:00
卜部昌平
7bcfd9189a drop-in type check for rb_define_global_function
We can check the function pointer passed to rb_define_global_function
like we do so in rb_define_method.  It turns out that almost anybody
is misunderstanding the API.
2019-08-29 18:34:09 +09:00
卜部昌平
1663d347c9 delete $ sign from C identifiers
They lack portability. See also
577164015
2019-08-27 15:52:26 +09:00
卜部昌平
bd8dc2561d struct MEMO now free from ANYARGS
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct.  There is only one usage of
MEMO::u3::func in load.c (where void Init_Foobar(vodi) is registered)
so why not just be explicit.
2019-08-27 15:52:26 +09:00
卜部昌平
ae2dc3f217 rb_define_hooked_variable now free from ANYARGS
After 5e86b005c0, I now think ANYARGS is
dangerous and should be extinct.  This commit uses rb_gvar_getter_t /
rb_gvar_setter_t for rb_define_hooked_variable /
rb_define_virtual_variable which revealed lots of function prototype
inconsistencies.  Some of them were literally decades old, going back
to dda5dc00cf.
2019-08-27 15:52:26 +09:00
Nobuyoshi Nakada
74ca6b88dd
Omit a tag unless loading with a wrapper module 2019-08-18 00:34:12 +09:00