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-3
  • Loading branch information
rm155 committed Sep 5, 2024
2 parents fc1ca87 + f250296 commit db237cb
Show file tree
Hide file tree
Showing 40 changed files with 1,065 additions and 343 deletions.
4 changes: 2 additions & 2 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ The following default gems are updated.
* optparse 0.5.0
* prism 1.0.0
* rdoc 6.7.0
* reline 0.5.9
* reline 0.5.10
* resolv 0.4.0
* stringio 3.1.2.dev
* strscan 3.1.1.dev
Expand All @@ -95,7 +95,7 @@ The following bundled gems are updated.
* rexml 3.3.7
* rss 0.3.1
* net-ftp 0.3.7
* net-imap 0.4.15
* net-imap 0.4.16
* net-smtp 0.5.0
* rbs 3.5.3
* typeprof 0.21.11
Expand Down
4 changes: 4 additions & 0 deletions array.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include "ruby_assert.h"

VALUE rb_cArray;
VALUE rb_cArray_empty_frozen;

/* Flags of RArray
*
Expand Down Expand Up @@ -8839,6 +8840,9 @@ Init_Array(void)
rb_define_method(rb_cArray, "freeze", rb_ary_freeze, 0);

rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0);

rb_cArray_empty_frozen = rb_ary_freeze(rb_ary_new());
rb_vm_register_global_object(rb_cArray_empty_frozen);
}

#include "array.rbinc"
8 changes: 8 additions & 0 deletions ast.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,14 @@ node_locations(VALUE ast_value, const NODE *node)
return rb_ary_new_from_args(2,
location_new(nd_code_loc(node)),
location_new(&RNODE_ALIAS(node)->keyword_loc));
case NODE_AND:
return rb_ary_new_from_args(2,
location_new(nd_code_loc(node)),
location_new(&RNODE_AND(node)->operator_loc));
case NODE_OR:
return rb_ary_new_from_args(2,
location_new(nd_code_loc(node)),
location_new(&RNODE_OR(node)->operator_loc));
case NODE_UNDEF:
return rb_ary_new_from_args(2,
location_new(nd_code_loc(node)),
Expand Down
23 changes: 23 additions & 0 deletions benchmark/time_xmlschema.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
prelude: |
# frozen_string_literal
unless Time.method_defined?(:xmlschema)
class Time
def xmlschema(fraction_digits=0)
fraction_digits = fraction_digits.to_i
s = strftime("%FT%T")
if fraction_digits > 0
s << strftime(".%#{fraction_digits}N")
end
s << (utc? ? 'Z' : strftime("%:z"))
end
end
end
time = Time.now
utc_time = Time.now.utc
benchmark:
- time.xmlschema
- utc_time.xmlschema
- time.xmlschema(6)
- utc_time.xmlschema(6)
- time.xmlschema(9)
- utc_time.xmlschema(9)
102 changes: 100 additions & 2 deletions compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -3236,6 +3236,8 @@ ci_argc_set(const rb_iseq_t *iseq, const struct rb_callinfo *ci, int argc)
return nci;
}

#define vm_ci_simple(ci) (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE)

static int
iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt)
{
Expand Down Expand Up @@ -3402,6 +3404,104 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal
}
}

/*
* duparray [...]
* send <calldata!mid:freeze, argc:0, ARGS_SIMPLE>, nil
* =>
* opt_ary_freeze [...], <calldata!mid:freeze, argc:0, ARGS_SIMPLE>
*/
if (IS_INSN_ID(iobj, duparray)) {
LINK_ELEMENT *next = iobj->link.next;
if (IS_INSN(next) && (IS_INSN_ID(next, send))) {
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(next, 0);
const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(next, 1);

if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && blockiseq == NULL && vm_ci_mid(ci) == idFreeze) {
VALUE ary = iobj->operands[0];
rb_obj_reveal(ary, rb_cArray);

iobj->insn_id = BIN(opt_ary_freeze);
iobj->operand_size = 2;
iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE));
iobj->operands[0] = ary;
iobj->operands[1] = (VALUE)ci;
ELEM_REMOVE(next);
}
}
}

/*
* duphash {...}
* send <calldata!mid:freeze, argc:0, ARGS_SIMPLE>, nil
* =>
* opt_hash_freeze {...}, <calldata!mid:freeze, argc:0, ARGS_SIMPLE>
*/
if (IS_INSN_ID(iobj, duphash)) {
LINK_ELEMENT *next = iobj->link.next;
if (IS_INSN(next) && (IS_INSN_ID(next, send))) {
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(next, 0);
const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(next, 1);

if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && blockiseq == NULL && vm_ci_mid(ci) == idFreeze) {
VALUE hash = iobj->operands[0];
rb_obj_reveal(hash, rb_cHash);

iobj->insn_id = BIN(opt_hash_freeze);
iobj->operand_size = 2;
iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE));
iobj->operands[0] = hash;
iobj->operands[1] = (VALUE)ci;
ELEM_REMOVE(next);
}
}
}

