diff --git a/array.c b/array.c index ed9c5ce4d06885..e760176176ae61 100644 --- a/array.c +++ b/array.c @@ -6920,7 +6920,7 @@ static const rb_data_type_t ary_sample_memo_type = { .function = { .dfree = (RUBY_DATA_FUNC)st_free_table, }, - .flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY + .flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_THREAD_SAFE_FREE }; static VALUE diff --git a/ast.c b/ast.c index 1ddc2b5791550e..9a1c08dad79982 100644 --- a/ast.c +++ b/ast.c @@ -45,7 +45,7 @@ static const rb_data_type_t rb_node_type = { "AST/node", {node_gc_mark, RUBY_TYPED_DEFAULT_FREE, node_memsize,}, 0, 0, - RUBY_TYPED_FREE_IMMEDIATELY, + RUBY_TYPED_THREAD_SAFE_FREE, }; struct ASTLocationData { @@ -70,7 +70,7 @@ static const rb_data_type_t rb_location_type = { "AST/location", {location_gc_mark, RUBY_TYPED_DEFAULT_FREE, location_memsize,}, 0, 0, - RUBY_TYPED_FREE_IMMEDIATELY, + RUBY_TYPED_THREAD_SAFE_FREE, }; diff --git a/box.c b/box.c index 0ca7838be96045..b6f52a66b69530 100644 --- a/box.c +++ b/box.c @@ -339,7 +339,7 @@ static const rb_data_type_t rb_master_box_data_type = { box_entry_memsize, rb_box_gc_update_references, }, - &rb_box_data_type, 0, RUBY_TYPED_FREE_IMMEDIATELY // TODO: enable RUBY_TYPED_WB_PROTECTED when inserting write barriers + &rb_box_data_type, 0, RUBY_TYPED_THREAD_SAFE_FREE // TODO: enable RUBY_TYPED_WB_PROTECTED when inserting write barriers }; VALUE diff --git a/compile.c b/compile.c index 801c768dffb12c..cbf00c9da113b8 100644 --- a/compile.c +++ b/compile.c @@ -12376,7 +12376,7 @@ static const rb_data_type_t labels_wrapper_type = { .dmark = (RUBY_DATA_FUNC)rb_mark_set, .dfree = (RUBY_DATA_FUNC)st_free_table, }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED, }; void @@ -12637,7 +12637,7 @@ static const rb_data_type_t pinned_list_type = { RUBY_DEFAULT_FREE, NULL, // No external memory to report, }, - 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_EMBEDDABLE }; static VALUE @@ -14821,7 +14821,7 @@ ibf_dump_memsize(const void *ptr) static const rb_data_type_t ibf_dump_type = { "ibf_dump", {ibf_dump_mark, ibf_dump_free, ibf_dump_memsize,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_EMBEDDABLE }; static void @@ -15058,7 +15058,7 @@ ibf_loader_memsize(const void *ptr) static const rb_data_type_t ibf_load_type = { "ibf_loader", {ibf_loader_mark, ibf_loader_free, ibf_loader_memsize,}, - 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_THREAD_SAFE_FREE }; const rb_iseq_t * diff --git a/concurrent_set.c b/concurrent_set.c index 42a5bfe8da2f8f..42ff6ef43f799e 100644 --- a/concurrent_set.c +++ b/concurrent_set.c @@ -91,7 +91,7 @@ static const rb_data_type_t concurrent_set_type = { .dsize = concurrent_set_size, }, /* Hack: NOT WB_PROTECTED on purpose (see above) */ - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_EMBEDDABLE }; VALUE diff --git a/dir.c b/dir.c index 389bdb2b4c574b..b1e4f1edb01d16 100644 --- a/dir.c +++ b/dir.c @@ -545,7 +545,7 @@ static const rb_data_type_t dir_data_type = { dir_free, NULL, // Nothing allocated externally, so don't need a memsize function }, - 0, NULL, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE + 0, NULL, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE }; static VALUE dir_close(VALUE); diff --git a/encoding.c b/encoding.c index c17f118eef3f33..581746e8a636ea 100644 --- a/encoding.c +++ b/encoding.c @@ -123,7 +123,7 @@ static rb_atomic_t locale_alias_registered; static const rb_data_type_t encoding_data_type = { "encoding", {0, 0, 0,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; #define is_encoding_type(obj) (RTYPEDDATA_TYPE(obj) == &encoding_data_type) diff --git a/enumerator.c b/enumerator.c index 69c96b2d8f0a32..9d22bbe9a0bf01 100644 --- a/enumerator.c +++ b/enumerator.c @@ -280,7 +280,7 @@ static const rb_data_type_t enumerator_data_type = { NULL, // Nothing allocated externally, so don't need a memsize function NULL, }, - 0, NULL, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE + 0, NULL, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE }; static struct enumerator * @@ -311,7 +311,7 @@ static const rb_data_type_t proc_entry_data_type = { NULL, // Nothing allocated externally, so don't need a memsize function proc_entry_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; static struct proc_entry * @@ -1332,7 +1332,7 @@ static const rb_data_type_t yielder_data_type = { NULL, yielder_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; static struct yielder * @@ -1456,7 +1456,7 @@ static const rb_data_type_t generator_data_type = { NULL, generator_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; static struct generator * @@ -2987,7 +2987,7 @@ static const rb_data_type_t producer_data_type = { producer_memsize, producer_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; static struct producer * @@ -3205,7 +3205,7 @@ static const rb_data_type_t enum_chain_data_type = { enum_chain_memsize, enum_chain_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; static struct enum_chain * @@ -3520,7 +3520,7 @@ static const rb_data_type_t enum_product_data_type = { enum_product_memsize, enum_product_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; static struct enum_product * @@ -3858,7 +3858,7 @@ static const rb_data_type_t arith_seq_data_type = { NULL, }, .parent = &enumerator_data_type, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE }; static VALUE diff --git a/error.c b/error.c index 7a08fd2b9ebbaa..379296c1182878 100644 --- a/error.c +++ b/error.c @@ -2533,7 +2533,7 @@ static const rb_data_type_t name_err_mesg_data_type = { NULL, // No external memory to report, name_err_mesg_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; /* :nodoc: */ diff --git a/ext/socket/raddrinfo.c b/ext/socket/raddrinfo.c index f1fbcc35def3e2..6a565789952952 100644 --- a/ext/socket/raddrinfo.c +++ b/ext/socket/raddrinfo.c @@ -1291,7 +1291,7 @@ addrinfo_memsize(const void *ptr) static const rb_data_type_t addrinfo_type = { "socket/addrinfo", {addrinfo_mark, addrinfo_free, addrinfo_memsize,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED, + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED, }; static VALUE diff --git a/file.c b/file.c index ec8e05f287be30..1231848c1035f0 100644 --- a/file.c +++ b/file.c @@ -548,7 +548,7 @@ static const rb_data_type_t stat_data_type = { RUBY_TYPED_DEFAULT_FREE, NULL, // No external memory to report }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; struct rb_stat { diff --git a/hash.c b/hash.c index cf5d7a3934129d..506b2afe7925f2 100644 --- a/hash.c +++ b/hash.c @@ -6941,7 +6941,7 @@ static const rb_data_type_t env_data_type = { NULL, NULL, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED, }; /* diff --git a/id_table.c b/id_table.c index 299b7d3ae5819f..f45cd2c61e1199 100644 --- a/id_table.c +++ b/id_table.c @@ -349,7 +349,7 @@ const rb_data_type_t rb_managed_id_table_type = { .dfree = managed_id_table_free, .dsize = managed_id_table_memsize, }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, }; static inline struct rb_id_table * @@ -478,7 +478,7 @@ const rb_data_type_t rb_marked_id_table_type = { .dcompact = marked_id_table_compact, }, .parent = &rb_managed_id_table_type, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, }; VALUE diff --git a/io.c b/io.c index 4385363ee6e5c6..f03bcb3be06b23 100644 --- a/io.c +++ b/io.c @@ -10036,7 +10036,7 @@ argf_memsize(const void *ptr) static const rb_data_type_t argf_type = { "ARGF", {argf_mark_and_move, RUBY_TYPED_DEFAULT_FREE, argf_memsize, argf_mark_and_move}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; static inline void diff --git a/io_buffer.c b/io_buffer.c index e1ddcc5f7f614c..b07626c5d738f5 100644 --- a/io_buffer.c +++ b/io_buffer.c @@ -332,7 +332,7 @@ static const rb_data_type_t rb_io_buffer_type = { .dcompact = rb_io_buffer_type_compact, }, .data = NULL, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, }; static struct rb_io_buffer * diff --git a/iseq.c b/iseq.c index b90fcb4334bfd7..5256631a23113c 100644 --- a/iseq.c +++ b/iseq.c @@ -1607,7 +1607,7 @@ static const rb_data_type_t iseqw_data_type = { iseqw_memsize, iseqw_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE|RUBY_TYPED_WB_PROTECTED }; static VALUE @@ -2863,7 +2863,7 @@ iseq_inspect(const rb_iseq_t *iseq) static const rb_data_type_t tmp_set = { "tmpset", {(void (*)(void *))rb_mark_set, (void (*)(void *))st_free_table, 0, 0,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE }; static VALUE @@ -3347,7 +3347,7 @@ cdhash_each(VALUE key, VALUE value, VALUE ary) static const rb_data_type_t label_wrapper = { "label_wrapper", {(void (*)(void *))rb_mark_tbl, (void (*)(void *))st_free_table, 0, 0,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE }; #define DECL_ID(name) \ diff --git a/lib/rubygems/request.rb b/lib/rubygems/request.rb index e817ee57042d10..2e28f41bef0079 100644 --- a/lib/rubygems/request.rb +++ b/lib/rubygems/request.rb @@ -61,7 +61,7 @@ def self.configure_connection_for_https(connection, cert_files) if Gem.configuration.ssl_client_cert pem = File.read Gem.configuration.ssl_client_cert connection.cert = OpenSSL::X509::Certificate.new pem - connection.key = OpenSSL::PKey::RSA.new pem + connection.key = OpenSSL::PKey.read pem end store.set_default_paths diff --git a/marshal.c b/marshal.c index e6ee3b47b05002..39b25552429ff3 100644 --- a/marshal.c +++ b/marshal.c @@ -237,7 +237,7 @@ memsize_dump_arg(const void *ptr) static const rb_data_type_t dump_arg_data = { "dump_arg", {mark_dump_arg, free_dump_arg, memsize_dump_arg,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_EMBEDDABLE }; static VALUE @@ -1301,7 +1301,7 @@ memsize_load_arg(const void *ptr) static const rb_data_type_t load_arg_data = { "load_arg", {mark_load_arg, free_load_arg, memsize_load_arg,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_EMBEDDABLE }; #define r_entry(v, arg) r_entry0((v), (arg)->data->num_entries, (arg)) @@ -2638,7 +2638,7 @@ static const rb_data_type_t marshal_compat_type = { .dsize = marshal_compat_table_memsize, .dcompact = marshal_compat_table_mark_and_move, }, - .flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY, + .flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_THREAD_SAFE_FREE, }; static st_table * diff --git a/memory_view.c b/memory_view.c index 2de756d681e4c7..d98711e90d3fd3 100644 --- a/memory_view.c +++ b/memory_view.c @@ -125,7 +125,7 @@ static const rb_data_type_t memory_view_entry_data_type = { 0, 0, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE }; /* Register memory view functions for the given class */ diff --git a/prism/prism.c b/prism/prism.c index 0960e39747f5ad..e3137d3167e7db 100644 --- a/prism/prism.c +++ b/prism/prism.c @@ -2249,7 +2249,15 @@ pm_regular_expression_flags_create(pm_parser_t *parser, const pm_token_t *closin if (closing->type == PM_TOKEN_REGEXP_END) { pm_buffer_t unknown_flags = { 0 }; - for (const uint8_t *flag = closing->start + 1; flag < closing->end; flag++) { + // The closing delimiter is normally a single byte, so the options + // follow it. A `\r\n` newline delimiter is two bytes, however, so we + // skip past it to avoid misreading the trailing `\n` as an option. + const uint8_t *flag = closing->start + 1; + if ((closing->end - closing->start) >= 2 && closing->start[0] == '\r' && closing->start[1] == '\n') { + flag++; + } + + for (; flag < closing->end; flag++) { switch (*flag) { case 'i': flags |= PM_REGULAR_EXPRESSION_FLAGS_IGNORE_CASE; break; case 'm': flags |= PM_REGULAR_EXPRESSION_FLAGS_MULTI_LINE; break; @@ -19047,8 +19055,11 @@ parse_parentheses(pm_parser_t *parser, pm_binding_power_t binding_power, uint8_t lex_state_set(parser, PM_LEX_STATE_ENDARG); } - parser_lex(parser); + /* Pop before consuming the closing `)` so the following token (e.g. a + * `do`) is lexed in the enclosing context rather than as a block + * belonging to the parenthesized expression. */ pm_accepts_block_stack_pop(parser); + parser_lex(parser); pop_block_exits(parser, previous_block_exits); if (PM_NODE_TYPE_P(statement, PM_MULTI_TARGET_NODE) || PM_NODE_TYPE_P(statement, PM_SPLAT_NODE)) { @@ -19319,6 +19330,13 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u accept1(parser, PM_TOKEN_NEWLINE); + /* Pop before consuming the closing `]` so the following token (e.g. + * a `do`) is lexed in the enclosing context rather than as a block + * belonging to the array's interior. Otherwise a `do` block would + * wrongly bind to a command with an array argument, as in + * `foo(m [] do end)`. */ + pm_accepts_block_stack_pop(parser); + if (!accept1(parser, PM_TOKEN_BRACKET_RIGHT)) { PM_PARSER_ERR_TOKEN_FORMAT(parser, &parser->current, PM_ERR_ARRAY_TERM, pm_token_str(parser->current.type)); parser->previous.start = parser->previous.end; @@ -19326,7 +19344,6 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u } pm_array_node_close_set(parser, array, &parser->previous); - pm_accepts_block_stack_pop(parser); return UP(array); } @@ -20645,6 +20662,11 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u } parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false); + + /* Pop before consuming the closing `}` so the following token + * (e.g. a `do`) is lexed in the enclosing context rather than + * as a block belonging to the lambda's interior. */ + pm_accepts_block_stack_pop(parser); expect1_opening(parser, PM_TOKEN_BRACE_RIGHT, PM_ERR_LAMBDA_TERM_BRACE, &opening); } else { expect1(parser, PM_TOKEN_KEYWORD_DO, PM_ERR_LAMBDA_OPEN); @@ -20661,6 +20683,8 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u parser_warn_indentation_mismatch(parser, opening_newline_index, &operator, false, false); } + /* As with the brace case above, pop before consuming `end`. */ + pm_accepts_block_stack_pop(parser); expect1_opening(parser, PM_TOKEN_KEYWORD_END, PM_ERR_LAMBDA_TERM_END, &operator); } @@ -20669,7 +20693,6 @@ parse_expression_prefix(pm_parser_t *parser, pm_binding_power_t binding_power, u pm_node_t *parameters = parse_blocklike_parameters(parser, UP(block_parameters), &operator, &parser->previous); pm_parser_scope_pop(parser); - pm_accepts_block_stack_pop(parser); return UP(pm_lambda_node_create(parser, &locals, &operator, &opening, &parser->previous, parameters, body)); } diff --git a/proc.c b/proc.c index cb6d214cb531c3..dfc750125239a7 100644 --- a/proc.c +++ b/proc.c @@ -106,7 +106,7 @@ const rb_data_type_t ruby_proc_data_type = { proc_memsize, proc_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; #define proc_data_type ruby_proc_data_type @@ -285,7 +285,7 @@ const rb_data_type_t ruby_binding_data_type = { binding_memsize, binding_mark_and_move, }, - 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_THREAD_SAFE_FREE }; VALUE @@ -1812,7 +1812,7 @@ static const rb_data_type_t method_data_type = { NULL, // No external memory to report, bm_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE | RUBY_TYPED_FROZEN_SHAREABLE_NO_REC + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE | RUBY_TYPED_FROZEN_SHAREABLE_NO_REC }; VALUE diff --git a/process.c b/process.c index ac44167c05f2ca..dc7199cba21c94 100644 --- a/process.c +++ b/process.c @@ -597,7 +597,7 @@ static const rb_data_type_t rb_process_status_type = { .dfree = RUBY_DEFAULT_FREE, .dsize = NULL, }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, }; static VALUE @@ -1740,7 +1740,7 @@ memsize_exec_arg(const void *ptr) static const rb_data_type_t exec_arg_data_type = { "exec_arg", {mark_exec_arg, RUBY_TYPED_DEFAULT_FREE, memsize_exec_arg}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_EMBEDDABLE }; #ifdef _WIN32 diff --git a/ractor.c b/ractor.c index f94c06cc738bf4..03c949d5ba9e04 100644 --- a/ractor.c +++ b/ractor.c @@ -2472,7 +2472,7 @@ static const rb_data_type_t cross_ractor_require_data_type = { NULL, // memsize NULL, // compact }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE }; static VALUE diff --git a/ractor_sync.c b/ractor_sync.c index 44c84ded92696f..5eeb6e20db9f28 100644 --- a/ractor_sync.c +++ b/ractor_sync.c @@ -36,7 +36,7 @@ static const rb_data_type_t ractor_port_data_type = { NULL, // memsize NULL, // update }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE, + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_EMBEDDABLE, }; static st_data_t @@ -1255,7 +1255,7 @@ static const rb_data_type_t ractor_selector_data_type = { ractor_selector_memsize, NULL, // update }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED, }; static struct ractor_selector * diff --git a/random.c b/random.c index 63f43a161ae252..1eaeacfe21dd92 100644 --- a/random.c +++ b/random.c @@ -272,7 +272,7 @@ const rb_data_type_t rb_random_data_type = { random_free, random_memsize, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; #define random_mt_mark rb_random_mark @@ -293,7 +293,7 @@ static const rb_data_type_t random_mt_type = { }, &rb_random_data_type, (void *)&random_mt_if, - RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; static rb_random_t * diff --git a/ruby_parser.c b/ruby_parser.c index a96fc4974bda2a..7f9c04e6b0facf 100644 --- a/ruby_parser.c +++ b/ruby_parser.c @@ -508,7 +508,7 @@ static const rb_data_type_t ruby_parser_data_type = { parser_free, parser_memsize, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE }; #ifdef UNIVERSAL_PARSER @@ -736,7 +736,7 @@ static const rb_data_type_t ast_data_type = { ast_free, NULL, // No dsize() because this object does not appear in ObjectSpace. }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE }; static VALUE diff --git a/scheduler.c b/scheduler.c index 7efd4274cb59a5..7a2671fead39dc 100644 --- a/scheduler.c +++ b/scheduler.c @@ -90,7 +90,7 @@ static const rb_data_type_t blocking_operation_data_type = { RUBY_DEFAULT_FREE, blocking_operation_memsize, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; /* diff --git a/set.c b/set.c index 2a892673287e64..982d0aa5baf63d 100644 --- a/set.c +++ b/set.c @@ -201,7 +201,7 @@ static const rb_data_type_t set_data_type = { .dsize = set_size, .dcompact = set_update_references, }, - .flags = RUBY_TYPED_EMBEDDABLE | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE + .flags = RUBY_TYPED_EMBEDDABLE | RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FROZEN_SHAREABLE }; static inline set_table * diff --git a/shape.c b/shape.c index f7b67c197c18a3..9052bd658b1ded 100644 --- a/shape.c +++ b/shape.c @@ -365,7 +365,7 @@ static const rb_data_type_t shape_tree_type = { .dsize = shape_tree_memsize, .dcompact = shape_tree_mark_and_move, }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED, }; diff --git a/string.c b/string.c index b3cb36007fc855..d1d9da2428a959 100644 --- a/string.c +++ b/string.c @@ -7883,7 +7883,7 @@ mapping_buffer_free(void *p) static const rb_data_type_t mapping_buffer_type = { "mapping_buffer", {0, mapping_buffer_free,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; static VALUE diff --git a/symbol.c b/symbol.c index d26d6680083aa0..b157d2677cdae3 100644 --- a/symbol.c +++ b/symbol.c @@ -209,7 +209,7 @@ static const rb_data_type_t sym_id_entry_list_type = { sym_id_entry_list_memsize, sym_id_entry_list_compact, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; static int diff --git a/test/prism/errors/do_block_in_command_args.txt b/test/prism/errors/do_block_in_command_args.txt new file mode 100644 index 00000000000000..82462ecf537da2 --- /dev/null +++ b/test/prism/errors/do_block_in_command_args.txt @@ -0,0 +1,21 @@ +foo(m [] do end) + ^~ unexpected 'do'; expected a `)` to close the arguments + ^~ unexpected 'do', expecting end-of-input + ^~ unexpected 'do', ignoring it + ^~~ unexpected 'end', ignoring it + ^ unexpected ')', ignoring it + +foo(m -> {} do end) + ^~ unexpected 'do'; expected a `)` to close the arguments + ^~ unexpected 'do', expecting end-of-input + ^~ unexpected 'do', ignoring it + ^~~ unexpected 'end', ignoring it + ^ unexpected ')', ignoring it + +foo(m (1) do end) + ^~ unexpected 'do'; expected a `)` to close the arguments + ^~ unexpected 'do', expecting end-of-input + ^~ unexpected 'do', ignoring it + ^~~ unexpected 'end', ignoring it + ^ unexpected ')', ignoring it + diff --git a/test/prism/regexp_test.rb b/test/prism/regexp_test.rb index cde0c23f97681e..41c51a111ccf86 100644 --- a/test/prism/regexp_test.rb +++ b/test/prism/regexp_test.rb @@ -237,8 +237,27 @@ def test_last_encoding_option_wins assert_equal Regexp::NOENCODING, option end + # A `%r` regexp can use a newline (LF or CRLF) as its delimiter. The closing + # delimiter terminates the regexp and must not be misread as an option -- in + # particular the trailing `\n` of a `\r\n` delimiter. + def test_newline_delimiter + assert_newline_regexp("%r\nfoo\n", "foo", 0) + assert_newline_regexp("%r\r\nfoo\r\n", "foo", 0) + assert_newline_regexp("%r\r\nfoo\r\ni", "foo", Regexp::IGNORECASE) + assert_newline_regexp("%r\r\nfoo\r\nmix", "foo", Regexp::IGNORECASE | Regexp::MULTILINE | Regexp::EXTENDED) + assert_newline_regexp("%r\r\n\r\n", "", 0) + end + private + def assert_newline_regexp(source, content, options) + node = Prism.parse_statement(source) + + assert_kind_of RegularExpressionNode, node + assert_equal content, node.content + assert_equal options, node.options + end + def assert_valid_regexp(source) assert Prism.parse_success?("/#{source}/ =~ \"\"") end diff --git a/test/rubygems/mldsa65_ca_cert.pem b/test/rubygems/mldsa65_ca_cert.pem new file mode 100644 index 00000000000000..065cef51214d38 --- /dev/null +++ b/test/rubygems/mldsa65_ca_cert.pem @@ -0,0 +1,119 @@ +-----BEGIN CERTIFICATE----- +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 +-----END CERTIFICATE----- diff --git a/test/rubygems/mldsa65_client.pem b/test/rubygems/mldsa65_client.pem new file mode 100644 index 00000000000000..a75718956bad17 --- /dev/null +++ b/test/rubygems/mldsa65_client.pem @@ -0,0 +1,206 @@ +-----BEGIN CERTIFICATE----- +MIIVvDCCCLmgAwIBAgIBAjALBglghkgBZQMEAxIwQTELMAkGA1UEBhMCSlAxDjAM +BgNVBAgMBVRva3lvMRUwEwYDVQQKDAxSdWJ5R2Vtc1Rlc3QxCzAJBgNVBAMMAkNB +MB4XDTA5MDEwMTAwMDAwMFoXDTQ5MTIzMTIzNTk1OVowRTELMAkGA1UEBhMCSlAx +DjAMBgNVBAgMBVRva3lvMRUwEwYDVQQKDAxSdWJ5R2Vtc1Rlc3QxDzANBgNVBAMM +BmNsaWVudDCCB7IwCwYJYIZIAWUDBAMSA4IHoQD7X3IOq2jQ0xZyeZ1T1wlHwG8p +6K57Y/eYrw/oxbhNiaIymTxADTgGQOq92554MzkHbossXzId7zoSLrWMeX+BQV0I +/NBfDL8InJ2R8Bk75C6hllHFmkRbRYkc5TVfuWlDY5yhewetrmOZHiQFTxSHNBNK +fzuT8d3o8QuexZfVzfC4eofO4jqwB/ptsYC7aTXIqb93qGV1LXVKawfrvkWVaquY +gGKvm2K6kHoobsH/d9k01MYPINShoRzNSa2Tyt7qvgjplbEtMe+iG+WZaCRJhmjS +4sVf241AbmlHK2oqYq1Ie3KaT78Hjx1mluoqvfvUqDGSWadSdFnly1kQqmnmY+PT +0xjWQ2l+FtfFU/LYQrAOwYN6IIQ6InXxOVgACti52QWROPtSf+GfM9LFYqKqTVs8 +rLXSv+aZE9PmcZCu3CxaYFyCgxUD/1zgTAqCIQFysVpfM7VL53ReiBvcK+3B9KxQ +06QS5JoIWE4KkZP+OlwiIZm0lhV5hXj7Fa+ln4NSMmrH/+SV0aJ9LhFN7gZBzyQf +bkPJvW5Tmazk+2HLJrPvyRH8K6lmId/+3YCZs+Mw7IYTNeOT333YbnEBgoZYk/KH +d3nrPP93PSw4s+pyWaM2SpCD2r30xQT27svGl0kROQX3wbma1chmz35FDzXRATcO +tUYmoHOqjj6qjw6sToxFxowEgH+cyEwpo6t5z0S0d6iL6f1xLxNr/BscGqK3GUF7 +fEEivQ3tOLw02lWynTK7ry0NWqGxtamaOlV6d46+nqLkBxhZSbDiadk2Ur/vMrqr +3Ycgt+QLXStWBdI4o5+ds89EUjB2YzNS7lYUpnowGMD/hgu1InHL8lr8EMtx1qzu +2hj8CkSDzc9+rfiTCZ2nXrynphrx0y5EyKH1zvGBoASLaHsQRdV8q5bMi2WJCE2C +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 +-----END CERTIFICATE----- +-----BEGIN PRIVATE KEY----- +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 +kfewIHuWBX+uMXRWZ2zfo9ES +-----END PRIVATE KEY----- diff --git a/test/rubygems/mldsa65_ssl_cert.pem b/test/rubygems/mldsa65_ssl_cert.pem new file mode 100644 index 00000000000000..9345f1d17a809d --- /dev/null +++ b/test/rubygems/mldsa65_ssl_cert.pem @@ -0,0 +1,119 @@ +-----BEGIN CERTIFICATE----- +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 +GyMn +-----END CERTIFICATE----- diff --git a/test/rubygems/mldsa65_ssl_key.pem b/test/rubygems/mldsa65_ssl_key.pem new file mode 100644 index 00000000000000..6f1118f1f6cfef --- /dev/null +++ b/test/rubygems/mldsa65_ssl_key.pem @@ -0,0 +1,88 @@ +-----BEGIN PRIVATE KEY----- +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 +7yEguRF45chFFmfOaycPlNOQ +-----END PRIVATE KEY----- diff --git a/test/rubygems/test_gem_remote_fetcher_local_ssl_server.rb b/test/rubygems/test_gem_remote_fetcher_local_ssl_server.rb index 59337e12c10ea2..129c216259e63a 100644 --- a/test/rubygems/test_gem_remote_fetcher_local_ssl_server.rb +++ b/test/rubygems/test_gem_remote_fetcher_local_ssl_server.rb @@ -40,6 +40,16 @@ def test_ssl_connection end end + def test_pqc_ssl_connection + omit_unless_support_pqc + + ssl_server = start_ssl_server(mode: :pqc) + temp_ca_cert = File.join(__dir__, "mldsa65_ca_cert.pem") + with_configured_fetcher(":ssl_ca_cert: #{temp_ca_cert}") do |fetcher| + fetcher.fetch_path("https://localhost:#{ssl_server.addr[1]}/yaml") + end + end + def test_ssl_client_cert_auth_connection ssl_server = start_ssl_server( { verify_mode: OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT } @@ -56,6 +66,25 @@ def test_ssl_client_cert_auth_connection end end + def test_pqc_ssl_client_cert_auth_connection + omit_unless_support_pqc + + ssl_server = start_ssl_server( + mode: :pqc, + verify_mode: OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT + ) + + temp_ca_cert = File.join(__dir__, "mldsa65_ca_cert.pem") + temp_client_cert = File.join(__dir__, "mldsa65_client.pem") + + with_configured_fetcher( + ":ssl_ca_cert: #{temp_ca_cert}\n" \ + ":ssl_client_cert: #{temp_client_cert}\n" + ) do |fetcher| + fetcher.fetch_path("https://localhost:#{ssl_server.addr[1]}/yaml") + end + end + def test_do_not_allow_invalid_client_cert_auth_connection ssl_server = start_ssl_server( { verify_mode: OpenSSL::SSL::VERIFY_PEER | OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT } @@ -135,12 +164,27 @@ def with_configured_fetcher(config_str = nil, &block) Gem.configuration = nil end + # mode: + # :non_pqc - Run single server with PQC-unsupported RSA (default) + # :pqc - Run single server with PQC-supported key exchange, + # X25519MLKEM768, and PQC-supported certificate, ML-DSA-65 def start_ssl_server(config = {}) + mode = config.fetch(:mode, :non_pqc) server = TCPServer.new(0) ctx = OpenSSL::SSL::SSLContext.new - ctx.cert = cert("ssl_cert.pem") - ctx.key = key("ssl_key.pem") - ctx.ca_file = File.join(__dir__, "ca_cert.pem") + + case mode + when :non_pqc + ctx.cert = cert("ssl_cert.pem") + ctx.key = key("ssl_key.pem") + ctx.ca_file = File.join(__dir__, "ca_cert.pem") + when :pqc + ctx.cert = cert("mldsa65_ssl_cert.pem") + ctx.key = key("mldsa65_ssl_key.pem") + ctx.ca_file = File.join(__dir__, "mldsa65_ca_cert.pem") + ctx.groups = "X25519MLKEM768" + end + ctx.verify_mode = config[:verify_mode] if config[:verify_mode] @ssl_server = OpenSSL::SSL::SSLServer.new(server, ctx) @ssl_server_thread = Thread.new do @@ -175,6 +219,17 @@ def cert(filename) end def key(filename) - OpenSSL::PKey::RSA.new(File.read(File.join(__dir__, filename))) + OpenSSL::PKey.read(File.read(File.join(__dir__, filename))) + end + + def omit_unless_support_pqc + # PQC algorithms ML-KEM and ML-DSA require OpenSSL >= 3.5. + # https://openssl-library.org/post/2025-04-08-openssl-35-final-release/ + omit "PQC algorithms require OpenSSL >= 3.5" unless + OpenSSL::OPENSSL_VERSION_NUMBER >= 0x30500000 + # ctx.groups (OpenSSL::SSL::SSLContext#groups) used in start_ssl_server + # mode :pqc requires Ruby OpenSSL >= 4.0. + omit "PQC test requires Ruby OpenSSL >= 4.0" unless + Gem::Version.new(OpenSSL::VERSION) >= Gem::Version.new("4.0") end end if Gem::HAVE_OPENSSL diff --git a/thread.c b/thread.c index 25dde73fd7f28f..2a89582a274e15 100644 --- a/thread.c +++ b/thread.c @@ -5081,7 +5081,7 @@ static const rb_data_type_t thgroup_data_type = { RUBY_TYPED_DEFAULT_FREE, NULL, // No external memory to report }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; /* @@ -5250,7 +5250,7 @@ thread_shield_mark(void *ptr) static const rb_data_type_t thread_shield_data_type = { "thread_shield", {thread_shield_mark, 0, 0,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE }; static VALUE diff --git a/thread_pthread.c b/thread_pthread.c index 875507dbcbca98..3214e25560c5b3 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -1731,9 +1731,15 @@ ruby_thread_set_native(rb_thread_t *th) static void native_thread_setup(struct rb_native_thread *nt); static void native_thread_setup_on_thread(struct rb_native_thread *nt); +// Internal cache of page size: +static size_t RB_THREAD_PAGE_SIZE; + void Init_native_thread(rb_thread_t *main_th) { + // Get the system page size for later use in stack allocation and stack overflow checks: + RB_THREAD_PAGE_SIZE = sysconf(_SC_PAGESIZE); + #if defined(HAVE_PTHREAD_CONDATTR_SETCLOCK) if (condattr_monotonic) { int r = pthread_condattr_init(condattr_monotonic); @@ -1969,7 +1975,7 @@ get_stack(void **addr, size_t *size) # ifdef HAVE_PTHREAD_ATTR_GETGUARDSIZE CHECK_ERR(pthread_attr_getguardsize(&attr, &guard)); # else - guard = getpagesize(); + guard = RB_THREAD_PAGE_SIZE; # endif *size -= guard; pthread_attr_destroy(&attr); @@ -2037,10 +2043,6 @@ static struct { extern void *STACK_END_ADDRESS; #endif -enum { - RUBY_STACK_SPACE_RATIO = 5 -}; - static void native_thread_init_main_thread_stack(void *addr) { @@ -2074,15 +2076,11 @@ native_thread_init_main_thread_stack(void *addr) { #if defined(HAVE_GETRLIMIT) #if defined(PTHREAD_STACK_DEFAULT) -# if PTHREAD_STACK_DEFAULT < RUBY_STACK_SPACE*5 -# error "PTHREAD_STACK_DEFAULT is too small" -# endif size_t size = PTHREAD_STACK_DEFAULT; #else size_t size = RUBY_VM_THREAD_VM_STACK_SIZE; #endif size_t space; - int pagesize = getpagesize(); struct rlimit rlim; STACK_GROW_DIR_DETECTION; if (getrlimit(RLIMIT_STACK, &rlim) == 0) { @@ -2090,10 +2088,10 @@ native_thread_init_main_thread_stack(void *addr) } addr = native_main_thread.stack_start; if (IS_STACK_DIR_UPPER()) { - space = ((size_t)((char *)addr + size) / pagesize) * pagesize - (size_t)addr; + space = ((size_t)((char *)addr + size) / RB_THREAD_PAGE_SIZE) * RB_THREAD_PAGE_SIZE - (size_t)addr; } else { - space = (size_t)addr - ((size_t)((char *)addr - size) / pagesize + 1) * pagesize; + space = (size_t)addr - ((size_t)((char *)addr - size) / RB_THREAD_PAGE_SIZE + 1) * RB_THREAD_PAGE_SIZE; } native_main_thread.stack_maxsize = space; #endif @@ -3253,7 +3251,7 @@ ruby_stack_overflowed_p(const rb_thread_t *th, const void *addr) { void *base; size_t size; - const size_t water_mark = 1024 * 1024; + const size_t water_mark = RB_THREAD_PAGE_SIZE; STACK_GROW_DIR_DETECTION; if (th) { @@ -3277,7 +3275,6 @@ ruby_stack_overflowed_p(const rb_thread_t *th, const void *addr) return 0; } - size /= RUBY_STACK_SPACE_RATIO; if (size > water_mark) size = water_mark; if (IS_STACK_DIR_UPPER()) { if (size > ~(size_t)base+1) size = ~(size_t)base+1; diff --git a/thread_sync.c b/thread_sync.c index 3baca8befc4f01..f6c3dca7745b3a 100644 --- a/thread_sync.c +++ b/thread_sync.c @@ -728,7 +728,7 @@ static const rb_data_type_t queue_data_type = { .dsize = queue_memsize, .dcompact = queue_mark_and_move, }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -834,7 +834,7 @@ static const rb_data_type_t szqueue_data_type = { .dcompact = szqueue_mark_and_move, }, .parent = &queue_data_type, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED, }; static VALUE @@ -1174,7 +1174,7 @@ condvar_memsize(const void *ptr) static const rb_data_type_t cv_data_type = { "condvar", {0, RUBY_TYPED_DEFAULT_FREE, condvar_memsize,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY|RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE|RUBY_TYPED_WB_PROTECTED }; static struct rb_condvar * diff --git a/time.c b/time.c index c3bda3f6af0472..24a09e88a77458 100644 --- a/time.c +++ b/time.c @@ -1909,7 +1909,7 @@ static const rb_data_type_t time_data_type = { .dsize = NULL, .dcompact = time_mark_and_move, }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_FROZEN_SHAREABLE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, }; static VALUE diff --git a/transcode.c b/transcode.c index 5bf99ff90b567f..b657ff18708219 100644 --- a/transcode.c +++ b/transcode.c @@ -3019,7 +3019,7 @@ econv_memsize(const void *ptr) static const rb_data_type_t econv_data_type = { "econv", {0, econv_free, econv_memsize,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE }; static VALUE diff --git a/variable.c b/variable.c index 687fa03631b6bb..dc015b4cbce168 100644 --- a/variable.c +++ b/variable.c @@ -2676,7 +2676,7 @@ autoload_table_compact(void *ptr) static const rb_data_type_t autoload_table_type = { "autoload_table", {autoload_table_mark, autoload_table_free, autoload_table_memsize, autoload_table_compact,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; #define check_autoload_table(av) \ diff --git a/vm.c b/vm.c index 9da23c68b6f3db..a5ab2a153013e1 100644 --- a/vm.c +++ b/vm.c @@ -3561,7 +3561,7 @@ vm_memsize(const void *ptr) const rb_data_type_t ruby_vm_data_type = { "VM", {0, 0, vm_memsize,}, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE }; #define vm_data_type ruby_vm_data_type @@ -3924,7 +3924,7 @@ const rb_data_type_t ruby_threadptr_data_type = { thread_memsize, thread_compact, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE }; VALUE @@ -4751,7 +4751,7 @@ static const rb_data_type_t pin_array_list_type = { .dsize = pin_array_list_memsize, .dcompact = pin_array_list_update_references, }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, }; static VALUE diff --git a/vm_backtrace.c b/vm_backtrace.c index 85a06586120030..a865b6e71f3f6a 100644 --- a/vm_backtrace.c +++ b/vm_backtrace.c @@ -158,7 +158,7 @@ static const rb_data_type_t location_data_type = { NULL, // No external memory to report, location_ref_update, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; int @@ -568,7 +568,7 @@ static const rb_data_type_t backtrace_data_type = { /* Cannot set the RUBY_TYPED_EMBEDDABLE flag because the loc of frame_info * points elements in the backtrace array. This can cause the loc to become * incorrect if this backtrace object is moved by compaction. */ - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED }; int diff --git a/vm_method.c b/vm_method.c index d8a42621c8f448..43ca4313bca487 100644 --- a/vm_method.c +++ b/vm_method.c @@ -135,7 +135,7 @@ static const rb_data_type_t cc_table_type = { .dcompact = vm_cc_table_compact, }, .parent = &rb_managed_id_table_type, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, + .flags = RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE, }; VALUE @@ -798,7 +798,7 @@ static const rb_data_type_t cc_refinement_set_type = { cc_refinement_set_compact, cc_refinement_set_handle_weak_references, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; VALUE diff --git a/vm_trace.c b/vm_trace.c index 305802f469df62..8ef805dc1fe9d4 100644 --- a/vm_trace.c +++ b/vm_trace.c @@ -906,7 +906,7 @@ static const rb_data_type_t tp_data_type = { NULL, // Nothing allocated externally, so don't need a memsize function tp_mark_and_move, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; static VALUE diff --git a/weakmap.c b/weakmap.c index 618c88bfa985f8..7cf0f6bc3e2845 100644 --- a/weakmap.c +++ b/weakmap.c @@ -141,7 +141,7 @@ const rb_data_type_t rb_weakmap_type = { wmap_compact, wmap_handle_weak_references, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; static int @@ -627,7 +627,7 @@ static const rb_data_type_t rb_weakkeymap_type = { wkmap_compact, wkmap_handle_weak_references, }, - 0, 0, RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_THREAD_SAFE_FREE | RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_EMBEDDABLE }; static int diff --git a/zjit.rb b/zjit.rb index 2c3fe3c248a2ee..bff9cfe1538621 100644 --- a/zjit.rb +++ b/zjit.rb @@ -129,9 +129,6 @@ def stats_string :send_count, :dynamic_send_count, :optimized_send_count, - :dynamic_setivar_count, - :dynamic_getivar_count, - :dynamic_definedivar_count, :iseq_optimized_send_count, :inline_cfunc_optimized_send_count, :inline_iseq_optimized_send_count, @@ -140,6 +137,10 @@ def stats_string :variadic_cfunc_optimized_send_count, ], buf:, stats:, right_align: true, base: :send_count) print_counters([ + :dynamic_setivar_count, + :dynamic_getivar_count, + :dynamic_definedivar_count, + :compiled_iseq_count, :compiled_side_exit_count, :failed_iseq_count, diff --git a/zjit/src/backend/lir.rs b/zjit/src/backend/lir.rs index 29ea7c7f61e135..60f6cbb5805c67 100644 --- a/zjit/src/backend/lir.rs +++ b/zjit/src/backend/lir.rs @@ -2588,16 +2588,15 @@ impl Assembler let payload = get_or_create_iseq_payload(exit.iseq); payload.reset_profiles_remaining(recompile.insn_idx as YarvInsnIdx); use crate::codegen::exit_recompile; + let (profile_kind, profile_payload) = recompile.strategy.to_c_args(); asm_comment!(asm, "profile and maybe recompile"); asm_ccall!(asm, exit_recompile, EC, recompile.frame_iseq, recompile.compiled_iseq, - Opnd::UImm(recompile.insn_idx as u64), - Opnd::Imm(match recompile.strategy { - hir::Recompile::ProfileSend { argc } => argc as i64, - hir::Recompile::ProfileSelf => -1, - }) + recompile.insn_idx.into(), + profile_kind.into(), + profile_payload.into() ); } } diff --git a/zjit/src/codegen.rs b/zjit/src/codegen.rs index c38d62e2a3053d..e422ca1acafbd1 100644 --- a/zjit/src/codegen.rs +++ b/zjit/src/codegen.rs @@ -710,7 +710,7 @@ fn gen_insn(cb: &mut CodeBlock, jit: &mut JITState, asm: &mut Assembler, functio gen_guard_type(jit, asm, opnd!(val), val_type, guard_type, recompile, &function.frame_state(state)) } &Insn::GuardBitEquals { val, expected, reason, state, recompile } => gen_guard_bit_equals(jit, asm, opnd!(val), expected, reason, recompile, &function.frame_state(state)), - &Insn::GuardAnyBitSet { val, mask, reason, state, .. } => gen_guard_any_bit_set(jit, asm, opnd!(val), mask, reason, &function.frame_state(state)), + &Insn::GuardAnyBitSet { val, mask, reason, state, recompile, .. } => gen_guard_any_bit_set(jit, asm, opnd!(val), mask, reason, recompile, &function.frame_state(state)), &Insn::GuardNoBitsSet { val, mask, reason, state, .. } => gen_guard_no_bits_set(jit, asm, opnd!(val), mask, reason, &function.frame_state(state)), &Insn::GuardLess { left, right, reason, state } => gen_guard_less(jit, asm, opnd!(left), opnd!(right), reason, &function.frame_state(state)), &Insn::GuardGreaterEq { left, right, state, .. } => gen_guard_greater_eq(jit, asm, opnd!(left), opnd!(right), &function.frame_state(state)), @@ -2772,10 +2772,10 @@ fn mask_to_opnd(mask: crate::hir::Const) -> Option { } /// Compile a bitmask check with a side exit if none of the masked bits are not set -fn gen_guard_any_bit_set(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, mask: crate::hir::Const, reason: SideExitReason, state: &FrameState) -> lir::Opnd { +fn gen_guard_any_bit_set(jit: &mut JITState, asm: &mut Assembler, val: lir::Opnd, mask: crate::hir::Const, reason: SideExitReason, recompile: Option, state: &FrameState) -> lir::Opnd { let mask_opnd = mask_to_opnd(mask).unwrap_or_else(|| panic!("gen_guard_any_bit_set: unexpected hir::Const {mask:?}")); asm.test(val, mask_opnd); - asm.jz(jit, side_exit(jit, state, reason)); + asm.jz(jit, side_exit_with_recompile(jit, state, reason, recompile)); val } @@ -3204,8 +3204,7 @@ pub(crate) use c_callable; c_callable! { /// Called from JIT side-exit code to profile operands and trigger recompilation. - /// For send instructions (argc >= 0): profiles receiver + args from the stack. - /// For shape guard exits (argc == -1): profiles self from the CFP. + /// `profile_kind` selects what to profile; `profile_payload` carries kind-specific data. /// Once enough profiles are gathered, invalidates the compiled unit for recompilation. /// /// Two iseqs are passed because they diverge for inlined code. `frame_iseq_raw` is @@ -3215,7 +3214,9 @@ c_callable! { /// inliner folds the callee's body into it), so its version is the one holding the /// failing guard and the one we must invalidate to force a recompile. For /// non-inlined code the two are identical. - pub(crate) fn exit_recompile(ec: EcPtr, frame_iseq_raw: VALUE, compiled_iseq_raw: VALUE, insn_idx: u32, argc: i32) { + pub(crate) fn exit_recompile(ec: EcPtr, frame_iseq_raw: VALUE, compiled_iseq_raw: VALUE, insn_idx: u32, profile_kind: i32, profile_payload: i32) { + let recompile = Recompile::from_c_args(profile_kind, profile_payload); + // Fast check before taking the VM lock: skip if the compiled unit is already // invalidated or at the version limit. This avoids expensive lock acquisition // on every shape guard exit after the recompile has already been triggered. @@ -3236,9 +3237,10 @@ c_callable! { let compiled_iseq: IseqPtr = compiled_iseq_raw.as_iseq(); // For no-profile sends, skip if already profiled at this insn_idx. - // For shape guard exits (argc == -1), always re-profile because the + // For shape guard exits, always re-profile because the // original YARV profiles were monomorphic but runtime showed new shapes. - if argc >= 0 && get_or_create_iseq_payload(frame_iseq).profile.done_profiling_at(insn_idx as usize) { + if matches!(recompile, Recompile::ProfileSend { .. }) && + get_or_create_iseq_payload(frame_iseq).profile.done_profiling_at(insn_idx as usize) { return; } @@ -3246,14 +3248,21 @@ c_callable! { let cfp = unsafe { get_ec_cfp(ec) }; let payload = get_or_create_iseq_payload(frame_iseq); - if argc >= 0 { - let sp = unsafe { get_cfp_sp(cfp) }; - // Profile the receiver and arguments for this send instruction - payload.profile.profile_send_at(frame_iseq, insn_idx as usize, sp, argc as usize) - } else { - // Profile self for shape guard exits (argc == -1) - let self_val = unsafe { get_cfp_self(cfp) }; - payload.profile.profile_self_at(frame_iseq, insn_idx as usize, self_val) + match recompile { + Recompile::ProfileSend { argc } => { + let sp = unsafe { get_cfp_sp(cfp) }; + // Profile the receiver and arguments for this send instruction + payload.profile.profile_send_at(frame_iseq, insn_idx as usize, sp, argc as usize) + } + Recompile::ProfileSelf => { + // Profile self for shape guard exits + let self_val = unsafe { get_cfp_self(cfp) }; + payload.profile.profile_self_at(frame_iseq, insn_idx as usize, self_val) + } + Recompile::ProfileBlockHandler => { + // Profile the block handler for this getblockparamproxy instruction + payload.profile.profile_getblockparamproxy_at(frame_iseq, insn_idx as usize, cfp) + } } }); diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index 661702af87e0bb..0e61035a0cee72 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -569,12 +569,39 @@ pub enum SideExitReason { } /// Controls how a side exit triggers recompilation. +pub const RECOMPILE_PROFILE_SEND: i32 = 0; +pub const RECOMPILE_PROFILE_SELF: i32 = 1; +pub const RECOMPILE_PROFILE_BLOCK_HANDLER: i32 = 2; + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum Recompile { /// Profile receiver + arguments from the stack (for sends without profile data). ProfileSend { argc: i32 }, /// Profile self from the CFP (for shape guard failures). ProfileSelf, + /// Profile the block handler from the CFP (for getblockparamproxy guard failures). + ProfileBlockHandler, +} + +impl Recompile { + /// Convert to primitive arguments for passing across the C ABI. + pub fn to_c_args(self) -> (i32, i32) { + match self { + Recompile::ProfileSend { argc } => (RECOMPILE_PROFILE_SEND, argc), + Recompile::ProfileSelf => (RECOMPILE_PROFILE_SELF, 0), + Recompile::ProfileBlockHandler => (RECOMPILE_PROFILE_BLOCK_HANDLER, 0), + } + } + + /// Reconstruct from primitive arguments received across the C ABI. + pub fn from_c_args(kind: i32, payload: i32) -> Self { + match kind { + RECOMPILE_PROFILE_SEND => Recompile::ProfileSend { argc: payload }, + RECOMPILE_PROFILE_SELF => Recompile::ProfileSelf, + RECOMPILE_PROFILE_BLOCK_HANDLER => Recompile::ProfileBlockHandler, + _ => unreachable!("unknown recompile profile kind: {kind}"), + } + } } #[derive(Debug, Clone, Copy)] @@ -1192,7 +1219,7 @@ pub enum Insn { /// Side-exit if val is not the expected Const. GuardBitEquals { val: InsnId, expected: Const, reason: SideExitReason, state: InsnId, recompile: Option }, /// Side-exit if (val & mask) == 0 - GuardAnyBitSet { val: InsnId, mask: Const, mask_name: Option, reason: SideExitReason, state: InsnId }, + GuardAnyBitSet { val: InsnId, mask: Const, mask_name: Option, reason: SideExitReason, state: InsnId, recompile: Option }, /// Side-exit if (val & mask) != 0 GuardNoBitsSet { val: InsnId, mask: Const, mask_name: Option, reason: SideExitReason, state: InsnId }, /// Side-exit if left is not greater than or equal to right (both operands are C long). @@ -2197,8 +2224,15 @@ impl<'a> std::fmt::Display for InsnPrinter<'a> { } return Ok(()) }, - Insn::GuardAnyBitSet { val, mask, mask_name: Some(name), .. } => { write!(f, "GuardAnyBitSet {val}, {name}={}", mask.print(self.ptr_map)) }, - Insn::GuardAnyBitSet { val, mask, .. } => { write!(f, "GuardAnyBitSet {val}, {}", mask.print(self.ptr_map)) }, + Insn::GuardAnyBitSet { val, mask, mask_name, recompile, .. } => { + let mask = mask.print(self.ptr_map); + let recompile = if recompile.is_some() { " recompile" } else { "" }; + if let Some(name) = mask_name { + write!(f, "GuardAnyBitSet {val}, {name}={mask}{recompile}") + } else { + write!(f, "GuardAnyBitSet {val}, {mask}{recompile}") + } + }, Insn::GuardNoBitsSet { val, mask, mask_name: Some(name), .. } => { write!(f, "GuardNoBitsSet {val}, {name}={}", mask.print(self.ptr_map)) }, Insn::GuardNoBitsSet { val, mask, .. } => { write!(f, "GuardNoBitsSet {val}, {}", mask.print(self.ptr_map)) }, Insn::GuardLess { left, right, .. } => write!(f, "GuardLess {left}, {right}"), @@ -4907,16 +4941,28 @@ impl Function { } } + fn getivar_fallback_reason(resolution: ReceiverTypeResolution, ic: *const iseq_inline_iv_cache_entry) -> Counter { + match resolution { + ReceiverTypeResolution::Megamorphic => Counter::getivar_fallback_megamorphic, + ReceiverTypeResolution::SkewedMegamorphic { .. } => Counter::getivar_fallback_skewed_megamorphic, + ReceiverTypeResolution::Polymorphic => Counter::getivar_fallback_polymorphic, + ReceiverTypeResolution::NoProfile if ic.is_null() => Counter::getivar_fallback_no_profile_missing_ic, + ReceiverTypeResolution::NoProfile => Counter::getivar_fallback_no_profile, + _ => Counter::getivar_fallback_not_monomorphic, + } + } + fn optimize_getivar(&mut self) { for block in self.reverse_post_order() { let old_insns = std::mem::take(&mut self.blocks[block.0].insns); assert!(self.blocks[block.0].insns.is_empty()); for insn_id in old_insns { match self.find(insn_id) { - Insn::GetIvar { self_val, id, ic: _, state } => { + Insn::GetIvar { self_val, id, ic, state } => { let Some(recv_type) = self.profiled_type_of_at(self_val, state) else { - // No (monomorphic/skewed polymorphic) profile info - self.count(block, Counter::getivar_fallback_not_monomorphic); + let resolution = self.resolve_receiver_type_from_profile(self_val, state); + let counter = Self::getivar_fallback_reason(resolution, ic); + self.count(block, counter); self.push_insn_id(block, insn_id); continue; }; if recv_type.flags().is_immediate() { @@ -8274,7 +8320,7 @@ fn add_iseq_to_hir( // So to check for either of those cases we can use: val & 0x1 == 0x1 // Bail out if the block handler is neither ISEQ nor ifunc - fun.push_insn(unmodified_block, Insn::GuardAnyBitSet { val: block_handler, mask: Const::CUInt64(0x1), mask_name: None, reason: SideExitReason::BlockParamProxyFallbackMiss, state: exit_id }); + fun.push_insn(unmodified_block, Insn::GuardAnyBitSet { val: block_handler, mask: Const::CUInt64(0x1), mask_name: None, reason: SideExitReason::BlockParamProxyFallbackMiss, state: exit_id, recompile: Some(Recompile::ProfileBlockHandler) }); // TODO(Shopify/ruby#753): GC root, so we should be able to avoid unnecessary GC tracing let proxy_val = fun.push_insn(unmodified_block, Insn::Const { val: Const::Value(unsafe { rb_block_param_proxy }) }); let mut args = vec![proxy_val]; @@ -8287,7 +8333,7 @@ fn add_iseq_to_hir( [profiled_handler] => match profiled_handler { ProfiledBlockHandlerFamily::Nil => { let block_handler = fun.load_ep_env_field(unmodified_block, ep, FieldName::VM_ENV_DATA_INDEX_SPECVAL, VM_ENV_DATA_INDEX_SPECVAL, types::CInt64); - fun.push_insn(unmodified_block, Insn::GuardBitEquals { val: block_handler, expected: Const::CInt64(VM_BLOCK_HANDLER_NONE.into()), reason: SideExitReason::BlockParamProxyNotNil, state: exit_id, recompile: None }); + fun.push_insn(unmodified_block, Insn::GuardBitEquals { val: block_handler, expected: Const::CInt64(VM_BLOCK_HANDLER_NONE.into()), reason: SideExitReason::BlockParamProxyNotNil, state: exit_id, recompile: Some(Recompile::ProfileBlockHandler) }); let nil_val = fun.push_insn(unmodified_block, Insn::Const { val: Const::Value(Qnil) }); let mut args = vec![nil_val]; if let Some(local) = original_local { @@ -8304,7 +8350,7 @@ fn add_iseq_to_hir( // So to check for either of those cases we can use: val & 0x1 == 0x1 // Bail out if the block handler is neither ISEQ nor ifunc - fun.push_insn(unmodified_block, Insn::GuardAnyBitSet { val: block_handler, mask: Const::CUInt64(0x1), mask_name: None, reason: SideExitReason::BlockParamProxyNotIseqOrIfunc, state: exit_id }); + fun.push_insn(unmodified_block, Insn::GuardAnyBitSet { val: block_handler, mask: Const::CUInt64(0x1), mask_name: None, reason: SideExitReason::BlockParamProxyNotIseqOrIfunc, state: exit_id, recompile: Some(Recompile::ProfileBlockHandler) }); // TODO(Shopify/ruby#753): GC root, so we should be able to avoid unnecessary GC tracing let proxy_val = fun.push_insn(unmodified_block, Insn::Const { val: Const::Value(unsafe { rb_block_param_proxy }) }); let mut args = vec![proxy_val]; @@ -8324,7 +8370,7 @@ fn add_iseq_to_hir( return_type: types::BasicObject, elidable: true, }); - fun.push_insn(unmodified_block, Insn::GuardBitEquals { val: is_proc, expected: Const::Value(Qtrue), reason: SideExitReason::BlockParamProxyNotProc, state: exit_id, recompile: None }); + fun.push_insn(unmodified_block, Insn::GuardBitEquals { val: is_proc, expected: Const::Value(Qtrue), reason: SideExitReason::BlockParamProxyNotProc, state: exit_id, recompile: Some(Recompile::ProfileBlockHandler) }); let mut args = vec![proc_val]; if let Some(local) = original_local { args.push(local); diff --git a/zjit/src/hir/opt_tests.rs b/zjit/src/hir/opt_tests.rs index df0941d2e2f8ad..e60226bb6f91a8 100644 --- a/zjit/src/hir/opt_tests.rs +++ b/zjit/src/hir/opt_tests.rs @@ -5116,7 +5116,7 @@ mod hir_opt_tests { Jump bb6(v21, v21) bb5(): v23:CInt64 = LoadField v17, :VM_ENV_DATA_INDEX_SPECVAL@0x1003 - v24:CInt64 = GuardAnyBitSet v23, CUInt64(1) + v24:CInt64 = GuardAnyBitSet v23, CUInt64(1) recompile v25:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb6(v25, v10) bb6(v15:BasicObject, v16:BasicObject): @@ -5159,7 +5159,7 @@ mod hir_opt_tests { bb5(): v24:BasicObject = LoadField v18, :VM_ENV_DATA_INDEX_SPECVAL@0x1003 v25:BasicObject = CCall v24, :rb_obj_is_proc@0x1008 - v26:TrueClass = GuardBitEquals v25, Value(true) + v26:TrueClass = GuardBitEquals v25, Value(true) recompile Jump bb6(v24, v10) bb6(v16:BasicObject, v17:BasicObject): v29:BasicObject = Send v14, &block, :then, v16 # SendFallbackReason: Complex argument passing @@ -5168,6 +5168,66 @@ mod hir_opt_tests { "); } + #[test] + fn test_recompile_no_profile_getblockparamproxy() { + eval(" + def test(flag, &block) + if flag + 0.then(&block) + else + :skip + end + end + test(false) + test(false) + test(true) + "); + assert_snapshot!(hir_string("test"), @" + fn test@:3: + bb1(): + EntryPoint interpreter + v1:BasicObject = LoadSelf + v2:CPtr = LoadSP + v3:BasicObject = LoadField v2, :flag@0x1000 + v4:BasicObject = LoadField v2, :block@0x1001 + Jump bb3(v1, v3, v4) + bb2(): + EntryPoint JIT(0) + v7:BasicObject = LoadArg :self@0 + v8:BasicObject = LoadArg :flag@1 + v9:BasicObject = LoadArg :block@2 + Jump bb3(v7, v8, v9) + bb3(v11:BasicObject, v12:BasicObject, v13:BasicObject): + CheckInterrupts + v19:CBool = Test v12 + v20:Falsy = RefineType v12, Falsy + CondBranch v19, bb5(), bb4(v11, v20, v13) + bb5(): + v22:Truthy = RefineType v12, Truthy + v25:Fixnum[0] = Const Value(0) + v29:CPtr = GetEP 0 + v30:CUInt64 = LoadField v29, :VM_ENV_DATA_INDEX_FLAGS@0x1002 + v31:CBool = IsBlockParamModified v30 + CondBranch v31, bb6(), bb7() + bb6(): + v33:BasicObject = LoadField v29, :block@0x1003 + Jump bb8(v33, v33) + bb7(): + v35:CInt64 = LoadField v29, :VM_ENV_DATA_INDEX_SPECVAL@0x1004 + v36:CInt64[0] = GuardBitEquals v35, CInt64(0) recompile + v37:NilClass = Const Value(nil) + Jump bb8(v37, v13) + bb8(v27:BasicObject, v28:BasicObject): + v40:BasicObject = Send v25, &block, :then, v27 # SendFallbackReason: Complex argument passing + CheckInterrupts + Return v40 + bb4(v45:BasicObject, v46:Falsy, v47:BasicObject): + v51:StaticSymbol[:skip] = Const Value(VALUE(0x1008)) + CheckInterrupts + Return v51 + "); + } + #[test] fn test_getblockparamproxy_modified() { eval(" @@ -5213,7 +5273,7 @@ mod hir_opt_tests { Jump bb9(v36, v36) bb8(): v38:CInt64 = LoadField v32, :VM_ENV_DATA_INDEX_SPECVAL@0x1003 - v39:CInt64 = GuardAnyBitSet v38, CUInt64(1) + v39:CInt64 = GuardAnyBitSet v38, CUInt64(1) recompile v40:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb9(v40, v17) bb9(v30:BasicObject, v31:BasicObject): @@ -5264,7 +5324,7 @@ mod hir_opt_tests { Jump bb9(v31) bb8(): v33:CInt64 = LoadField v27, :VM_ENV_DATA_INDEX_SPECVAL@0x1002 - v34:CInt64 = GuardAnyBitSet v33, CUInt64(1) + v34:CInt64 = GuardAnyBitSet v33, CUInt64(1) recompile v35:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb9(v35) bb9(v26:BasicObject): @@ -9409,7 +9469,7 @@ mod hir_opt_tests { Jump bb6(v22, v22) bb5(): v24:CInt64 = LoadField v18, :VM_ENV_DATA_INDEX_SPECVAL@0x1003 - v25:CInt64 = GuardAnyBitSet v24, CUInt64(1) + v25:CInt64 = GuardAnyBitSet v24, CUInt64(1) recompile v26:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb6(v26, v10) bb6(v16:BasicObject, v17:BasicObject): @@ -9449,7 +9509,7 @@ mod hir_opt_tests { Jump bb6(v22, v22) bb5(): v24:CInt64 = LoadField v18, :VM_ENV_DATA_INDEX_SPECVAL@0x1003 - v25:CInt64[0] = GuardBitEquals v24, CInt64(0) + v25:CInt64[0] = GuardBitEquals v24, CInt64(0) recompile v26:NilClass = Const Value(nil) Jump bb6(v26, v10) bb6(v16:BasicObject, v17:BasicObject): @@ -9490,7 +9550,7 @@ mod hir_opt_tests { Jump bb6(v17) bb5(): v19:CInt64 = LoadField v13, :VM_ENV_DATA_INDEX_SPECVAL@0x1002 - v20:CInt64 = GuardAnyBitSet v19, CUInt64(1) + v20:CInt64 = GuardAnyBitSet v19, CUInt64(1) recompile v21:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb6(v21) bb6(v12:BasicObject): @@ -12982,7 +13042,7 @@ mod hir_opt_tests { Jump bb6(v22, v22) bb5(): v24:CInt64 = LoadField v18, :VM_ENV_DATA_INDEX_SPECVAL@0x1003 - v25:CInt64 = GuardAnyBitSet v24, CUInt64(1) + v25:CInt64 = GuardAnyBitSet v24, CUInt64(1) recompile v26:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb6(v26, v10) bb6(v16:BasicObject, v17:BasicObject): @@ -18860,7 +18920,7 @@ mod hir_opt_tests { Jump bb8(v41, v41) bb7(): v43:CInt64 = LoadField v37, :VM_ENV_DATA_INDEX_SPECVAL@0x104a - v44:CInt64 = GuardAnyBitSet v43, CUInt64(1) + v44:CInt64 = GuardAnyBitSet v43, CUInt64(1) recompile v45:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1050)) Jump bb8(v45, v54) bb8(v35:BasicObject, v36:BasicObject): @@ -18924,7 +18984,7 @@ mod hir_opt_tests { Jump bb8(v43, v43) bb7(): v45:CInt64 = LoadField v39, :VM_ENV_DATA_INDEX_SPECVAL@0x104a - v46:CInt64 = GuardAnyBitSet v45, CUInt64(1) + v46:CInt64 = GuardAnyBitSet v45, CUInt64(1) recompile v47:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1050)) Jump bb8(v47, v55) bb8(v37:BasicObject, v38:BasicObject): diff --git a/zjit/src/hir/tests.rs b/zjit/src/hir/tests.rs index dbe66a6bef1521..86e8dbb9dc9c53 100644 --- a/zjit/src/hir/tests.rs +++ b/zjit/src/hir/tests.rs @@ -2504,7 +2504,7 @@ pub(crate) mod hir_build_tests { Jump bb6(v40, v40) bb5(): v42:CInt64 = LoadField v36, :VM_ENV_DATA_INDEX_SPECVAL@0x1006 - v43:CInt64 = GuardAnyBitSet v42, CUInt64(1) + v43:CInt64 = GuardAnyBitSet v42, CUInt64(1) recompile v44:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb6(v44, v21) bb6(v34:BasicObject, v35:BasicObject): @@ -3460,7 +3460,7 @@ pub(crate) mod hir_build_tests { Jump bb6(v21, v21) bb5(): v23:CInt64 = LoadField v17, :VM_ENV_DATA_INDEX_SPECVAL@0x1003 - v24:CInt64 = GuardAnyBitSet v23, CUInt64(1) + v24:CInt64 = GuardAnyBitSet v23, CUInt64(1) recompile v25:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb6(v25, v10) bb6(v15:BasicObject, v16:BasicObject): @@ -3505,7 +3505,7 @@ pub(crate) mod hir_build_tests { bb5(): v24:BasicObject = LoadField v18, :VM_ENV_DATA_INDEX_SPECVAL@0x1003 v25:BasicObject = CCall v24, :rb_obj_is_proc@0x1008 - v26:TrueClass = GuardBitEquals v25, Value(true) + v26:TrueClass = GuardBitEquals v25, Value(true) recompile Jump bb6(v24, v10) bb6(v16:BasicObject, v17:BasicObject): v29:BasicObject = Send v14, &block, :then, v16 # SendFallbackReason: Uncategorized(send) @@ -3559,7 +3559,7 @@ pub(crate) mod hir_build_tests { Jump bb9(v36, v36) bb8(): v38:CInt64 = LoadField v32, :VM_ENV_DATA_INDEX_SPECVAL@0x1003 - v39:CInt64 = GuardAnyBitSet v38, CUInt64(1) + v39:CInt64 = GuardAnyBitSet v38, CUInt64(1) recompile v40:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb9(v40, v17) bb9(v30:BasicObject, v31:BasicObject): @@ -3612,7 +3612,7 @@ pub(crate) mod hir_build_tests { Jump bb9(v31) bb8(): v33:CInt64 = LoadField v27, :VM_ENV_DATA_INDEX_SPECVAL@0x1002 - v34:CInt64 = GuardAnyBitSet v33, CUInt64(1) + v34:CInt64 = GuardAnyBitSet v33, CUInt64(1) recompile v35:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb9(v35) bb9(v26:BasicObject): @@ -3885,7 +3885,7 @@ pub(crate) mod hir_build_tests { Jump bb6(v25, v25) bb5(): v27:CInt64 = LoadField v21, :VM_ENV_DATA_INDEX_SPECVAL@0x1004 - v28:CInt64 = GuardAnyBitSet v27, CUInt64(1) + v28:CInt64 = GuardAnyBitSet v27, CUInt64(1) recompile v29:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb6(v29, v13) bb6(v19:BasicObject, v20:BasicObject): @@ -3934,7 +3934,7 @@ pub(crate) mod hir_build_tests { Jump bb6(v40, v40) bb5(): v42:CInt64 = LoadField v36, :VM_ENV_DATA_INDEX_SPECVAL@0x1006 - v43:CInt64[0] = GuardBitEquals v42, CInt64(0) + v43:CInt64[0] = GuardBitEquals v42, CInt64(0) recompile v44:NilClass = Const Value(nil) Jump bb6(v44, v21) bb6(v34:BasicObject, v35:BasicObject): @@ -3979,7 +3979,7 @@ pub(crate) mod hir_build_tests { bb5(): v27:BasicObject = LoadField v21, :VM_ENV_DATA_INDEX_SPECVAL@0x1004 v28:BasicObject = CCall v27, :rb_obj_is_proc@0x1008 - v29:TrueClass = GuardBitEquals v28, Value(true) + v29:TrueClass = GuardBitEquals v28, Value(true) recompile Jump bb6(v27, v13) bb6(v19:BasicObject, v20:BasicObject): v32:HashExact = GuardType v12, HashExact @@ -4023,7 +4023,7 @@ pub(crate) mod hir_build_tests { bb5(): v27:BasicObject = LoadField v21, :VM_ENV_DATA_INDEX_SPECVAL@0x1004 v28:BasicObject = CCall v27, :rb_obj_is_proc@0x1008 - v29:TrueClass = GuardBitEquals v28, Value(true) + v29:TrueClass = GuardBitEquals v28, Value(true) recompile Jump bb6(v27, v13) bb6(v19:BasicObject, v20:BasicObject): v32:HashExact = GuardType v12, HashExact @@ -4076,7 +4076,7 @@ pub(crate) mod hir_build_tests { Jump bb6(v40, v40) bb5(): v42:CInt64 = LoadField v36, :VM_ENV_DATA_INDEX_SPECVAL@0x1006 - v43:CInt64[0] = GuardBitEquals v42, CInt64(0) + v43:CInt64[0] = GuardBitEquals v42, CInt64(0) recompile v44:NilClass = Const Value(nil) Jump bb6(v44, v21) bb6(v34:BasicObject, v35:BasicObject): @@ -4119,7 +4119,7 @@ pub(crate) mod hir_build_tests { Jump bb6(v25, v25) bb5(): v27:CInt64 = LoadField v21, :VM_ENV_DATA_INDEX_SPECVAL@0x1004 - v28:CInt64 = GuardAnyBitSet v27, CUInt64(1) + v28:CInt64 = GuardAnyBitSet v27, CUInt64(1) recompile v29:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb6(v29, v13) bb6(v19:BasicObject, v20:BasicObject): @@ -4819,7 +4819,7 @@ pub(crate) mod hir_build_tests { Jump bb7(v39, v39) bb6(): v41:CInt64 = LoadField v35, :VM_ENV_DATA_INDEX_SPECVAL@0x1006 - v42:CInt64 = GuardAnyBitSet v41, CUInt64(1) + v42:CInt64 = GuardAnyBitSet v41, CUInt64(1) recompile v43:ObjectSubclass[BlockParamProxy] = Const Value(VALUE(0x1008)) Jump bb7(v43, v22) bb7(v33:BasicObject, v34:BasicObject): diff --git a/zjit/src/profile.rs b/zjit/src/profile.rs index e42ad0326ec6f9..fd830c35a308f7 100644 --- a/zjit/src/profile.rs +++ b/zjit/src/profile.rs @@ -467,6 +467,29 @@ impl IseqProfile { entry.profiles_remaining == 0 } + /// Profile the block handler for a getblockparamproxy guard exit at runtime. + pub fn profile_getblockparamproxy_at(&mut self, iseq: IseqPtr, insn_idx: YarvInsnIdx, cfp: CfpPtr) -> bool { + let pc = unsafe { rb_iseq_pc_at_idx(iseq, insn_idx as u32) }; + let level = unsafe { pc.add(2).read() }.as_u32(); + + let entry = self.entry_mut(insn_idx); + if entry.profiles_remaining == 0 { + entry.profiles_remaining = get_option!(num_profiles); + } + if entry.opnd_types.is_empty() { + entry.opnd_types.resize(1, TypeDistribution::new()); + } + let ep = unsafe { get_cfp_ep_level(cfp, level) }; + let block_handler = unsafe { *ep.offset(VM_ENV_DATA_INDEX_SPECVAL as isize) }; + let untagged = unsafe { rb_vm_untag_block_handler(block_handler) }; + + let ty = ProfiledType::object(untagged); + VALUE::from(iseq).write_barrier(ty.class()); + entry.opnd_types[0].observe(ty); + entry.profiles_remaining = entry.profiles_remaining.saturating_sub(1); + entry.profiles_remaining == 0 + } + /// Get profiled operand types for a given instruction index pub fn get_operand_types(&self, insn_idx: YarvInsnIdx) -> Option<&[TypeDistribution]> { self.entry(insn_idx).map(|e| e.opnd_types.as_slice()).filter(|s| !s.is_empty()) diff --git a/zjit/src/stats.rs b/zjit/src/stats.rs index 1083dbd23c6cc6..7e20704bf32ad2 100644 --- a/zjit/src/stats.rs +++ b/zjit/src/stats.rs @@ -324,6 +324,11 @@ make_counters! { dynamic_getivar { // getivar_fallback_: Fallback reasons for dynamic getivar instructions getivar_fallback_not_monomorphic, + getivar_fallback_megamorphic, + getivar_fallback_skewed_megamorphic, + getivar_fallback_polymorphic, + getivar_fallback_no_profile_missing_ic, + getivar_fallback_no_profile, getivar_fallback_immediate, getivar_fallback_not_t_object, getivar_fallback_complex,