summaryrefslogtreecommitdiff
path: root/include/ruby
AgeCommit message (Collapse)Author
2024-10-23Fix false warning by gcc 14 for aarch64Nobuyoshi Nakada
gcc 14 for aarch64 with `-O3` may emit a false positive warning for a pointer access of `RB_BUILTIN_TYPE` called from `RB_TYPE_P`. `Qfalse` shouldn't get there because of `RB_SPECIAL_CONST_P`, but the optimizer seems to ignore this condition in some cases (`ASSUME` just before the access doesn't seem to have any effect either). Only by reversing the order in `RB_SPECIAL_CONST_P` to compare with 0 first does the warning seem to go away. Notes: Merged: https://github.com/ruby/ruby/pull/11928
2024-10-08Cast via `uintptr_t` function pointer between object pointerNobuyoshi Nakada
- ISO C forbids conversion of function pointer to object pointer type - ISO C forbids conversion of object pointer to function pointer type
2024-10-04Better handling of timeout in `rb_io_maybe_wait_*`. (#9531)Samuel Williams
Notes: Merged-By: ioquatix <samuel@codeotaku.com>
2024-10-04Clarify `rb_io_maybe_wait` behaviour. (#9527)Samuel Williams
Notes: Merged-By: ioquatix <samuel@codeotaku.com>
2024-09-24fix rb_memsearch() documentNAITOH Jun
## Why? The explanation of x and y is reversed. https://github.com/ruby/ruby/blob/ddbd64400199fd408d23c85f9fb0d7f742ecf9e1/re.c#L251-L256 ``` long rb_memsearch(const void *x0, long m, const void *y0, long n, rb_encoding *enc) { const unsigned char *x = x0, *y = y0; if (m > n) return -1; ``` Notes: Merged: https://github.com/ruby/ruby/pull/11625
2024-08-28[DOC] Mention rb_io_fdopen() takes ownership of the FDAlan Wu
2024-08-11Fix sign-conversion warningNobuyoshi Nakada
``` ../../.././include/ruby/internal/special_consts.h:349:36: error: conversion to ‘VALUE’ {aka ‘long unsigned int’} from ‘int’ may change the sign of the result [-Werror=sign-conversion] 349 | return RB_SPECIAL_CONST_P(obj) * RUBY_Qtrue; | ~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~ ```
2024-07-25Fix memory leak in Regexp capture group when timeoutPeter Zhu
[Bug #20650] The capture group allocates memory that is leaked when it times out. For example: re = Regexp.new("^#{"(a*)" * 10_000}x$", timeout: 0.000001) str = "a" * 1000000 + "x" 10.times do 100.times do re =~ str rescue Regexp::TimeoutError end puts `ps -o rss= -p #{$$}` end Before: 34688 56416 78288 100368 120784 140704 161904 183568 204320 224800 After: 16288 16288 16880 16896 16912 16928 16944 17184 17184 17200 Notes: Merged: https://github.com/ruby/ruby/pull/11238
2024-07-19Make rb_check_frozen_inline() static inline againAlan Wu
Since 730e3b2ce01915c4a98b79bb281b2c38a9ff1131 ("Stop exposing `rb_str_chilled_p`"), we noticed a speed loss on a few benchmarks that are string operations heavy. This is partially due to routines no longer having the options to inline rb_check_frozen_inline() in non-LTO builds. Make it an inlining candidate again to recover speed. Testing this patch on my machine, the fannkuchredux benchmark gets a 1.15 speed-up with YJIT and 1.03 without YJIT. Notes: Merged: https://github.com/ruby/ruby/pull/11211
2024-07-17[DOC] Note that rb_obj_freeze_inline() can raise NoMemoryErrorAlan Wu
And move it back to a public header because Doxygen might not be scanning the .c files. [Feature #18776] Notes: Merged: https://github.com/ruby/ruby/pull/11179
2024-07-17[DOC] No more is rb_ary_freeze() an alias of rb_obj_freeze()Alan Wu
[Feature #20589] Notes: Merged: https://github.com/ruby/ruby/pull/11179
2024-07-12give up USE_GC_MALLOC_OBJ_INFO_DETAILS卜部昌平
This feature is no longer possible under current design; now that our GC is pluggable, we cannot assume what was achieved by this compiler flag is always possble by the dynamically-loaded GC implementation.
2024-07-10Add rb_block_call2, a flexible variant of rb_block_callYusuke Endoh
This function accepts flags: RB_NO_KEYWORDS, RB_PASS_KEYWORDS, RB_PASS_CALLED_KEYWORDS: Works as the same as rb_block_call_kw. RB_BLOCK_NO_USE_PACKED_ARGS: The given block ("bl_proc") does not use "yielded_arg" of rb_block_call_func_t. Instead, the block accesses the yielded arguments via "argc" and "argv". This flag allows the called method to yield arguments without allocating an Array.
2024-06-21Show more in `RBIMPL_ASSERT_TYPE`Nobuyoshi Nakada
2024-06-21Delegate from `RBIMPL_ASSERT_OR_ASSUME` to `RUBY_ASSERT_ALWAYS`Nobuyoshi Nakada
Get rid of expansion of the argument which often contains complicated macros, and simplify the failure message.
2024-06-13Crash instead of raising with Check_Type() in RBIMPL_ASSERT_TYPE() in debug ↵Alan Wu
builds Previously, RBIMPL_ASSERT_TYPE() used Check_Type() only in RUBY_DEBUG builds. It raised TypeError, but only in debug builds. For people testing type mismatch using debug builds looking for a Ruby exception, this can be misleading -- the code could be missing a type check in non-debug builds if it is relying on for example RSTRING_LEN() to raise. Also, Check_Type() can obscure the true cause of error in debug mode. When type check fails because the object is corrupt, instead of crashing with a clear type assertion message, it can crash while trying to construct an exception object to raise. You can see this for example in <https://github.com/ruby/ruby/actions/runs/9489999591/job/26152506434?pr=10985>, where RB_ENCODING_GET() is used on a corrupt object, but the crash happens later and says "Assertion Failed: ../src/vm_method.c:1477:callable_method_entry_or_negative". RBIMPL_ASSERT_TYPE() should assert right away. RBIMPL_ASSERT_OR_ASSUME() asserts when RUBY_DEBUG and assumes in release builds, as desired. This should help investigate flaky CI failures that show up as TypeError from `Kernel#require`, e.g. "'Kernel#require': wrong argument type false (expected String) (TypeError)". Same CI failure examples: - https://github.com/ruby/ruby/actions/runs/9034787861/job/24828147431 - https://github.com/ruby/ruby/actions/runs/9418303667/job/25945492440 - https://github.com/ruby/ruby/actions/runs/9505650952/job/26201031314 The failure occurs with and without use of YJIT.
2024-06-07Cast `RUBY_ATOMIC_PTR_CAS` argumentsNobuyoshi Nakada
As well as `RUBY_ATOMIC_PTR_EXCHANGE` and `RUBY_ATOMIC_PTR_LOAD`.
2024-06-06Mark old Data API as deprecatedJean Boussier
[Feature #19998]
2024-06-02Stop exposing `rb_str_chilled_p`Jean Boussier
[Feature #20205] Now that chilled strings no longer appear as frozen, there is no need to offer an API to check for chilled strings. We however need to change `rb_check_frozen_internal` to no longer be a macro, as it needs to check for chilled strings.
2024-05-28Make value_type.h compatible with -WconversionJean Boussier
[Feature #20507] This was missed from the initial commit. ``` ../../.././include/ruby/internal/value_type.h:446:27: error: implicit conversion changes signedness: 'enum ruby_value_type' to 'int' [-Werror,-Wsign-conversion] rb_unexpected_type(v, t); ~~~~~~~~~~~~~~~~~~ ^ ```
2024-05-28Allow compilation of C extensions with `-Wconversion`Mike Dalessio
C extension maintainers can now compile with this warning option and the Ruby header files will generate no warnings. [Feature #20507]
2024-05-28Stop marking chilled strings as frozenÉtienne Barrié
They were initially made frozen to avoid false positives for cases such as: str = str.dup if str.frozen? But this may cause bugs and is generally confusing for users. [Feature #20205] Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
2024-04-29suppress -Wold-style-cast warnings卜部昌平
2024-04-29workaround C++ compile error卜部昌平
We observe compiler error on FreeBSD. Their stdckdint.h does not understand C++. This shall be addressed on their side. Unti then we resport to our own version. https://rubyci.s3.amazonaws.com/freebsd14/ruby-master/log/20240427T143002Z.log.html.gz
2024-04-27use of stdckdint.h卜部昌平
C23 is going to have this header. The industry is already moving towards accepting it; OSes and compilers started to implement theirs. Why not detect its presence and if any, prefer over other ways. See also: - https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2683.pdf - https://reviews.freebsd.org/D41734 - https://reviews.llvm.org/D157331 - https://gcc.gnu.org/git/?p=gcc.git;a=commit;h=8441841a1b985d68245954af1ff023db121b0635
2024-04-19Refer autoconfigured endian macro (#10572)Nobuyoshi Nakada
Remove the case `RB_IO_BUFFER_HOST_ENDIAN` is not defined.
2024-04-18Include coderange.h in encoding.hPeter Zhu
ruby_coderange_type is defined in ruby/internal/encoding/coderange.h so we need to include it.
2024-04-16RB_OBJ_FREEZE_RAW: Set the object shapeJean Boussier
2024-04-11put empty `rb_gc_force_recycle()`Koichi Sasada
and declare it will be removed soon. ddtrace is still referes the API and build was failed. See https://github.com/DataDog/dd-trace-rb/pull/3578 Maybe threre are only few users of this C-API now so we can remove it soon.
2024-04-08Add builtin type assertionNobuyoshi Nakada
2024-04-05Remove deprecated function rb_gc_force_recyclePeter Zhu
This function has been deprecated since Ruby 3.1, so we should remove it for Ruby 3.4.
2024-03-27[DOC] remove repetitive words in commentscrazeteam
Signed-off-by: crazeteam <lilujing@outlook.com>
2024-03-26Expose rb_str_chilled_pÉtienne Barrié
Some extensions (like stringio) may need to differentiate between chilled strings and frozen strings. They can now use rb_str_chilled_p but must check for its presence since the function will be removed when chilled strings are removed. [Bug #20389] [Feature #20205] Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
2024-03-23[DOC] Small edits in rbasic.hXavier Noria
2024-03-22Revert "Hide public implementation of `rb_io`. (#9568)" (#10283)Samuel Williams
This reverts commit 9ab1fa3bf570bf19b0d6808adf12e965aacc6d83.
2024-03-19Implement chilled stringsÉtienne Barrié
[Feature #20205] As a path toward enabling frozen string literals by default in the future, this commit introduce "chilled strings". From a user perspective chilled strings pretend to be frozen, but on the first attempt to mutate them, they lose their frozen status and emit a warning rather than to raise a `FrozenError`. Implementation wise, `rb_compile_option_struct.frozen_string_literal` is no longer a boolean but a tri-state of `enabled/disabled/unset`. When code is compiled with frozen string literals neither explictly enabled or disabled, string literals are compiled with a new `putchilledstring` instruction. This instruction is identical to `putstring` except it marks the String with the `STR_CHILLED (FL_USER3)` and `FL_FREEZE` flags. Chilled strings have the `FL_FREEZE` flag as to minimize the need to check for chilled strings across the codebase, and to improve compatibility with C extensions. Notes: - `String#freeze`: clears the chilled flag. - `String#-@`: acts as if the string was mutable. - `String#+@`: acts as if the string was mutable. - `String#clone`: copies the chilled flag. Co-authored-by: Jean Boussier <byroot@ruby-lang.org>
2024-03-14[Feature #20265] Remove rb_newobj_of and RB_NEWOBJ_OFPeter Zhu
2024-03-14[Feature #20265] Remove rb_newobj and RB_NEWOBJPeter Zhu
2024-03-14[Feature #20306] Implement ruby_free_at_exit_pPeter Zhu
ruby_free_at_exit_p is a way for extensions to determine whether they should free all memory at shutdown.
2024-03-06Move FL_SINGLETON to FL_USER1Jean Boussier
This frees FL_USER0 on both T_MODULE and T_CLASS. Note: prior to this, FL_SINGLETON was never set on T_MODULE, so checking for `FL_SINGLETON` without first checking that `FL_TYPE` was `T_CLASS` was valid. That's no longer the case.
2024-03-06Hide public implementation of `rb_io`. (#9568)Samuel Williams
Remove `struct rb_io {...}`.
2024-03-05[DOC] fix some commentscui fliter
Signed-off-by: cui fliter <imcusg@gmail.com>
2024-03-01Clarify C API documentation about pinned classesJean Boussier
They are not only pinned, but also immortal. Even if the constant referencing them is removed, they will remain alive. It's a precision worth noting.
2024-02-26Revise 9ec342e07df6aa5e2c2e9003517753a2f1b508fdNobuyoshi Nakada
2024-02-26[Bug #20296] Fix the default assertion messageNobuyoshi Nakada
2024-02-26Introduction of Happy Eyeballs Version 2 (RFC8305) in Socket.tcp (#9374)Misaki Shioi
* Introduction of Happy Eyeballs Version 2 (RFC8305) in Socket.tcp This is an implementation of Happy Eyeballs version 2 (RFC 8305) in Socket.tcp. [Background] Currently, `Socket.tcp` synchronously resolves names and makes connection attempts with `Addrinfo::foreach.` This implementation has the following two problems. 1. In name resolution, the program stops until the DNS server responds to all DNS queries. 2. In a connection attempt, while an IP address is trying to connect to the destination host and is taking time, the program stops, and other resolved IP addresses cannot try to connect. [Proposal] "Happy Eyeballs" ([RFC 8305](https://datatracker.ietf.org/doc/html/rfc8305)) is an algorithm to solve this kind of problem. It avoids delays to the user whenever possible and also uses IPv6 preferentially. I implemented it into `Socket.tcp` by using `Addrinfo.getaddrinfo` in each thread spawned per address family to resolve the hostname asynchronously, and using `Socket::connect_nonblock` to try to connect with multiple addrinfo in parallel. [Outcome] This change eliminates a fatal defect in the following cases. Case 1. One of the A or AAAA DNS queries does not return --- require 'socket' class Addrinfo class << self # Current Socket.tcp depends on foreach def foreach(nodename, service, family=nil, socktype=nil, protocol=nil, flags=nil, timeout: nil, &block) getaddrinfo(nodename, service, Socket::AF_INET6, socktype, protocol, flags, timeout: timeout) .concat(getaddrinfo(nodename, service, Socket::AF_INET, socktype, protocol, flags, timeout: timeout)) .each(&block) end def getaddrinfo(_, _, family, *_) case family when Socket::AF_INET6 then sleep when Socket::AF_INET then [Addrinfo.tcp("127.0.0.1", 4567)] end end end end Socket.tcp("localhost", 4567) --- Because the current `Socket.tcp` cannot resolve IPv6 names, the program stops in this case. It cannot start to connect with IPv4 address. Though `Socket.tcp` with HEv2 can promptly start a connection attempt with IPv4 address in this case. Case 2. Server does not promptly return ack for syn of either IPv4 / IPv6 address family --- require 'socket' fork do socket = Socket.new(Socket::AF_INET6, :STREAM) socket.setsockopt(:SOCKET, :REUSEADDR, true) socket.bind(Socket.pack_sockaddr_in(4567, '::1')) sleep socket.listen(1) connection, _ = socket.accept connection.close socket.close end fork do socket = Socket.new(Socket::AF_INET, :STREAM) socket.setsockopt(:SOCKET, :REUSEADDR, true) socket.bind(Socket.pack_sockaddr_in(4567, '127.0.0.1')) socket.listen(1) connection, _ = socket.accept connection.close socket.close end Socket.tcp("localhost", 4567) --- The current `Socket.tcp` tries to connect serially, so when its first name resolves an IPv6 address and initiates a connection to an IPv6 server, this server does not return an ACK, and the program stops. Though `Socket.tcp` with HEv2 starts to connect sequentially and in parallel so a connection can be established promptly at the socket that attempted to connect to the IPv4 server. In exchange, the performance of `Socket.tcp` with HEv2 will be degraded. --- 100.times { Socket.tcp("www.ruby-lang.org", 80) } --- This is due to the addition of the creation of IO objects, Thread objects, etc., and calls to `IO::select` in the implementation. * Avoid NameError of Socket::EAI_ADDRFAMILY in MinGW * Support Windows with SO_CONNECT_TIME * Improve performance I have additionally implemented the following patterns: - If the host is single-stack, name resolution is performed in the main thread. This reduces the cost of creating threads. - If an IP address is specified, name resolution is performed in the main thread. This also reduces the cost of creating threads. - If only one IP address is resolved, connect is executed in blocking mode. This reduces the cost of calling IO::select. Also, I have added a fast_fallback option for users who wish not to use HE. Here are the results of each performance test. ```ruby require 'socket' require 'benchmark' HOSTNAME = "www.ruby-lang.org" PORT = 80 ai = Addrinfo.tcp(HOSTNAME, PORT) Benchmark.bmbm do |x| x.report("Domain name") do 30.times { Socket.tcp(HOSTNAME, PORT).close } end x.report("IP Address") do 30.times { Socket.tcp(ai.ip_address, PORT).close } end x.report("fast_fallback: false") do 30.times { Socket.tcp(HOSTNAME, PORT, fast_fallback: false).close } end end ``` ``` user system total real Domain name 0.015567 0.032511 0.048078 ( 0.325284) IP Address 0.004458 0.014219 0.018677 ( 0.284361) fast_fallback: false 0.005869 0.021511 0.027380 ( 0.321891) ```` And this is the measurement result when executed in a single stack environment. ``` user system total real Domain name 0.007062 0.019276 0.026338 ( 1.905775) IP Address 0.004527 0.012176 0.016703 ( 3.051192) fast_fallback: false 0.005546 0.019426 0.024972 ( 1.775798) ``` The following is the result of the run on Ruby 3.3.0. (on Dual stack environment) ``` user system total real Ruby 3.3.0 0.007271 0.027410 0.034681 ( 0.472510) ``` (on Single stack environment) ``` user system total real Ruby 3.3.0 0.005353 0.018898 0.024251 ( 1.774535) ``` * Do not cache `Socket.ip_address_list` As mentioned in the comment at https://github.com/ruby/ruby/pull/9374#discussion_r1482269186, caching Socket.ip_address_list does not follow changes in network configuration. But if we stop caching, it becomes necessary to check every time `Socket.tcp` is called whether it's a single stack or not, which could further degrade performance in the case of a dual stack. From this, I've changed the approach so that when a domain name is passed, it doesn't check whether it's a single stack or not and resolves names in parallel each time. The performance measurement results are as follows. require 'socket' require 'benchmark' HOSTNAME = "www.ruby-lang.org" PORT = 80 ai = Addrinfo.tcp(HOSTNAME, PORT) Benchmark.bmbm do |x| x.report("Domain name") do 30.times { Socket.tcp(HOSTNAME, PORT).close } end x.report("IP Address") do 30.times { Socket.tcp(ai.ip_address, PORT).close } end x.report("fast_fallback: false") do 30.times { Socket.tcp(HOSTNAME, PORT, fast_fallback: false).close } end end user system total real Domain name 0.004085 0.011873 0.015958 ( 0.330097) IP Address 0.000993 0.004400 0.005393 ( 0.257286) fast_fallback: false 0.001348 0.008266 0.009614 ( 0.298626) * Wait forever if fallback addresses are unresolved, unless resolv_timeout Changed from waiting only 3 seconds for name resolution when there is no fallback address available, to waiting as long as there is no resolv_timeout. This is in accordance with the current `Socket.tcp` specification. * Use exact pattern to match IPv6 address format for specify address family
2024-02-21`rb_thread_lock_native_thread()`Koichi Sasada
Introduce `rb_thread_lock_native_thread()` to allocate dedicated native thread to the current Ruby thread for M:N threads. This C API is similar to Go's `runtime.LockOSThread()`. Accepted at https://github.com/ruby/dev-meeting-log/blob/master/2023/DevMeeting-2023-08-24.md (and missed to implement on Ruby 3.3.0)
2024-02-11Win32: Fix pre-defined macros for platformsNobuyoshi Nakada
Use `_WIN64` for word-size, `_M_AMD64` for CPU-specific feature.
2024-02-08Extract `RBIMPL_VA_OPT_ARGS`Nobuyoshi Nakada
Similar to splat argument in Ruby, which be expanded to `__VA_ARGS__` with a leading comma if any arguments given, otherwise empty.
2024-02-08Optional detail info at assertion failureNobuyoshi Nakada