/*
* newarray 0
* send <calldata!mid:freeze, argc:0, ARGS_SIMPLE>, nil
* =>
* opt_ary_freeze [], <calldata!mid:freeze, argc:0, ARGS_SIMPLE>
*/
if (IS_INSN_ID(iobj, newarray) && iobj->operands[0] == INT2FIX(0)) {
LINK_ELEMENT *next = iobj->link.next;
if (IS_INSN(next) && (IS_INSN_ID(next, send))) {
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(next, 0);
const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(next, 1);

if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && blockiseq == NULL && vm_ci_mid(ci) == idFreeze) {
iobj->insn_id = BIN(opt_ary_freeze);
iobj->operand_size = 2;
iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE));
iobj->operands[0] = rb_cArray_empty_frozen;
iobj->operands[1] = (VALUE)ci;
ELEM_REMOVE(next);
}
}
}

/*
* newhash 0
* send <calldata!mid:freeze, argc:0, ARGS_SIMPLE>, nil
* =>
* opt_hash_freeze {}, <calldata!mid:freeze, argc:0, ARGS_SIMPLE>
*/
if (IS_INSN_ID(iobj, newhash) && iobj->operands[0] == INT2FIX(0)) {
LINK_ELEMENT *next = iobj->link.next;
if (IS_INSN(next) && (IS_INSN_ID(next, send))) {
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(next, 0);
const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(next, 1);

if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && blockiseq == NULL && vm_ci_mid(ci) == idFreeze) {
iobj->insn_id = BIN(opt_hash_freeze);
iobj->operand_size = 2;
iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE));
iobj->operands[0] = rb_cHash_empty_frozen;
iobj->operands[1] = (VALUE)ci;
ELEM_REMOVE(next);
}
}
}

if (IS_INSN_ID(iobj, branchif) ||
IS_INSN_ID(iobj, branchnil) ||
IS_INSN_ID(iobj, branchunless)) {
Expand Down Expand Up @@ -3987,8 +4087,6 @@ insn_set_specialized_instruction(rb_iseq_t *iseq, INSN *iobj, int insn_id)
return COMPILE_OK;
}

#define vm_ci_simple(ci) (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE)

static int
iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj)
{
Expand Down
16 changes: 14 additions & 2 deletions ext/socket/raddrinfo.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,12 @@ nogvl_getaddrinfo(void *arg)
return (void *)(VALUE)ret;
}

static void *
fork_safe_getaddrinfo(void *arg)
{
return rb_thread_prevent_fork(nogvl_getaddrinfo, arg);
}

static int
rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai)
{
Expand All @@ -336,7 +342,7 @@ rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hint
arg.service = portp;
arg.hints = hints;
arg.res = ai;
return (int)(VALUE)rb_thread_call_without_gvl(nogvl_getaddrinfo, &arg, RUBY_UBF_IO, 0);
return (int)(VALUE)rb_thread_call_without_gvl(fork_safe_getaddrinfo, &arg, RUBY_UBF_IO, 0);
}

#elif GETADDRINFO_IMPL == 2
Expand Down Expand Up @@ -477,6 +483,12 @@ do_pthread_create(pthread_t *th, void *(*start_routine) (void *), void *arg)
return ret;
}

static void *
fork_safe_do_getaddrinfo(void *ptr)
{
return rb_thread_prevent_fork(do_getaddrinfo, ptr);
}

