diff --git a/NEWS.md b/NEWS.md index c2154fd82321ae..d0a4de6c836051 100644 --- a/NEWS.md +++ b/NEWS.md @@ -223,7 +223,7 @@ They are still available on rubygems.org and can be installed with * net-imap 0.6.6 * 0.6.2 to [v0.6.3][net-imap-v0.6.3], [v0.6.4][net-imap-v0.6.4], [v0.6.4.1][net-imap-v0.6.4.1], [v0.6.5][net-imap-v0.6.5], [v0.6.6][net-imap-v0.6.6] * rbs 4.2.0 - * 3.10.0 to [v3.10.1][rbs-v3.10.1], [v3.10.2][rbs-v3.10.2], [v3.10.3][rbs-v3.10.3], [v3.10.4][rbs-v3.10.4], [v4.0.0.dev.1][rbs-v4.0.0.dev.1], [v4.0.0.dev.2][rbs-v4.0.0.dev.2], [v4.0.0.dev.3][rbs-v4.0.0.dev.3], [v4.0.0.dev.4][rbs-v4.0.0.dev.4], [v4.0.0.dev.5][rbs-v4.0.0.dev.5], [v4.0.0][rbs-v4.0.0], [v4.0.1.dev.1][rbs-v4.0.1.dev.1], [v4.0.1.dev.2][rbs-v4.0.1.dev.2], [v4.0.1][rbs-v4.0.1], [v4.0.2][rbs-v4.0.2], [v4.0.3][rbs-v4.0.3] + * 3.10.0 to [v3.10.1][rbs-v3.10.1], [v3.10.2][rbs-v3.10.2], [v3.10.3][rbs-v3.10.3], [v3.10.4][rbs-v3.10.4], [v4.0.0.dev.1][rbs-v4.0.0.dev.1], [v4.0.0.dev.2][rbs-v4.0.0.dev.2], [v4.0.0.dev.3][rbs-v4.0.0.dev.3], [v4.0.0.dev.4][rbs-v4.0.0.dev.4], [v4.0.0.dev.5][rbs-v4.0.0.dev.5], [v4.0.0][rbs-v4.0.0], [v4.0.1.dev.1][rbs-v4.0.1.dev.1], [v4.0.1.dev.2][rbs-v4.0.1.dev.2], [v4.0.1][rbs-v4.0.1], [v4.0.2][rbs-v4.0.2], [v4.0.3][rbs-v4.0.3], [v4.1.0.pre.1][rbs-v4.1.0.pre.1], [v4.1.0.pre.2][rbs-v4.1.0.pre.2], [v4.1.0][rbs-v4.1.0], [v4.1.1.pre.1][rbs-v4.1.1.pre.1], [v4.1.1][rbs-v4.1.1], [v4.1.2][rbs-v4.1.2], [v4.1.3][rbs-v4.1.3], [v4.2.0.pre.1][rbs-v4.2.0.pre.1], [v4.2.0][rbs-v4.2.0] * typeprof 0.32.0 * mutex_m 0.3.0 * bigdecimal 4.1.2 @@ -476,6 +476,15 @@ A lot of work has gone into making Ractors more stable, performant, and usable. [rbs-v4.0.1]: https://github.com/ruby/rbs/releases/tag/v4.0.1 [rbs-v4.0.2]: https://github.com/ruby/rbs/releases/tag/v4.0.2 [rbs-v4.0.3]: https://github.com/ruby/rbs/releases/tag/v4.0.3 +[rbs-v4.1.0.pre.1]: https://github.com/ruby/rbs/releases/tag/v4.1.0.pre.1 +[rbs-v4.1.0.pre.2]: https://github.com/ruby/rbs/releases/tag/v4.1.0.pre.2 +[rbs-v4.1.0]: https://github.com/ruby/rbs/releases/tag/v4.1.0 +[rbs-v4.1.1.pre.1]: https://github.com/ruby/rbs/releases/tag/v4.1.1.pre.1 +[rbs-v4.1.1]: https://github.com/ruby/rbs/releases/tag/v4.1.1 +[rbs-v4.1.2]: https://github.com/ruby/rbs/releases/tag/v4.1.2 +[rbs-v4.1.3]: https://github.com/ruby/rbs/releases/tag/v4.1.3 +[rbs-v4.2.0.pre.1]: https://github.com/ruby/rbs/releases/tag/v4.2.0.pre.1 +[rbs-v4.2.0]: https://github.com/ruby/rbs/releases/tag/v4.2.0 [bigdecimal-v4.1.0]: https://github.com/ruby/bigdecimal/releases/tag/v4.1.0 [bigdecimal-v4.1.1]: https://github.com/ruby/bigdecimal/releases/tag/v4.1.1 [bigdecimal-v4.1.2]: https://github.com/ruby/bigdecimal/releases/tag/v4.1.2 diff --git a/compile.c b/compile.c index 2ff207928a57e6..fcb884eb440b0f 100644 --- a/compile.c +++ b/compile.c @@ -1763,7 +1763,7 @@ iseq_set_exception_local_table(rb_iseq_t *iseq) { ISEQ_BODY(iseq)->local_table_size = numberof(rb_iseq_shared_exc_local_tbl); ISEQ_BODY(iseq)->local_table = rb_iseq_shared_exc_local_tbl; - ISEQ_BODY(iseq)->lvar_states = NULL; // $! is read-only, so don't need lvar_states + ISEQ_BODY(iseq)->lvar_states.list = NULL; // $! is read-only, so don't need lvar_states return COMPILE_OK; } @@ -1917,7 +1917,7 @@ update_lvar_state(const rb_iseq_t *iseq, int level, int idx) iseq = ISEQ_BODY(iseq)->parent_iseq; } - uint8_t *states = ISEQ_BODY(iseq)->lvar_states; + uint8_t *states = iseq_lvar_states(ISEQ_BODY(iseq)); int table_idx = ISEQ_BODY(iseq)->local_table_size - idx; switch (iseq_lvar_state_get(states, table_idx)) { case lvar_uninitialized: @@ -1937,14 +1937,16 @@ update_lvar_state(const rb_iseq_t *iseq, int level, int idx) static int iseq_set_parameters_lvar_state(const rb_iseq_t *iseq) { + uint8_t *states = iseq_lvar_states(ISEQ_BODY(iseq)); + for (unsigned int i=0; iparam.size; i++) { - iseq_lvar_state_set(ISEQ_BODY(iseq)->lvar_states, i, lvar_initialized); + iseq_lvar_state_set(states, i, lvar_initialized); } int lead_num = ISEQ_BODY(iseq)->param.lead_num; int opt_num = ISEQ_BODY(iseq)->param.opt_num; for (int i=0; ilvar_states, lead_num + i, lvar_uninitialized); + iseq_lvar_state_set(states, lead_num + i, lvar_uninitialized); } return COMPILE_OK; @@ -2310,7 +2312,13 @@ iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl, const NODE * MEMCPY(ids, tbl->ids + offset, ID, size); ISEQ_BODY(iseq)->local_table = ids; - ISEQ_BODY(iseq)->lvar_states = ZALLOC_N(uint8_t, ISEQ_LVAR_STATES_BUFLEN(size)); + if (ISEQ_LVAR_STATES_EMBED_P(size)) { + /* states are embedded in the body; zero them out */ + memset(ISEQ_BODY(iseq)->lvar_states.single, 0, sizeof(ISEQ_BODY(iseq)->lvar_states.single)); + } + else { + ISEQ_BODY(iseq)->lvar_states.list = ZALLOC_N(uint8_t, ISEQ_LVAR_STATES_BUFLEN(size)); + } } ISEQ_BODY(iseq)->local_table_size = size; @@ -13509,19 +13517,28 @@ ibf_dump_lvar_states(struct ibf_dump *dump, const rb_iseq_t *iseq) const struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); const int size = ISEQ_LVAR_STATES_BUFLEN(body->local_table_size); IBF_W_ALIGN(uint8_t); - return ibf_dump_write(dump, body->lvar_states, sizeof(uint8_t) * (body->lvar_states ? size : 0)); + if (iseq_has_lvar_states_p(body)) { + return ibf_dump_write(dump, iseq_lvar_states(body), sizeof(uint8_t) * size); + } + else { + return ibf_dump_write(dump, NULL, 0); + } } -static uint8_t * -ibf_load_lvar_states(const struct ibf_load *load, ibf_offset_t lvar_states_offset, int size, const ID *local_table) +static void +ibf_load_lvar_states(const struct ibf_load *load, struct rb_iseq_constant_body *load_body, ibf_offset_t lvar_states_offset, int size, const ID *local_table) { if (local_table == rb_iseq_shared_exc_local_tbl || size <= 0) { - return NULL; + load_body->lvar_states.list = NULL; + } + else if (ISEQ_LVAR_STATES_EMBED_P((unsigned int)size)) { + ibf_offset_t pos = lvar_states_offset; + const int len = sizeof(uint8_t) * ISEQ_LVAR_STATES_BUFLEN(size); + memcpy(load_body->lvar_states.single, ibf_load_ptr(load, &pos, len), len); } else { - uint8_t *states = IBF_R(lvar_states_offset, uint8_t, ISEQ_LVAR_STATES_BUFLEN(size)); - return states; + load_body->lvar_states.list = IBF_R(lvar_states_offset, uint8_t, ISEQ_LVAR_STATES_BUFLEN(size)); } } @@ -14105,7 +14122,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) load_body->insns_info.body = ibf_load_insns_info_body(load, insns_info_body_offset, insns_info_size); load_body->insns_info.positions_or_succ_index_table.positions = ibf_load_insns_info_positions(load, insns_info_positions_offset, insns_info_size); load_body->local_table = ibf_load_local_table(load, local_table_offset, local_table_size); - load_body->lvar_states = ibf_load_lvar_states(load, lvar_states_offset, local_table_size, load_body->local_table); + ibf_load_lvar_states(load, load_body, lvar_states_offset, local_table_size, load_body->local_table); ibf_load_catch_table(load, catch_table_offset, catch_table_size, iseq); const rb_iseq_t *parent_iseq = ibf_load_iseq(load, (const rb_iseq_t *)(VALUE)parent_iseq_index); diff --git a/ext/io/console/depend b/ext/io/console/depend index 2729ec9a6c3c4d..e75559610faa1e 100644 --- a/ext/io/console/depend +++ b/ext/io/console/depend @@ -1,21 +1,3 @@ -# mkdepend: depends win32_vk.inc => $(VK_HEADER) - # AUTOGENERATED DEPENDENCIES START console.o: console.c # AUTOGENERATED DEPENDENCIES END - -win32_vk.inc: win32_vk.list $(srcdir)/extract-vk.rb - -.list.inc: - ( \ - $(RUBY) $(srcdir)/extract-vk.rb $< && \ - gperf --ignore-case -L ANSI-C -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k* $< \ - | sed -f $(top_srcdir)/tool/gperf.sed \ - ) > $(@F) - -.SUFFIXES: .chksum .list .inc - -.list.chksum: - @$(RUBY) -I$(top_srcdir)/tool -rchecksum \ - -e "Checksum.update(ARGV) {|k|k.copy(k.target) rescue k.make(k.target)}" \ - -- --make=$(MAKE) -I$(srcdir) $( 60 code.last << " x(#{n})z" end puts ["#define EACH_VK(x,z)", code].join(" \\\n "), "" +IO.popen(["gperf", *ARGV], "r+") do |f| + w = Thread.start { + f.puts source + f.close_write + } + puts f.read.sub(/^\w*hash .*\{(?m:.*?)\n\}/) { + $&.sub!(" hval = ", " hval = (unsigned int)") + } + w.join +end diff --git a/ext/io/console/win32_vk.mk b/ext/io/console/win32_vk.mk new file mode 100644 index 00000000000000..97757a05e429fd --- /dev/null +++ b/ext/io/console/win32_vk.mk @@ -0,0 +1,13 @@ +win32_vk.inc: win32_vk.list $(srcdir)/extract-vk.rb + +.list.inc: + $(Q)$(RUBY) $(srcdir)/extract-vk.rb $< \ + --ignore-case -L ANSI-C -E -C -P -p -j1 -i 1 -g -o -t -K ofs -N console_win32_vk -k* \ + > $(@F) + +.SUFFIXES: .chksum .list .inc + +.list.chksum: + @$(RUBY) -I$(top_srcdir)/tool -rchecksum \ + -e "Checksum.update(ARGV) {|k|k.copy(k.target) rescue k.make(k.target)}" \ + -- --make=$(MAKE) -I$(srcdir) $(local_table != rb_iseq_shared_exc_local_tbl)) { SIZED_FREE_N(body->local_table, body->local_table_size); } - SIZED_FREE_N(body->lvar_states, ISEQ_LVAR_STATES_BUFLEN(body->local_table_size)); + if (!ISEQ_LVAR_STATES_EMBED_P(body->local_table_size)) { + SIZED_FREE_N(body->lvar_states.list, ISEQ_LVAR_STATES_BUFLEN(body->local_table_size)); + } compile_data_free(ISEQ_COMPILE_DATA(iseq)); if (body->outer_variables) rb_id_table_free(body->outer_variables); @@ -591,7 +593,9 @@ rb_iseq_memsize(const rb_iseq_t *iseq) size += body->iseq_size * sizeof(VALUE); size += body->insns_info.size * (sizeof(struct iseq_insn_info_entry) + sizeof(unsigned int)); size += body->local_table_size * sizeof(ID); // body->local_table - if (body->lvar_states) size += ISEQ_LVAR_STATES_BUFLEN(body->local_table_size) * sizeof(uint8_t); + if (!ISEQ_LVAR_STATES_EMBED_P(body->local_table_size) && body->lvar_states.list) { + size += ISEQ_LVAR_STATES_BUFLEN(body->local_table_size) * sizeof(uint8_t); + } size += ISEQ_MBITS_BUFLEN(body->iseq_size) * ISEQ_MBITS_SIZE; if (body->catch_table) { size += iseq_catch_table_bytes(body->catch_table->size); diff --git a/iseq.h b/iseq.h index e75e16788f4ab3..7c68038c15c1f7 100644 --- a/iseq.h +++ b/iseq.h @@ -29,6 +29,7 @@ RUBY_EXTERN const int ruby_api_version[]; #define ISEQ_LVAR_STATE_BITS 2 #define ISEQ_LVAR_STATES_PER_BYTE (CHAR_BIT / ISEQ_LVAR_STATE_BITS) #define ISEQ_LVAR_STATES_BUFLEN(size) roomof(size, ISEQ_LVAR_STATES_PER_BYTE) +#define ISEQ_LVAR_STATES_EMBED_P(size) (ISEQ_LVAR_STATES_BUFLEN(size) <= sizeof(uint8_t *)) STATIC_ASSERT(lvar_state_fits_in_iseq_lvar_state_bits, lvar_reassigned < (1 << ISEQ_LVAR_STATE_BITS)); static inline enum lvar_state @@ -58,6 +59,23 @@ typedef void (*rb_iseq_callback)(const rb_iseq_t *, void *); extern const ID rb_iseq_shared_exc_local_tbl[]; +static inline bool +iseq_has_lvar_states_p(const struct rb_iseq_constant_body *body) +{ + return body->local_table_size > 0 && body->local_table != rb_iseq_shared_exc_local_tbl; +} + +static inline uint8_t * +iseq_lvar_states(const struct rb_iseq_constant_body *body) +{ + if (ISEQ_LVAR_STATES_EMBED_P(body->local_table_size)) { + return (uint8_t *)body->lvar_states.single; + } + else { + return body->lvar_states.list; + } +} + /* Ensure body->variable is allocated, returning the struct. */ struct rb_iseq_variable *rb_iseq_variable_ensure(rb_iseq_t *iseq); diff --git a/tool/test/test_mkdepend.rb b/tool/test/test_mkdepend.rb index 763fc7873fe53a..ee4e4d800b0480 100644 --- a/tool/test/test_mkdepend.rb +++ b/tool/test/test_mkdepend.rb @@ -336,8 +336,6 @@ def test_virtual_dependencies_are_declared %w[eventids1.h {$(VPATH)}eventids1.c], ripper.dependencies['eventids1.c'], ) - console = mkdepend.dependency_declarations('ext/io/console/depend') - assert_equal(%w[$(VK_HEADER)], console.dependencies['win32_vk.inc']) assert_include( mkdepend.dependency_targets('ext/socket/depend'), 'constdefs.h', diff --git a/vm.c b/vm.c index 67b44c100614bb..d1084a851bfb4b 100644 --- a/vm.c +++ b/vm.c @@ -1500,7 +1500,7 @@ env_copy(const VALUE *src_ep, VALUE read_only_variables) for (unsigned int j=0; jlocal_table_size; j++) { if (id == body->local_table[j]) { // check reassignment - if (iseq_lvar_state_get(body->lvar_states, j) == lvar_reassigned) { + if (iseq_lvar_state_get(iseq_lvar_states(body), j) == lvar_reassigned) { VALUE name = rb_id2str(id); VALUE msg = rb_sprintf("cannot make a shareable Proc because " "the outer variable '%" PRIsVALUE "' may be reassigned.", name); diff --git a/vm_core.h b/vm_core.h index fc64d278c65b50..a1e6bfac431ff6 100644 --- a/vm_core.h +++ b/vm_core.h @@ -524,7 +524,10 @@ struct rb_iseq_constant_body { const ID *local_table; /* must free */ - uint8_t *lvar_states; + union { + uint8_t *list; + uint8_t single[sizeof(uint8_t *)]; + } lvar_states; /* catch table */ struct iseq_catch_table *catch_table; diff --git a/zjit/src/cruby_bindings.inc.rs b/zjit/src/cruby_bindings.inc.rs index 0821ed934d5ac1..4bb6e5bc8a38ab 100644 --- a/zjit/src/cruby_bindings.inc.rs +++ b/zjit/src/cruby_bindings.inc.rs @@ -1282,6 +1282,12 @@ pub union rb_iseq_constant_body_iseq_insn_info__bindgen_ty_1 { #[repr(C)] #[derive(Copy, Clone)] pub union rb_iseq_constant_body__bindgen_ty_1 { + pub list: *mut u8, + pub single: [u8; 8usize], +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union rb_iseq_constant_body__bindgen_ty_2 { pub list: *mut iseq_bits_t, pub single: iseq_bits_t, }