static int
rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hints, struct addrinfo **ai)
{
Expand All @@ -493,7 +505,7 @@ rb_getaddrinfo(const char *hostp, const char *portp, const struct addrinfo *hint
}

pthread_t th;
if (do_pthread_create(&th, do_getaddrinfo, arg) != 0) {
if (do_pthread_create(&th, fork_safe_do_getaddrinfo, arg) != 0) {
int err = errno;
free_getaddrinfo_arg(arg);
errno = err;
Expand Down
2 changes: 1 addition & 1 deletion gems/bundled_gems
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ test-unit 3.6.2 https://github.com/test-unit/test-unit
rexml 3.3.7 https://github.com/ruby/rexml
rss 0.3.1 https://github.com/ruby/rss
net-ftp 0.3.7 https://github.com/ruby/net-ftp
net-imap 0.4.15 https://github.com/ruby/net-imap
net-imap 0.4.16 https://github.com/ruby/net-imap
net-pop 0.1.2 https://github.com/ruby/net-pop
net-smtp 0.5.0 https://github.com/ruby/net-smtp
matrix 0.4.2 https://github.com/ruby/matrix
Expand Down
6 changes: 6 additions & 0 deletions hash.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,13 +104,15 @@ static VALUE rb_hash_s_try_convert(VALUE, VALUE);
* 2. Insert WBs
*/

/* :nodoc: */
VALUE
rb_hash_freeze(VALUE hash)
{
return rb_obj_freeze(hash);
}

VALUE rb_cHash;
VALUE rb_cHash_empty_frozen;

static VALUE envtbl;
static ID id_hash, id_flatten_bang;
Expand Down Expand Up @@ -7119,6 +7121,7 @@ Init_Hash(void)
rb_define_singleton_method(rb_cHash, "try_convert", rb_hash_s_try_convert, 1);
rb_define_method(rb_cHash, "initialize_copy", rb_hash_replace, 1);
rb_define_method(rb_cHash, "rehash", rb_hash_rehash, 0);
rb_define_method(rb_cHash, "freeze", rb_hash_freeze, 0);

rb_define_method(rb_cHash, "to_hash", rb_hash_to_hash, 0);
rb_define_method(rb_cHash, "to_h", rb_hash_to_h, 0);
Expand Down Expand Up @@ -7205,6 +7208,9 @@ Init_Hash(void)
rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash?", rb_hash_s_ruby2_keywords_hash_p, 1);
rb_define_singleton_method(rb_cHash, "ruby2_keywords_hash", rb_hash_s_ruby2_keywords_hash, 1);

rb_cHash_empty_frozen = rb_hash_freeze(rb_hash_new());
rb_vm_register_global_object(rb_cHash_empty_frozen);

/* Document-class: ENV
*
* +ENV+ is a hash-like accessor for environment variables.
Expand Down
30 changes: 30 additions & 0 deletions insns.def
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,36 @@ objtostring
}
}

DEFINE_INSN
opt_ary_freeze
(VALUE ary, CALL_DATA cd)
()
(VALUE val)
{
val = vm_opt_ary_freeze(ary, BOP_FREEZE, idFreeze);

if (UNDEF_P(val)) {
RUBY_DTRACE_CREATE_HOOK(ARRAY, RARRAY_LEN(ary));
PUSH(rb_ary_resurrect(ary));
CALL_SIMPLE_METHOD();
}
}

DEFINE_INSN
opt_hash_freeze
(VALUE hash, CALL_DATA cd)
()
(VALUE val)
{
val = vm_opt_hash_freeze(hash, BOP_FREEZE, idFreeze);

if (UNDEF_P(val)) {
RUBY_DTRACE_CREATE_HOOK(HASH, RHASH_SIZE(hash) << 1);
PUSH(rb_hash_resurrect(hash));
CALL_SIMPLE_METHOD();
}
}

DEFINE_INSN
opt_str_freeze
(VALUE str, CALL_DATA cd)
Expand Down
1 change: 1 addition & 0 deletions internal/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ size_t rb_ary_size_as_embedded(VALUE ary);
void rb_ary_make_embedded(VALUE ary);
bool rb_ary_embeddable_p(VALUE ary);
VALUE rb_ary_diff(VALUE ary1, VALUE ary2);
RUBY_EXTERN VALUE rb_cArray_empty_frozen;

static inline VALUE rb_ary_entry_internal(VALUE ary, long offset);
static inline bool ARY_PTR_USING_P(VALUE ary);
Expand Down
1 change: 1 addition & 0 deletions internal/hash.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_fu
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
VALUE rb_ident_hash_new_with_size(st_index_t size);
void rb_hash_free(VALUE hash);
RUBY_EXTERN VALUE rb_cHash_empty_frozen;

static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
static inline VALUE RHASH_IFNONE(VALUE h);
Expand Down
5 changes: 5 additions & 0 deletions internal/thread.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ VALUE rb_thread_shield_wait(VALUE self);
VALUE rb_thread_shield_release(VALUE self);
VALUE rb_thread_shield_destroy(VALUE self);
int rb_thread_to_be_killed(VALUE thread);
void rb_thread_acquire_fork_lock(void);
void rb_thread_release_fork_lock(void);
void rb_thread_reset_fork_lock(void);
void rb_mutex_allow_trap(VALUE self, int val);
VALUE rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data);
VALUE rb_mutex_owned_p(VALUE self);
Expand All @@ -64,6 +67,8 @@ void rb_notify_fd_close_wait(struct rb_io_close_wait_list *busy);

RUBY_SYMBOL_EXPORT_BEGIN

void *rb_thread_prevent_fork(void *(*func)(void *), void *data); /* for ext/socket/raddrinfo.c */

/* Temporary. This API will be removed (renamed). */
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
VALUE rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, int events);
Expand Down
Loading

0 comments on commit db237cb

Please sign in to comment.