From 319afed20fba8f9b44611d16e4930260f7b56b86 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Mon, 19 Oct 2020 16:47:32 +0900 Subject: [PATCH 01/41] Use language TLS specifier if it is possible. To access TLS, it is faster to use language TLS specifier instead of using pthread_get/setspecific functions. Original proposal is: Use native thread locals. #3665 --- ractor.h | 8 ++++++++ thread_pthread.c | 16 ++++++++++++++++ thread_pthread.h | 23 +++++++++++++++++++++++ thread_win32.h | 4 ++++ vm.c | 19 +++++++++++++++++++ vm_core.h | 10 ++++++++-- 6 files changed, 78 insertions(+), 2 deletions(-) diff --git a/ractor.h b/ractor.h index 4cd89522a7..d3de06b559 100644 --- a/ractor.h +++ b/ractor.h @@ -205,7 +205,15 @@ rb_ractor_thread_switch(rb_ractor_t *cr, rb_thread_t *th) static inline void rb_ractor_set_current_ec(rb_ractor_t *cr, rb_execution_context_t *ec) { +#ifdef RB_THREAD_LOCAL_SPECIFIER + #if __APPLE__ + rb_current_ec_set(ec); + #else + ruby_current_ec = ec; + #endif +#else native_tls_set(ruby_current_ec_key, ec); +#endif if (cr->threads.running_ec != ec) { if (0) fprintf(stderr, "rb_ractor_set_current_ec ec:%p->%p\n", diff --git a/thread_pthread.c b/thread_pthread.c index 427897cfd8..71667aec69 100644 --- a/thread_pthread.c +++ b/thread_pthread.c @@ -550,7 +550,11 @@ native_cond_timeout(rb_nativethread_cond_t *cond, const rb_hrtime_t rel) #define native_cleanup_push pthread_cleanup_push #define native_cleanup_pop pthread_cleanup_pop +#ifdef RB_THREAD_LOCAL_SPECIFIER +static RB_THREAD_LOCAL_SPECIFIER rb_thread_t *ruby_native_thread; +#else static pthread_key_t ruby_native_thread_key; +#endif static void null_func(int i) @@ -561,7 +565,11 @@ null_func(int i) static rb_thread_t * ruby_thread_from_native(void) { +#ifdef RB_THREAD_LOCAL_SPECIFIER + return ruby_native_thread; +#else return pthread_getspecific(ruby_native_thread_key); +#endif } static int @@ -570,7 +578,12 @@ ruby_thread_set_native(rb_thread_t *th) if (th && th->ec) { rb_ractor_set_current_ec(th->ractor, th->ec); } +#ifdef RB_THREAD_LOCAL_SPECIFIER + ruby_native_thread = th; + return 1; +#else return pthread_setspecific(ruby_native_thread_key, th) == 0; +#endif } static void native_thread_init(rb_thread_t *th); @@ -587,12 +600,15 @@ Init_native_thread(rb_thread_t *th) if (r) condattr_monotonic = NULL; } #endif + +#ifndef RB_THREAD_LOCAL_SPECIFIER if (pthread_key_create(&ruby_native_thread_key, 0) == EAGAIN) { rb_bug("pthread_key_create failed (ruby_native_thread_key)"); } if (pthread_key_create(&ruby_current_ec_key, 0) == EAGAIN) { rb_bug("pthread_key_create failed (ruby_current_ec_key)"); } +#endif th->thread_id = pthread_self(); ruby_thread_set_native(th); fill_thread_id_str(th); diff --git a/thread_pthread.h b/thread_pthread.h index d14857b05a..fa375b3e55 100644 --- a/thread_pthread.h +++ b/thread_pthread.h @@ -83,6 +83,14 @@ typedef struct rb_global_vm_lock_struct { int wait_yield; } rb_global_vm_lock_t; + +#if __STDC_VERSION__ >= 201112 + #define RB_THREAD_LOCAL_SPECIFIER _Thread_local +#elif defined(__GNUC__) + /* note that ICC (linux) and Clang are covered by __GNUC__ */ + #define RB_THREAD_LOCAL_SPECIFIER __thread +#else + typedef pthread_key_t native_tls_key_t; static inline void * @@ -102,5 +110,20 @@ native_tls_set(native_tls_key_t key, void *ptr) rb_bug("pthread_setspecific error"); } } +#endif + +RUBY_SYMBOL_EXPORT_BEGIN +#ifdef RB_THREAD_LOCAL_SPECIFIER + #if __APPLE__ + // on Darwin, TLS can not be accessed across .so + struct rb_execution_context_struct *rb_current_ec(); + void rb_current_ec_set(struct rb_execution_context_struct *); + #else + RUBY_EXTERN RB_THREAD_LOCAL_SPECIFIER struct rb_execution_context_struct *ruby_current_ec; + #endif +#else + RUBY_EXTERN native_tls_key_t ruby_current_ec_key; +#endif +RUBY_SYMBOL_EXPORT_END #endif /* RUBY_THREAD_PTHREAD_H */ diff --git a/thread_win32.h b/thread_win32.h index 0d95731587..cdcc159b2d 100644 --- a/thread_win32.h +++ b/thread_win32.h @@ -63,4 +63,8 @@ void rb_native_cond_timedwait(rb_nativethread_cond_t *cond, rb_nativethread_lock void rb_native_cond_initialize(rb_nativethread_cond_t *cond); void rb_native_cond_destroy(rb_nativethread_cond_t *cond); +RUBY_SYMBOL_EXPORT_BEGIN +RUBY_EXTERN native_tls_key_t ruby_current_ec_key; +RUBY_SYMBOL_EXPORT_END + #endif /* RUBY_THREAD_WIN32_H */ diff --git a/vm.c b/vm.c index 77a0659dd1..879814a14b 100644 --- a/vm.c +++ b/vm.c @@ -379,7 +379,26 @@ VALUE rb_block_param_proxy; #define ruby_vm_redefined_flag GET_VM()->redefined_flag VALUE ruby_vm_const_missing_count = 0; rb_vm_t *ruby_current_vm_ptr = NULL; + +#ifdef RB_THREAD_LOCAL_SPECIFIER +RB_THREAD_LOCAL_SPECIFIER rb_execution_context_t *ruby_current_ec; + +#ifdef __APPLE__ + rb_execution_context_t * + rb_current_ec(void) + { + return ruby_current_ec; + } + void + rb_current_ec_set(rb_execution_context_t *ec) + { + ruby_current_ec = ec; + } +#endif + +#else native_tls_key_t ruby_current_ec_key; +#endif rb_event_flag_t ruby_vm_event_flags; rb_event_flag_t ruby_vm_event_enabled_global_flags; diff --git a/vm_core.h b/vm_core.h index 73b6be52f6..f644e8a6bc 100644 --- a/vm_core.h +++ b/vm_core.h @@ -1721,8 +1721,6 @@ RUBY_EXTERN rb_event_flag_t ruby_vm_event_flags; RUBY_EXTERN rb_event_flag_t ruby_vm_event_enabled_global_flags; RUBY_EXTERN unsigned int ruby_vm_event_local_num; -RUBY_EXTERN native_tls_key_t ruby_current_ec_key; - RUBY_SYMBOL_EXPORT_END #define GET_VM() rb_current_vm() @@ -1764,7 +1762,15 @@ rb_ec_vm_ptr(const rb_execution_context_t *ec) static inline rb_execution_context_t * rb_current_execution_context(void) { +#ifdef RB_THREAD_LOCAL_SPECIFIER + #if __APPLE__ + rb_execution_context_t *ec = rb_current_ec(); + #else + rb_execution_context_t *ec = ruby_current_ec; + #endif +#else rb_execution_context_t *ec = native_tls_get(ruby_current_ec_key); +#endif VM_ASSERT(ec != NULL); return ec; } From dac3677469158f0c7fd3e86a9d6969f80153628c Mon Sep 17 00:00:00 2001 From: git Date: Tue, 20 Oct 2020 01:05:27 +0900 Subject: [PATCH 02/41] * 2020-10-20 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 69a7b2efd7..0627a937c0 100644 --- a/version.h +++ b/version.h @@ -16,7 +16,7 @@ #define RUBY_RELEASE_YEAR 2020 #define RUBY_RELEASE_MONTH 10 -#define RUBY_RELEASE_DAY 19 +#define RUBY_RELEASE_DAY 20 #include "ruby/version.h" From a76a30724dfdfd26938960d2f756b4d97f8d855e Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Tue, 20 Oct 2020 01:34:17 +0900 Subject: [PATCH 03/41] Revert "reduce lock for encoding" This reverts commit de17e2dea137bc5ba9f00e3acec32792d0dbb2eb. This patch can introduce race condition because of conflicting read/write access for enc_table::default_list. Maybe we need to freeze default_list at the end of Init_encdb() in enc/encdb.c. --- encoding.c | 125 +++++++++++++++++++++++------------------------------ 1 file changed, 53 insertions(+), 72 deletions(-) diff --git a/encoding.c b/encoding.c index cd3738426a..7f798cd78d 100644 --- a/encoding.c +++ b/encoding.c @@ -68,11 +68,9 @@ struct rb_encoding_entry { }; static struct enc_table { - // default_list + additional_list - struct rb_encoding_entry default_list[DEFAULT_ENCODING_LIST_CAPA]; - struct rb_encoding_entry *additional_list; - int additional_list_size; + struct rb_encoding_entry *list; int count; + int size; st_table *names; } global_enc_table; @@ -350,54 +348,24 @@ rb_find_encoding(VALUE enc) } static int -enc_table_expand(struct enc_table *enc_table, const int newsize) +enc_table_expand(struct enc_table *enc_table, int newsize) { - if (newsize <= DEFAULT_ENCODING_LIST_CAPA) { - // ok - } - else { - int add_size = newsize - DEFAULT_ENCODING_LIST_CAPA; - if (add_size <= enc_table->additional_list_size) { - // ok - } - else { - struct rb_encoding_entry *ent; - add_size = (add_size + 7) / 8 * 8; + struct rb_encoding_entry *ent; + int count = newsize; - if (enc_table->additional_list == NULL) { - ent = enc_table->additional_list = ALLOC_N(struct rb_encoding_entry, add_size); - } - else { - ent = REALLOC_N(enc_table->additional_list, struct rb_encoding_entry, add_size); - } - - memset(ent + enc_table->additional_list_size, 0, sizeof(*ent)*(add_size - enc_table->additional_list_size)); - enc_table->additional_list = ent; - enc_table->additional_list_size = add_size; - } - } - - return newsize; -} - -static struct rb_encoding_entry * -enc_entry_at(struct enc_table *enc_table, int index) -{ - if (LIKELY(index < DEFAULT_ENCODING_LIST_CAPA)) { - return &enc_table->default_list[index]; - } - else { - struct rb_encoding_entry *e; - GLOBAL_ENC_TABLE_EVAL(enc_table, - e = &enc_table->additional_list[index - DEFAULT_ENCODING_LIST_CAPA]); - return e; - } + if (enc_table->size >= newsize) return newsize; + newsize = (newsize + 7) / 8 * 8; + ent = REALLOC_N(enc_table->list, struct rb_encoding_entry, newsize); + memset(ent + enc_table->size, 0, sizeof(*ent)*(newsize - enc_table->size)); + enc_table->list = ent; + enc_table->size = newsize; + return count; } static int enc_register_at(struct enc_table *enc_table, int index, const char *name, rb_encoding *base_encoding) { - struct rb_encoding_entry *ent = enc_entry_at(enc_table, index); + struct rb_encoding_entry *ent = &enc_table->list[index]; rb_raw_encoding *encoding; if (!valid_encoding_name_p(name)) return -1; @@ -441,18 +409,19 @@ static int enc_registered(struct enc_table *enc_table, const char *name); static rb_encoding * enc_from_index(struct enc_table *enc_table, int index) { - // do not need a lock - if (UNLIKELY(index < 0 || enc_table->count <= (index &= ENC_INDEX_MASK))) { return 0; } - return enc_entry_at(enc_table, index)->enc; + return enc_table->list[index].enc; } rb_encoding * rb_enc_from_index(int index) { - return enc_from_index(&global_enc_table, index); + rb_encoding *enc; + GLOBAL_ENC_TABLE_EVAL(enc_table, + enc = enc_from_index(enc_table, index)); + return enc; } int @@ -491,7 +460,7 @@ enc_registered(struct enc_table *enc_table, const char *name) st_data_t idx = 0; if (!name) return -1; - if (!enc_table->names) return -1; + if (!enc_table->list) return -1; if (st_lookup(enc_table->names, (st_data_t)name, &idx)) { return (int)idx; } @@ -523,9 +492,9 @@ enc_check_duplication(struct enc_table *enc_table, const char *name) static rb_encoding* set_base_encoding(struct enc_table *enc_table, int index, rb_encoding *base) { - struct rb_encoding_entry *entry = enc_entry_at(enc_table, index); - rb_encoding *enc = entry->enc; - entry->base = base; + rb_encoding *enc = enc_table->list[index].enc; + + enc_table->list[index].base = base; if (ENC_DUMMY_P(base)) ENC_SET_DUMMY((rb_raw_encoding *)enc); return enc; } @@ -552,7 +521,11 @@ rb_enc_set_base(const char *name, const char *orig) int rb_enc_set_dummy(int index) { - rb_encoding *enc = rb_enc_from_index(index); + rb_encoding *enc; + + GLOBAL_ENC_TABLE_EVAL(enc_table, + enc = enc_table->list[index].enc); + ENC_SET_DUMMY((rb_raw_encoding *)enc); return index; } @@ -642,10 +615,14 @@ rb_define_dummy_encoding(const char *name) { int index; - GLOBAL_ENC_TABLE_EVAL(enc_table, - index = enc_replicate(enc_table, name, rb_ascii8bit_encoding())); - rb_encoding *enc = rb_enc_from_index(index); - ENC_SET_DUMMY((rb_raw_encoding *)enc); + GLOBAL_ENC_TABLE_ENTER(enc_table); + { + index = enc_replicate(enc_table, name, rb_ascii8bit_encoding()); + rb_encoding *enc = enc_table->list[index].enc; + ENC_SET_DUMMY((rb_raw_encoding *)enc); + } + GLOBAL_ENC_TABLE_LEAVE(); + return index; } @@ -653,12 +630,17 @@ int rb_encdb_dummy(const char *name) { int index; - GLOBAL_ENC_TABLE_EVAL(enc_table, - index = enc_replicate_with_index(enc_table, name, - rb_ascii8bit_encoding(), - enc_registered(enc_table, name))); - rb_encoding *enc = rb_enc_from_index(index); - ENC_SET_DUMMY((rb_raw_encoding *)enc); + + GLOBAL_ENC_TABLE_ENTER(enc_table); + { + index = enc_replicate_with_index(enc_table, name, + rb_ascii8bit_encoding(), + enc_registered(enc_table, name)); + rb_encoding *enc = enc_table->list[index].enc; + ENC_SET_DUMMY((rb_raw_encoding *)enc); + } + GLOBAL_ENC_TABLE_LEAVE(); + return index; } @@ -788,10 +770,9 @@ rb_enc_init(struct enc_table *enc_table) ENC_REGISTER(ASCII); ENC_REGISTER(UTF_8); ENC_REGISTER(US_ASCII); - - global_enc_ascii = enc_table->default_list[ENCINDEX_ASCII].enc; - global_enc_utf_8 = enc_table->default_list[ENCINDEX_UTF_8].enc; - global_enc_us_ascii = enc_table->default_list[ENCINDEX_US_ASCII].enc; + global_enc_ascii = enc_table->list[ENCINDEX_ASCII].enc; + global_enc_utf_8 = enc_table->list[ENCINDEX_UTF_8].enc; + global_enc_us_ascii = enc_table->list[ENCINDEX_US_ASCII].enc; #undef ENC_REGISTER #define ENCDB_REGISTER(name, enc) enc_register_at(enc_table, ENCINDEX_##enc, name, NULL) ENCDB_REGISTER("UTF-16BE", UTF_16BE); @@ -847,7 +828,7 @@ load_encoding(const char *name) else if ((idx = enc_registered(enc_table, name)) < 0) { idx = -1; } - else if (enc_autoload_p(enc_from_index(enc_table, idx))) { + else if (enc_autoload_p(enc_table->list[idx].enc)) { idx = -1; } } @@ -859,13 +840,13 @@ load_encoding(const char *name) static int enc_autoload_body(struct enc_table *enc_table, rb_encoding *enc) { - rb_encoding *base = enc_entry_at(enc_table, ENC_TO_ENCINDEX(enc))->base; + rb_encoding *base = enc_table->list[ENC_TO_ENCINDEX(enc)].base; if (base) { int i = 0; do { if (i >= enc_table->count) return -1; - } while (enc_from_index(enc_table, i) != base && (++i, 1)); + } while (enc_table->list[i].enc != base && (++i, 1)); if (enc_autoload_p(base)) { if (enc_autoload(base) < 0) return -1; } @@ -2207,7 +2188,7 @@ Init_Encoding(void) rb_gc_register_mark_object(list); for (i = 0; i < enc_table->count; ++i) { - rb_ary_push(list, enc_new(enc_from_index(enc_table, i))); + rb_ary_push(list, enc_new(enc_table->list[i].enc)); } rb_marshal_define_compat(rb_cEncoding, Qnil, 0, enc_m_loader); From 4a7dccf44f02fa471e848ec729393c257b97da4d Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Mon, 19 Oct 2020 20:56:08 -0700 Subject: [PATCH 04/41] Add a Ripper.lex test of :on_embexpr_end This is a weird use case of Ripper.lex which I'm not sure is supposed to be maintained, so I'm adding this test so that we can easily notice such changes. If we change the behavior, this will break the behavior of hamlit.gem v1 and code like https://github.com/haml/haml/pull/1043. --- test/ripper/test_lexer.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/ripper/test_lexer.rb b/test/ripper/test_lexer.rb index 1794773d89..3fc44234b9 100644 --- a/test/ripper/test_lexer.rb +++ b/test/ripper/test_lexer.rb @@ -138,4 +138,11 @@ class TestRipper::Lexer < Test::Unit::TestCase assert_equal pos, code.bytesize assert_equal expected.size, result.size end + + def test_trailing_on_embexpr_end + # This is useful for scanning a template engine literal `{ foo, bar: baz }` + # whose body inside brackes works like trailing method arguments, like Haml. + token = Ripper.lex("a( foo, bar: baz }").last + assert_equal [[1, 17], :on_embexpr_end, "}", state(:EXPR_ARG)], token + end end From c05e41035c01ab38bdb279601a08e17921bcdc8e Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Fri, 9 Oct 2020 10:16:59 +0900 Subject: [PATCH 05/41] Bundle typeprof gem as bundled gems --- common.mk | 2 +- gems/bundled_gems | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/common.mk b/common.mk index e3bf8f9428..10910d1775 100644 --- a/common.mk +++ b/common.mk @@ -1350,7 +1350,7 @@ test-bundled-gems-prepare: $(TEST_RUNNABLE)-test-bundled-gems-prepare no-test-bundled-gems-prepare: no-test-bundled-gems-precheck yes-test-bundled-gems-prepare: yes-test-bundled-gems-precheck $(XRUBY) -C "$(srcdir)" bin/gem install --no-document \ - --install-dir .bundle --conservative "bundler" "minitest:~> 5" "test-unit" "rake" "hoe" "yard" "pry" "packnga" "rexml" "json-schema" + --install-dir .bundle --conservative "bundler" "minitest:~> 5" "test-unit" "rake" "hoe" "yard" "pry" "packnga" "rexml" "json-schema" "rbs" PREPARE_BUNDLED_GEMS = test-bundled-gems-prepare test-bundled-gems: $(TEST_RUNNABLE)-test-bundled-gems diff --git a/gems/bundled_gems b/gems/bundled_gems index 486b11c2ee..87f046e3fe 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -6,3 +6,4 @@ test-unit 3.3.6 https://github.com/test-unit/test-unit 3.3.6 rexml 3.2.4 https://github.com/ruby/rexml rss 0.2.9 https://github.com/ruby/rss 0.2.9 rbs 0.13.1 https://github.com/ruby/rbs +typeprof 0.2.0 https://github.com/ruby/typeprof From 9ced5fae6df9e70506ddad822e15745884e365fd Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Tue, 20 Oct 2020 15:36:51 +0900 Subject: [PATCH 06/41] add a NEWS for Fiber#transfer --- NEWS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/NEWS.md b/NEWS.md index d39c379d01..559bd97f80 100644 --- a/NEWS.md +++ b/NEWS.md @@ -190,6 +190,7 @@ Outstanding ones only. * `Fiber#blocking?` tells whether the fiber is non-blocking. [[Feature #16786]] * `Fiber#backtrace` & `Fiber#backtrace_locations` provide per-fiber backtrace. [[Feature #16815]] + * The limitation of `Fiber#transfer` is relaxed. [Bug #17221] * Kernel From 99310e3eb56fbc85bb45119285812eb959448d0c Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Tue, 20 Oct 2020 10:46:43 +0900 Subject: [PATCH 07/41] Some global variables can be accessed from ractors Some global variables should be used from non-main Ractors. [Bug #17268] ```ruby # ractor-local (derived from created ractor): debug '$DEBUG' => $DEBUG, '$-d' => $-d, # ractor-local (derived from created ractor): verbose '$VERBOSE' => $VERBOSE, '$-w' => $-w, '$-W' => $-W, '$-v' => $-v, # process-local (readonly): other commandline parameters '$-p' => $-p, '$-l' => $-l, '$-a' => $-a, # process-local (readonly): getpid '$$' => $$, # thread local: process result '$?' => $?, # scope local: match '$~' => $~.inspect, '$&' => $&, '$`' => $`, '$\'' => $', '$+' => $+, '$1' => $1, # scope local: last line '$_' => $_, # scope local: last backtrace '$@' => $@, '$!' => $!, # ractor local: stdin, out, err '$stdin' => $stdin.inspect, '$stdout' => $stdout.inspect, '$stderr' => $stderr.inspect, ``` --- bootstraptest/test_ractor.rb | 59 ++++++++++++++++++++++++++++++++++++ common.mk | 3 ++ eval.c | 3 ++ io.c | 3 ++ process.c | 4 +++ ractor.c | 4 +++ ractor.h | 2 ++ re.c | 7 +++++ ruby.c | 50 ++++++++++++++++++++++++------ vm.c | 18 +++-------- vm_core.h | 2 +- 11 files changed, 131 insertions(+), 24 deletions(-) diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index eaa265fcfa..94570597ba 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -611,6 +611,65 @@ assert_equal 'ok', %q{ 'ok' } +# $DEBUG, $VERBOSE are Ractor local +assert_equal 'true', %q{ + $DEBUG = true + $VERBOSE = true + + def ractor_local_globals + /a(b)(c)d/ =~ 'abcd' # for $~ + `echo foo` + + { + # ractor-local (derived from created ractor): debug + '$DEBUG' => $DEBUG, + '$-d' => $-d, + + # ractor-local (derived from created ractor): verbose + '$VERBOSE' => $VERBOSE, + '$-w' => $-w, + '$-W' => $-W, + '$-v' => $-v, + + # process-local (readonly): other commandline parameters + '$-p' => $-p, + '$-l' => $-l, + '$-a' => $-a, + + # process-local (readonly): getpid + '$$' => $$, + + # thread local: process result + '$?' => $?, + + # scope local: match + '$~' => $~.inspect, + '$&' => $&, + '$`' => $`, + '$\'' => $', + '$+' => $+, + '$1' => $1, + + # scope local: last line + '$_' => $_, + + # scope local: last backtrace + '$@' => $@, + '$!' => $!, + + # ractor local: stdin, out, err + '$stdin' => $stdin.inspect, + '$stdout' => $stdout.inspect, + '$stderr' => $stderr.inspect, + } + end + + h = Ractor.new do + ractor_local_globals + end.take + ractor_local_globals == h #=> true +} + # selfs are different objects assert_equal 'false', %q{ r = Ractor.new do diff --git a/common.mk b/common.mk index 10910d1775..a8719ca4e6 100644 --- a/common.mk +++ b/common.mk @@ -10943,6 +10943,7 @@ re.$(OBJEXT): $(top_srcdir)/internal/imemo.h re.$(OBJEXT): $(top_srcdir)/internal/re.h re.$(OBJEXT): $(top_srcdir)/internal/static_assert.h re.$(OBJEXT): $(top_srcdir)/internal/string.h +re.$(OBJEXT): $(top_srcdir)/internal/variable.h re.$(OBJEXT): $(top_srcdir)/internal/warnings.h re.$(OBJEXT): {$(VPATH)}assert.h re.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -10955,9 +10956,11 @@ re.$(OBJEXT): {$(VPATH)}backward/2/long_long.h re.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h re.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h re.$(OBJEXT): {$(VPATH)}config.h +re.$(OBJEXT): {$(VPATH)}constant.h re.$(OBJEXT): {$(VPATH)}defines.h re.$(OBJEXT): {$(VPATH)}encindex.h re.$(OBJEXT): {$(VPATH)}encoding.h +re.$(OBJEXT): {$(VPATH)}id_table.h re.$(OBJEXT): {$(VPATH)}intern.h re.$(OBJEXT): {$(VPATH)}internal.h re.$(OBJEXT): {$(VPATH)}internal/anyargs.h diff --git a/eval.c b/eval.c index 87c048be3f..9a10cb46b1 100644 --- a/eval.c +++ b/eval.c @@ -2084,6 +2084,9 @@ Init_eval(void) rb_define_virtual_variable("$@", errat_getter, errat_setter); rb_define_virtual_variable("$!", errinfo_getter, 0); + rb_gvar_ractor_local("$@"); + rb_gvar_ractor_local("$!"); + rb_define_global_function("raise", f_raise, -1); rb_define_global_function("fail", f_raise, -1); diff --git a/io.c b/io.c index c986ffbc47..3b4ae6d60b 100644 --- a/io.c +++ b/io.c @@ -13543,6 +13543,7 @@ Init_IO(void) rb_define_hooked_variable("$\\", &rb_output_rs, 0, deprecated_str_setter); rb_define_virtual_variable("$_", get_LAST_READ_LINE, set_LAST_READ_LINE); + rb_gvar_ractor_local("$_"); rb_define_method(rb_cIO, "initialize_copy", rb_io_init_copy, 1); rb_define_method(rb_cIO, "reopen", rb_io_reopen, -1); @@ -13764,6 +13765,8 @@ Init_IO(void) ARGF.filename = rb_str_new2("-"); rb_define_hooked_variable("$-i", &argf, opt_i_get, opt_i_set); + rb_gvar_ractor_local("$-i"); + rb_define_hooked_variable("$*", &argf, argf_argv_getter, rb_gvar_readonly_setter); #if defined (_WIN32) || defined(__CYGWIN__) diff --git a/process.c b/process.c index 8abb3ea86f..90db3c5677 100644 --- a/process.c +++ b/process.c @@ -8445,6 +8445,10 @@ InitVM_process(void) #define rb_intern(str) rb_intern_const(str) rb_define_virtual_variable("$?", get_CHILD_STATUS, 0); rb_define_virtual_variable("$$", get_PROCESS_ID, 0); + + rb_gvar_ractor_local("$$"); + rb_gvar_ractor_local("$?"); + rb_define_global_function("exec", f_exec, -1); rb_define_global_function("fork", rb_f_fork, 0); rb_define_global_function("exit!", rb_f_exit_bang, -1); diff --git a/ractor.c b/ractor.c index 5bc65a0491..68ac5a25fe 100644 --- a/ractor.c +++ b/ractor.c @@ -1373,6 +1373,10 @@ ractor_create(rb_execution_context_t *ec, VALUE self, VALUE loc, VALUE name, VAL r->r_stdout = rb_io_prep_stdout(); r->r_stderr = rb_io_prep_stderr(); + rb_ractor_t *cr = rb_ec_ractor_ptr(ec); + r->verbose = cr->verbose; + r->debug = cr->debug; + rb_thread_create_ractor(r, args, block); RB_GC_GUARD(rv); diff --git a/ractor.h b/ractor.h index d3de06b559..1afd91b77c 100644 --- a/ractor.h +++ b/ractor.h @@ -125,6 +125,8 @@ struct rb_ractor_struct { VALUE r_stdin; VALUE r_stdout; VALUE r_stderr; + VALUE verbose; + VALUE debug; }; // rb_ractor_t is defined in vm_core.h rb_ractor_t *rb_ractor_main_alloc(void); diff --git a/re.c b/re.c index badd321782..020ba7b6d6 100644 --- a/re.c +++ b/re.c @@ -19,6 +19,7 @@ #include "internal/imemo.h" #include "internal/re.h" #include "internal/string.h" +#include "internal/variable.h" #include "regint.h" #include "ruby/encoding.h" #include "ruby/re.h" @@ -4052,6 +4053,12 @@ Init_Regexp(void) rb_define_virtual_variable("$'", postmatch_getter, 0); rb_define_virtual_variable("$+", last_paren_match_getter, 0); + rb_gvar_ractor_local("$~"); + rb_gvar_ractor_local("$&"); + rb_gvar_ractor_local("$`"); + rb_gvar_ractor_local("$'"); + rb_gvar_ractor_local("$+"); + rb_define_virtual_variable("$=", ignorecase_getter, ignorecase_setter); rb_define_virtual_variable("$KCODE", kcode_getter, kcode_setter); rb_define_virtual_variable("$-K", kcode_getter, kcode_setter); diff --git a/ruby.c b/ruby.c index 9ca980dfbd..4feae7757a 100644 --- a/ruby.c +++ b/ruby.c @@ -63,6 +63,7 @@ #include "ruby/thread.h" #include "ruby/util.h" #include "ruby/version.h" +#include "ruby/internal/error.h" #ifndef MAXPATHLEN # define MAXPATHLEN 1024 @@ -2021,6 +2022,10 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt) rb_define_readonly_boolean("$-l", opt->do_line); rb_define_readonly_boolean("$-a", opt->do_split); + rb_gvar_ractor_local("$-p"); + rb_gvar_ractor_local("$-l"); + rb_gvar_ractor_local("$-a"); + if ((rb_e_script = opt->e_script) != 0) { rb_gc_register_mark_object(opt->e_script); } @@ -2430,16 +2435,24 @@ forbid_setid(const char *s, const ruby_cmdline_options_t *opt) rb_raise(rb_eSecurityError, "no %s allowed while running setgid", s); } +static VALUE +verbose_getter(ID id, VALUE *ptr) +{ + return *rb_ruby_verbose_ptr(); +} + static void verbose_setter(VALUE val, ID id, VALUE *variable) { - *variable = RTEST(val) ? Qtrue : val; + *rb_ruby_verbose_ptr() = RTEST(val) ? Qtrue : val; } static VALUE -opt_W_getter(ID id, VALUE *variable) +opt_W_getter(ID id, VALUE *dmy) { - switch (*variable) { + VALUE v = *rb_ruby_verbose_ptr(); + + switch (v) { case Qnil: return INT2FIX(0); case Qfalse: @@ -2451,16 +2464,35 @@ opt_W_getter(ID id, VALUE *variable) } } +static VALUE +debug_getter(ID id, VALUE *dmy) +{ + return *rb_ruby_debug_ptr(); +} + +static void +debug_setter(VALUE val, ID id, VALUE *dmy) +{ + *rb_ruby_debug_ptr() = val; +} + /*! Defines built-in variables */ void ruby_prog_init(void) { - rb_define_hooked_variable("$VERBOSE", &ruby_verbose, 0, verbose_setter); - rb_define_hooked_variable("$-v", &ruby_verbose, 0, verbose_setter); - rb_define_hooked_variable("$-w", &ruby_verbose, 0, verbose_setter); - rb_define_hooked_variable("$-W", &ruby_verbose, opt_W_getter, rb_gvar_readonly_setter); - rb_define_variable("$DEBUG", &ruby_debug); - rb_define_variable("$-d", &ruby_debug); + rb_define_virtual_variable("$VERBOSE", verbose_getter, verbose_setter); + rb_define_virtual_variable("$-v", verbose_getter, verbose_setter); + rb_define_virtual_variable("$-w", verbose_getter, verbose_setter); + rb_define_virtual_variable("$-W", opt_W_getter, rb_gvar_readonly_setter); + rb_define_virtual_variable("$DEBUG", debug_getter, debug_setter); + rb_define_virtual_variable("$-d", debug_getter, debug_setter); + + rb_gvar_ractor_local("$VERBOSE"); + rb_gvar_ractor_local("$-v"); + rb_gvar_ractor_local("$-w"); + rb_gvar_ractor_local("$-W"); + rb_gvar_ractor_local("$DEBUG"); + rb_gvar_ractor_local("$-d"); rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0); rb_define_hooked_variable("$PROGRAM_NAME", &rb_progname, 0, set_arg0); diff --git a/vm.c b/vm.c index 879814a14b..ada33ae87b 100644 --- a/vm.c +++ b/vm.c @@ -3515,28 +3515,18 @@ Init_top_self(void) rb_define_alias(rb_singleton_class(rb_vm_top_self()), "inspect", "to_s"); } -static VALUE * -ruby_vm_verbose_ptr(rb_vm_t *vm) -{ - return &vm->verbose; -} - -static VALUE * -ruby_vm_debug_ptr(rb_vm_t *vm) -{ - return &vm->debug; -} - VALUE * rb_ruby_verbose_ptr(void) { - return ruby_vm_verbose_ptr(GET_VM()); + rb_ractor_t *cr = GET_RACTOR(); + return &cr->verbose; } VALUE * rb_ruby_debug_ptr(void) { - return ruby_vm_debug_ptr(GET_VM()); + rb_ractor_t *cr = GET_RACTOR(); + return &cr->debug; } /* iseq.c */ diff --git a/vm_core.h b/vm_core.h index f644e8a6bc..8525bfcf3e 100644 --- a/vm_core.h +++ b/vm_core.h @@ -633,7 +633,7 @@ typedef struct rb_vm_struct { struct list_head workqueue; /* <=> rb_workqueue_job.jnode */ rb_nativethread_lock_t workqueue_lock; - VALUE verbose, debug, orig_progname, progname; + VALUE orig_progname, progname; VALUE coverages; int coverage_mode; From 2bdbdc1580f52dc8d70a71b824238e0f20342dca Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Tue, 20 Oct 2020 11:21:49 +0900 Subject: [PATCH 08/41] add Ractor.shareable?(obj) This method returns obj is shareable or not. --- ractor.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/ractor.rb b/ractor.rb index 78980b2685..c825fbe0da 100644 --- a/ractor.rb +++ b/ractor.rb @@ -166,4 +166,11 @@ class Ractor close_incoming close_outgoing end + + # utility method + def self.shareable? obj + __builtin_cexpr! %q{ + rb_ractor_shareable_p(obj) ? Qtrue : Qfalse; + } + end end From ade411465dc054af5ff025531649b69134d74b56 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Tue, 20 Oct 2020 11:24:37 +0900 Subject: [PATCH 09/41] ObjectSpace.each_object with Ractors Unshareable objects should not be touched from multiple ractors so ObjectSpace.each_object should be restricted. On multi-ractor mode, ObjectSpace.each_object only iterates shareable objects. [Feature #17270] --- bootstraptest/test_ractor.rb | 9 +++++++++ gc.c | 6 ++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index 94570597ba..a02adb612a 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -823,6 +823,15 @@ assert_equal '[1, 4, 3, 2, 1]', %q{ counts.inspect } +# ObjectSpace.each_object can not handle unshareable objects with Ractors +assert_equal '0', %q{ + Ractor.new{ + n = 0 + ObjectSpace.each_object{|o| n += 1 unless Ractor.shareable?(o)} + n + }.take +} + ### ### Synchronization tests ### diff --git a/gc.c b/gc.c index 81d3bc2c27..f72d76e857 100644 --- a/gc.c +++ b/gc.c @@ -3292,8 +3292,10 @@ os_obj_of_i(void *vstart, void *vend, size_t stride, void *data) volatile VALUE v = (VALUE)p; if (!internal_object_p(v)) { if (!oes->of || rb_obj_is_kind_of(v, oes->of)) { - rb_yield(v); - oes->num++; + if (!rb_multi_ractor_p() || rb_ractor_shareable_p(v)) { + rb_yield(v); + oes->num++; + } } } } From 18cecda46e427362fa3447679e5d8a917b5d6cb6 Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Tue, 20 Oct 2020 16:00:35 +0900 Subject: [PATCH 10/41] range.c: Fix an exception message in rb_range_beg_len [Bug #17271] --- range.c | 7 ++----- test/ruby/test_array.rb | 3 +++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/range.c b/range.c index 17d29925f1..c019fcf2e0 100644 --- a/range.c +++ b/range.c @@ -1332,7 +1332,7 @@ rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp) VALUE rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err) { - long beg, end, origbeg, origend; + long beg, end; VALUE b, e; int excl; @@ -1341,8 +1341,6 @@ rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err) beg = NIL_P(b) ? 0 : NUM2LONG(b); end = NIL_P(e) ? -1 : NUM2LONG(e); if (NIL_P(e)) excl = 0; - origbeg = beg; - origend = end; if (beg < 0) { beg += len; if (beg < 0) @@ -1368,8 +1366,7 @@ rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err) out_of_range: if (err) { - rb_raise(rb_eRangeError, "%ld..%s%ld out of range", - origbeg, excl ? "." : "", origend); + rb_raise(rb_eRangeError, "%+"PRIsVALUE" out of range", range); } return Qnil; } diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index 5d1785220e..bc5d86354e 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -2381,6 +2381,9 @@ class TestArray < Test::Unit::TestCase assert_raise(ArgumentError) { [0].freeze[0, 0, 0] = 0 } assert_raise(TypeError) { [0][:foo] = 0 } assert_raise(FrozenError) { [0].freeze[:foo] = 0 } + + # [Bug #17271] + assert_raise_with_message(RangeError, "-7.. out of range") { [*0..5][-7..] = 1 } end def test_first2 From 67c25a34a7c70e3cec868472517b699b1e881857 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Tue, 20 Oct 2020 17:57:20 +0900 Subject: [PATCH 11/41] skip `echo foo` on Solaris On Solaris, it seems to access ENV in ``, so skip it now. ``` stderr output is not empty Exception `NameError' at bootstraptest.tmp.rb:7 - can not access non-sharable objects in constant Object::ENV by non-main Ractor. # terminated with exception (report_on_exception is true): bootstraptest.tmp.rb:7:in ``': can not access non-sharable objects in constant Object::ENV by non-main Ractor. (NameError) Exception `Ractor::RemoteError' at :130 - thrown by remote Ractor. :130:in `take': thrown by remote Ractor. (Ractor::RemoteError) from bootstraptest.tmp.rb:55:in `
' bootstraptest.tmp.rb:7:in ``': can not access non-sharable objects in constant Object::ENV by non-main Ractor. (NameError) from bootstraptest.tmp.rb:7:in `ractor_local_globals' from bootstraptest.tmp.rb:54:in `block in
' ``` --- bootstraptest/test_ractor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index a02adb612a..74edfa8cd6 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -618,7 +618,7 @@ assert_equal 'true', %q{ def ractor_local_globals /a(b)(c)d/ =~ 'abcd' # for $~ - `echo foo` + `echo foo` unless /solaris/ !~ RUBY_PLATFORM { # ractor-local (derived from created ractor): debug From f6680c9ad1b334f094144d788887cd33f7043f41 Mon Sep 17 00:00:00 2001 From: Hiroshi SHIBATA Date: Tue, 20 Oct 2020 21:33:02 +0900 Subject: [PATCH 12/41] Added rbs and typeprof to doc/* --- doc/maintainers.rdoc | 4 ++++ doc/standard_library.rdoc | 2 ++ 2 files changed, 6 insertions(+) diff --git a/doc/maintainers.rdoc b/doc/maintainers.rdoc index ef3fa932fc..ed510cce90 100644 --- a/doc/maintainers.rdoc +++ b/doc/maintainers.rdoc @@ -378,3 +378,7 @@ Zachary Scott (zzak) https://github.com/ruby/rexml [rss] https://github.com/ruby/rss +[rbs] + https://github.com/ruby/rbs +[typeprof] + http://github.com/ruby/typeprof diff --git a/doc/standard_library.rdoc b/doc/standard_library.rdoc index 75ffaf5d5c..ea786d50b2 100644 --- a/doc/standard_library.rdoc +++ b/doc/standard_library.rdoc @@ -115,3 +115,5 @@ Rake:: Ruby build program with capabilities similar to make Test::Unit:: A compatibility layer for MiniTest REXML:: An XML toolkit for Ruby RSS:: Family of libraries that support various formats of XML "feeds" +RBS:: RBS is a language to describe the structure of Ruby programs +TypeProf:: A type analysis tool for Ruby code based on abstract interpretation From 520e0916af0fe53a5ca57269a2bae50cc60e4241 Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Wed, 9 Sep 2020 15:24:22 +0200 Subject: [PATCH 13/41] Implement a freeze: parser option If set to true all parsed objects will be immediately frozen, and strings will be deduplicated if the Ruby implementation allows it. --- ext/json/extconf.rb | 1 + ext/json/parser/extconf.rb | 25 ++++++++ ext/json/parser/parser.c | 115 +++++++++++++++++++++------------- ext/json/parser/parser.h | 1 + ext/json/parser/parser.rl | 29 ++++++++- test/json/json_parser_test.rb | 21 +++++++ 6 files changed, 147 insertions(+), 45 deletions(-) diff --git a/ext/json/extconf.rb b/ext/json/extconf.rb index 7595d58a98..8a99b6a5c8 100644 --- a/ext/json/extconf.rb +++ b/ext/json/extconf.rb @@ -1,2 +1,3 @@ require 'mkmf' + create_makefile('json') diff --git a/ext/json/parser/extconf.rb b/ext/json/parser/extconf.rb index f7360d46b2..f832b56a61 100644 --- a/ext/json/parser/extconf.rb +++ b/ext/json/parser/extconf.rb @@ -3,4 +3,29 @@ require 'mkmf' have_func("rb_enc_raise", "ruby.h") +# checking if String#-@ (str_uminus) dedupes... ' +begin + a = -(%w(t e s t).join) + b = -(%w(t e s t).join) + if a.equal?(b) + $CFLAGS << ' -DSTR_UMINUS_DEDUPE=1 ' + else + $CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 ' + end +rescue NoMethodError + $CFLAGS << ' -DSTR_UMINUS_DEDUPE=0 ' +end + +# checking if String#-@ (str_uminus) directly interns frozen strings... ' +begin + s = rand.to_s.freeze + if (-s).equal?(s) && (-s.dup).equal?(s) + $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=1 ' + else + $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 ' + end +rescue NoMethodError + $CFLAGS << ' -DSTR_UMINUS_DEDUPE_FROZEN=0 ' +end + create_makefile 'json/ext/parser' diff --git a/ext/json/parser/parser.c b/ext/json/parser/parser.c index 6f0e4ace84..aaef53aace 100644 --- a/ext/json/parser/parser.c +++ b/ext/json/parser/parser.c @@ -97,7 +97,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class, i_array_class, i_decimal_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_aref, - i_leftshift, i_new, i_BigDecimal; + i_leftshift, i_new, i_BigDecimal, i_freeze, i_uminus; #line 126 "parser.rl" @@ -869,6 +869,10 @@ case 28: #line 292 "parser.rl" + if (json->freeze) { + OBJ_FREEZE(*result); + } + if (cs >= JSON_value_first_final) { return p; } else { @@ -877,7 +881,7 @@ case 28: } -#line 881 "parser.c" +#line 885 "parser.c" enum {JSON_integer_start = 1}; enum {JSON_integer_first_final = 3}; enum {JSON_integer_error = 0}; @@ -885,7 +889,7 @@ enum {JSON_integer_error = 0}; enum {JSON_integer_en_main = 1}; -#line 308 "parser.rl" +#line 312 "parser.rl" static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result) @@ -893,15 +897,15 @@ static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *res int cs = EVIL; -#line 897 "parser.c" +#line 901 "parser.c" { cs = JSON_integer_start; } -#line 315 "parser.rl" +#line 319 "parser.rl" json->memo = p; -#line 905 "parser.c" +#line 909 "parser.c" { if ( p == pe ) goto _test_eof; @@ -935,14 +939,14 @@ case 3: goto st0; goto tr4; tr4: -#line 305 "parser.rl" +#line 309 "parser.rl" { p--; {p++; cs = 4; goto _out;} } goto st4; st4: if ( ++p == pe ) goto _test_eof4; case 4: -#line 946 "parser.c" +#line 950 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -961,7 +965,7 @@ case 5: _out: {} } -#line 317 "parser.rl" +#line 321 "parser.rl" if (cs >= JSON_integer_first_final) { long len = p - json->memo; @@ -976,7 +980,7 @@ case 5: } -#line 980 "parser.c" +#line 984 "parser.c" enum {JSON_float_start = 1}; enum {JSON_float_first_final = 8}; enum {JSON_float_error = 0}; @@ -984,7 +988,7 @@ enum {JSON_float_error = 0}; enum {JSON_float_en_main = 1}; -#line 342 "parser.rl" +#line 346 "parser.rl" static int is_bigdecimal_class(VALUE obj) @@ -1005,15 +1009,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul int cs = EVIL; -#line 1009 "parser.c" +#line 1013 "parser.c" { cs = JSON_float_start; } -#line 362 "parser.rl" +#line 366 "parser.rl" json->memo = p; -#line 1017 "parser.c" +#line 1021 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1071,14 +1075,14 @@ case 8: goto st0; goto tr9; tr9: -#line 336 "parser.rl" +#line 340 "parser.rl" { p--; {p++; cs = 9; goto _out;} } goto st9; st9: if ( ++p == pe ) goto _test_eof9; case 9: -#line 1082 "parser.c" +#line 1086 "parser.c" goto st0; st5: if ( ++p == pe ) @@ -1139,7 +1143,7 @@ case 7: _out: {} } -#line 364 "parser.rl" +#line 368 "parser.rl" if (cs >= JSON_float_first_final) { long len = p - json->memo; @@ -1165,7 +1169,7 @@ case 7: -#line 1169 "parser.c" +#line 1173 "parser.c" enum {JSON_array_start = 1}; enum {JSON_array_first_final = 17}; enum {JSON_array_error = 0}; @@ -1173,7 +1177,7 @@ enum {JSON_array_error = 0}; enum {JSON_array_en_main = 1}; -#line 417 "parser.rl" +#line 421 "parser.rl" static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting) @@ -1187,14 +1191,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul *result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class); -#line 1191 "parser.c" +#line 1195 "parser.c" { cs = JSON_array_start; } -#line 430 "parser.rl" +#line 434 "parser.rl" -#line 1198 "parser.c" +#line 1202 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1233,7 +1237,7 @@ case 2: goto st2; goto st0; tr2: -#line 394 "parser.rl" +#line 398 "parser.rl" { VALUE v = Qnil; char *np = JSON_parse_value(json, p, pe, &v, current_nesting); @@ -1253,7 +1257,7 @@ st3: if ( ++p == pe ) goto _test_eof3; case 3: -#line 1257 "parser.c" +#line 1261 "parser.c" switch( (*p) ) { case 13: goto st3; case 32: goto st3; @@ -1353,14 +1357,14 @@ case 12: goto st3; goto st12; tr4: -#line 409 "parser.rl" +#line 413 "parser.rl" { p--; {p++; cs = 17; goto _out;} } goto st17; st17: if ( ++p == pe ) goto _test_eof17; case 17: -#line 1364 "parser.c" +#line 1368 "parser.c" goto st0; st13: if ( ++p == pe ) @@ -1416,7 +1420,7 @@ case 16: _out: {} } -#line 431 "parser.rl" +#line 435 "parser.rl" if(cs >= JSON_array_first_final) { return p + 1; @@ -1505,7 +1509,7 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd) } -#line 1509 "parser.c" +#line 1513 "parser.c" enum {JSON_string_start = 1}; enum {JSON_string_first_final = 8}; enum {JSON_string_error = 0}; @@ -1513,7 +1517,7 @@ enum {JSON_string_error = 0}; enum {JSON_string_en_main = 1}; -#line 538 "parser.rl" +#line 542 "parser.rl" static int @@ -1535,15 +1539,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu *result = rb_str_buf_new(0); -#line 1539 "parser.c" +#line 1543 "parser.c" { cs = JSON_string_start; } -#line 559 "parser.rl" +#line 563 "parser.rl" json->memo = p; -#line 1547 "parser.c" +#line 1551 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1568,7 +1572,7 @@ case 2: goto st0; goto st2; tr2: -#line 524 "parser.rl" +#line 528 "parser.rl" { *result = json_string_unescape(*result, json->memo + 1, p); if (NIL_P(*result)) { @@ -1579,14 +1583,14 @@ tr2: {p = (( p + 1))-1;} } } -#line 535 "parser.rl" +#line 539 "parser.rl" { p--; {p++; cs = 8; goto _out;} } goto st8; st8: if ( ++p == pe ) goto _test_eof8; case 8: -#line 1590 "parser.c" +#line 1594 "parser.c" goto st0; st3: if ( ++p == pe ) @@ -1662,7 +1666,7 @@ case 7: _out: {} } -#line 561 "parser.rl" +#line 565 "parser.rl" if (json->create_additions && RTEST(match_string = json->match_string)) { VALUE klass; @@ -1678,7 +1682,22 @@ case 7: if (json->symbolize_names && json->parsing_name) { *result = rb_str_intern(*result); } else if (RB_TYPE_P(*result, T_STRING)) { +# if STR_UMINUS_DEDUPE_FROZEN + if (json->freeze) { + // Starting from MRI 2.8 it is preferable to freeze the string + // before deduplication so that it can be interned directly + // otherwise it would be duplicated first which is wasteful. + *result = rb_funcall(rb_str_freeze(*result), i_uminus, 0); + } +# elif STR_UMINUS_DEDUPE + if (json->freeze) { + // MRI 2.5 and older do not deduplicate strings that are already + // frozen. + *result = rb_funcall(*result, i_uminus, 0); + } +# else rb_str_resize(*result, RSTRING_LEN(*result)); +# endif } if (cs >= JSON_string_first_final) { return p + 1; @@ -1786,6 +1805,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->symbolize_names = 0; } + tmp = ID2SYM(i_freeze); + if (option_given_p(opts, tmp)) { + json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0; + } else { + json->freeze = 0; + } tmp = ID2SYM(i_create_additions); if (option_given_p(opts, tmp)) { json->create_additions = RTEST(rb_hash_aref(opts, tmp)); @@ -1849,7 +1874,7 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } -#line 1853 "parser.c" +#line 1878 "parser.c" enum {JSON_start = 1}; enum {JSON_first_final = 10}; enum {JSON_error = 0}; @@ -1857,7 +1882,7 @@ enum {JSON_error = 0}; enum {JSON_en_main = 1}; -#line 761 "parser.rl" +#line 786 "parser.rl" /* @@ -1874,16 +1899,16 @@ static VALUE cParser_parse(VALUE self) GET_PARSER; -#line 1878 "parser.c" +#line 1903 "parser.c" { cs = JSON_start; } -#line 777 "parser.rl" +#line 802 "parser.rl" p = json->source; pe = p + json->len; -#line 1887 "parser.c" +#line 1912 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1917,7 +1942,7 @@ st0: cs = 0; goto _out; tr2: -#line 753 "parser.rl" +#line 778 "parser.rl" { char *np = JSON_parse_value(json, p, pe, &result, 0); if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;} @@ -1927,7 +1952,7 @@ st10: if ( ++p == pe ) goto _test_eof10; case 10: -#line 1931 "parser.c" +#line 1956 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2016,7 +2041,7 @@ case 9: _out: {} } -#line 780 "parser.rl" +#line 805 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2126,6 +2151,8 @@ void Init_parser(void) i_leftshift = rb_intern("<<"); i_new = rb_intern("new"); i_BigDecimal = rb_intern("BigDecimal"); + i_freeze = rb_intern("freeze"); + i_uminus = rb_intern("-@"); } /* diff --git a/ext/json/parser/parser.h b/ext/json/parser/parser.h index e6cf779024..e3eb920cc6 100644 --- a/ext/json/parser/parser.h +++ b/ext/json/parser/parser.h @@ -37,6 +37,7 @@ typedef struct JSON_ParserStruct { int allow_nan; int parsing_name; int symbolize_names; + int freeze; VALUE object_class; VALUE array_class; VALUE decimal_class; diff --git a/ext/json/parser/parser.rl b/ext/json/parser/parser.rl index 00a35bded4..4629052096 100644 --- a/ext/json/parser/parser.rl +++ b/ext/json/parser/parser.rl @@ -95,7 +95,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions, i_chr, i_max_nesting, i_allow_nan, i_symbolize_names, i_object_class, i_array_class, i_decimal_class, i_key_p, i_deep_const_get, i_match, i_match_string, i_aset, i_aref, - i_leftshift, i_new, i_BigDecimal; + i_leftshift, i_new, i_BigDecimal, i_freeze, i_uminus; %%{ machine JSON_common; @@ -290,6 +290,10 @@ static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *resul %% write init; %% write exec; + if (json->freeze) { + OBJ_FREEZE(*result); + } + if (cs >= JSON_value_first_final) { return p; } else { @@ -573,7 +577,22 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu if (json->symbolize_names && json->parsing_name) { *result = rb_str_intern(*result); } else if (RB_TYPE_P(*result, T_STRING)) { +# if STR_UMINUS_DEDUPE_FROZEN + if (json->freeze) { + // Starting from MRI 2.8 it is preferable to freeze the string + // before deduplication so that it can be interned directly + // otherwise it would be duplicated first which is wasteful. + *result = rb_funcall(rb_str_freeze(*result), i_uminus, 0); + } +# elif STR_UMINUS_DEDUPE + if (json->freeze) { + // MRI 2.5 and older do not deduplicate strings that are already + // frozen. + *result = rb_funcall(*result, i_uminus, 0); + } +# else rb_str_resize(*result, RSTRING_LEN(*result)); +# endif } if (cs >= JSON_string_first_final) { return p + 1; @@ -681,6 +700,12 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self) } else { json->symbolize_names = 0; } + tmp = ID2SYM(i_freeze); + if (option_given_p(opts, tmp)) { + json->freeze = RTEST(rb_hash_aref(opts, tmp)) ? 1 : 0; + } else { + json->freeze = 0; + } tmp = ID2SYM(i_create_additions); if (option_given_p(opts, tmp)) { json->create_additions = RTEST(rb_hash_aref(opts, tmp)); @@ -886,6 +911,8 @@ void Init_parser(void) i_leftshift = rb_intern("<<"); i_new = rb_intern("new"); i_BigDecimal = rb_intern("BigDecimal"); + i_freeze = rb_intern("freeze"); + i_uminus = rb_intern("-@"); } /* diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb index 514441efce..e29f3f126f 100644 --- a/test/json/json_parser_test.rb +++ b/test/json/json_parser_test.rb @@ -218,6 +218,17 @@ class JSONParserTest < Test::Unit::TestCase end end + def test_freeze + assert_predicate parse('{}', :freeze => true), :frozen? + assert_predicate parse('[]', :freeze => true), :frozen? + assert_predicate parse('"foo"', :freeze => true), :frozen? + + if string_deduplication_available? + assert_same -'foo', parse('"foo"', :freeze => true) + assert_same -'foo', parse('{"foo": 1}', :freeze => true).keys.first + end + end + def test_parse_comments json = < Date: Wed, 7 Oct 2020 03:13:48 +0100 Subject: [PATCH 14/41] Fix an issue with generate_pretty and empty objects in the Ruby and Java implementations --- test/json/json_generator_test.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/json/json_generator_test.rb b/test/json/json_generator_test.rb index 77b539dc3f..2ecdc97298 100644 --- a/test/json/json_generator_test.rb +++ b/test/json/json_generator_test.rb @@ -92,6 +92,11 @@ EOT end def test_generate_pretty + json = pretty_generate({}) + assert_equal(<<'EOT'.chomp, json) +{ +} +EOT json = pretty_generate(@hash) # hashes aren't (insertion) ordered on every ruby implementation # assert_equal(@json3, json) From a3ae90b8c552e4f98d81284815c50691be7e1a36 Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Tue, 20 Oct 2020 13:16:19 +0900 Subject: [PATCH 15/41] NEWS.md: mention TypeProf --- NEWS.md | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 559bd97f80..83b7a5af9a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -83,7 +83,9 @@ sufficient information, see the ChangeLog file or Redmine * Interpolated String literals are no longer frozen when `# frozen-string-literal: true` is used. [[Feature #17104]] -* RBS is introduced. It is a type definition language for Ruby programs. +* A static analysis foundation is introduced. See "Static analysis" section in detail. + * RBS is introduced. It is a type definition language for Ruby programs. + * TypeProf is experimentally bundled. It is a type analysis tool for Ruby programs. ## Command line options @@ -417,7 +419,9 @@ Excluding feature bug fixes. * Optimize C method call a little -## RBS +## Statis analysis + +### RBS * RBS is a new language for type definition of Ruby programs. It allows writing types of classes and modules with advanced @@ -428,6 +432,35 @@ Excluding feature bug fixes. * `rbs` gem is bundled to load and process RBS files. +### TypeProf + +* TypeProf is a type analysis tool for Ruby code based on abstract interpretation. + * It reads non-annotated Ruby code, tries inferring its type signature, and prints + the analysis result in RBS format. + * Though it supports only a subset of the Ruby language yet, we will continuously + improve the coverage of language features, the analysis performance, and usability. + +```ruby +# test.rb +def foo(x) + if x > 10 + x.to_s + else + nil + end +end + +foo(42) +``` + +``` +$ typeprof test.rb +# Classes +class Object + def foo : (Integer) -> String? +end +``` + ## Miscellaneous changes * Methods using `ruby2_keywords` will no longer keep empty keyword From 512752ba19c960daf1d866f96fb33f3c0b2d7a75 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Tue, 20 Oct 2020 23:48:20 +0900 Subject: [PATCH 16/41] fix condition --- bootstraptest/test_ractor.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index 74edfa8cd6..f951d4b938 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -618,7 +618,7 @@ assert_equal 'true', %q{ def ractor_local_globals /a(b)(c)d/ =~ 'abcd' # for $~ - `echo foo` unless /solaris/ !~ RUBY_PLATFORM + `echo foo` unless /solaris/ =~ RUBY_PLATFORM { # ractor-local (derived from created ractor): debug From d915e7ee0095727e63104c53b1adc7a70bae6522 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 20 Oct 2020 23:52:03 +0900 Subject: [PATCH 17/41] strip trailing spaces [ci skip] --- test/json/json_parser_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb index e29f3f126f..c7f1a5f3b4 100644 --- a/test/json/json_parser_test.rb +++ b/test/json/json_parser_test.rb @@ -222,7 +222,7 @@ class JSONParserTest < Test::Unit::TestCase assert_predicate parse('{}', :freeze => true), :frozen? assert_predicate parse('[]', :freeze => true), :frozen? assert_predicate parse('"foo"', :freeze => true), :frozen? - + if string_deduplication_available? assert_same -'foo', parse('"foo"', :freeze => true) assert_same -'foo', parse('{"foo": 1}', :freeze => true).keys.first From 081cc4eb283cb01ddffb364397e5175dbfacab66 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Tue, 20 Oct 2020 19:32:10 +0900 Subject: [PATCH 18/41] Dump FrozenCore specially --- iseq.c | 3 ++- node.c | 21 ++++++++++++++++++++- vm.c | 1 + 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/iseq.c b/iseq.c index 2f10cd6223..85ced1212c 100644 --- a/iseq.c +++ b/iseq.c @@ -1861,6 +1861,7 @@ local_var_name(const rb_iseq_t *diseq, VALUE level, VALUE op) } int rb_insn_unified_local_var_level(VALUE); +VALUE rb_dump_literal(VALUE lit); VALUE rb_insn_operand_intern(const rb_iseq_t *iseq, @@ -1936,7 +1937,7 @@ rb_insn_operand_intern(const rb_iseq_t *iseq, break; } } - ret = rb_inspect(op); + ret = rb_dump_literal(op); if (CLASS_OF(op) == rb_cISeq) { if (child) { rb_ary_push(child, op); diff --git a/node.c b/node.c index 936043794a..b68d9c1cfe 100644 --- a/node.c +++ b/node.c @@ -26,7 +26,7 @@ #define A_ID(id) add_id(buf, (id)) #define A_INT(val) rb_str_catf(buf, "%d", (val)) #define A_LONG(val) rb_str_catf(buf, "%ld", (val)) -#define A_LIT(lit) AR(rb_inspect(lit)) +#define A_LIT(lit) AR(rb_dump_literal(lit)) #define A_NODE_HEADER(node, term) \ rb_str_catf(buf, "@ %s (line: %d, location: (%d,%d)-(%d,%d))%s"term, \ ruby_node_name(nd_type(node)), nd_line(node), \ @@ -79,6 +79,25 @@ #define LAST_NODE (next_indent = " ") +VALUE +rb_dump_literal(VALUE lit) +{ + if (!RB_SPECIAL_CONST_P(lit)) { + VALUE str; + switch (RB_BUILTIN_TYPE(lit)) { + case T_CLASS: case T_MODULE: case T_ICLASS: + str = rb_class_path(lit); + if (FL_TEST(lit, FL_SINGLETON)) { + str = rb_sprintf("<%"PRIsVALUE">", str); + } + return str; + default: + break; + } + } + return rb_inspect(lit); +} + static void add_indent(VALUE buf, VALUE indent) { diff --git a/vm.c b/vm.c index ada33ae87b..1f3d97b56d 100644 --- a/vm.c +++ b/vm.c @@ -3123,6 +3123,7 @@ Init_VM(void) /* FrozenCore (hidden) */ fcore = rb_class_new(rb_cBasicObject); + rb_set_class_path(fcore, rb_cRubyVM, "FrozenCore"); RBASIC(fcore)->flags = T_ICLASS; klass = rb_singleton_class(fcore); rb_define_method_id(klass, id_core_set_method_alias, m_core_set_method_alias, 3); From a6a8576e877b02b83cabd0e712ecd377e7bc156b Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Wed, 21 Oct 2020 02:40:18 +0900 Subject: [PATCH 19/41] Feature #16812: Allow slicing arrays with ArithmeticSequence (#3241) * Support ArithmeticSequence in Array#slice * Extract rb_range_component_beg_len * Use rb_range_values to check Range object * Fix ary_make_partial_step * Fix for negative step cases * range.c: Describe the role of err argument in rb_range_component_beg_len * Raise a RangeError when an arithmetic sequence refers the outside of an array [Feature #16812] --- array.c | 91 +++++++++++++++++++++-- enumerator.c | 44 ++++++++++- include/ruby/internal/intern/enumerator.h | 1 + internal/range.h | 4 + range.c | 69 ++++++++++++----- test/ruby/test_array.rb | 38 +++++++++- 6 files changed, 216 insertions(+), 31 deletions(-) diff --git a/array.c b/array.c index 0373c1e374..9183dfc3e6 100644 --- a/array.c +++ b/array.c @@ -1140,6 +1140,52 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len) } } +static VALUE +ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step) +{ + assert(offset >= 0); + assert(len >= 0); + assert(offset+len <= RARRAY_LEN(ary)); + assert(step != 0); + + const VALUE *values = RARRAY_CONST_PTR_TRANSIENT(ary); + const long orig_len = len; + + if ((step > 0 && step >= len) || (step < 0 && (step < -len))) { + VALUE result = ary_new(klass, 1); + VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result); + RB_OBJ_WRITE(result, ptr, values[offset]); + ARY_SET_EMBED_LEN(result, 1); + return result; + } + + long ustep = (step < 0) ? -step : step; + len = (len + ustep - 1) / ustep; + + long i; + long j = offset + ((step > 0) ? 0 : (orig_len - 1)); + VALUE result = ary_new(klass, len); + if (len <= RARRAY_EMBED_LEN_MAX) { + VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result); + for (i = 0; i < len; ++i) { + RB_OBJ_WRITE(result, ptr+i, values[j]); + j += step; + } + ARY_SET_EMBED_LEN(result, len); + } + else { + RARRAY_PTR_USE_TRANSIENT(result, ptr, { + for (i = 0; i < len; ++i) { + RB_OBJ_WRITE(result, ptr+i, values[j]); + j += step; + } + }); + ARY_SET_LEN(result, len); + } + + return result; +} + static VALUE ary_make_shared_copy(VALUE ary) { @@ -1571,7 +1617,7 @@ rb_ary_entry(VALUE ary, long offset) } VALUE -rb_ary_subseq(VALUE ary, long beg, long len) +rb_ary_subseq_step(VALUE ary, long beg, long len, long step) { VALUE klass; long alen = RARRAY_LEN(ary); @@ -1584,8 +1630,18 @@ rb_ary_subseq(VALUE ary, long beg, long len) } klass = rb_obj_class(ary); if (len == 0) return ary_new(klass, 0); + if (step == 0) + rb_raise(rb_eArgError, "slice step cannot be zero"); + if (step == 1) + return ary_make_partial(ary, klass, beg, len); + else + return ary_make_partial_step(ary, klass, beg, len, step); +} - return ary_make_partial(ary, klass, beg, len); +VALUE +rb_ary_subseq(VALUE ary, long beg, long len) +{ + return rb_ary_subseq_step(ary, beg, len, 1); } static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e); @@ -1595,6 +1651,11 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e); * array[index] -> object or nil * array[start, length] -> object or nil * array[range] -> object or nil + * array[aseq] -> object or nil + * array.slice(index) -> object or nil + * array.slice(start, length) -> object or nil + * array.slice(range) -> object or nil + * array.slice(aseq) -> object or nil * * Returns elements from +self+; does not modify +self+. * @@ -1651,6 +1712,19 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e); * a[-3..2] # => [:foo, "bar", 2] * * If range.start is larger than the array size, returns +nil+. + * a = [:foo, 'bar', 2] + * a[4..1] # => nil + * a[4..0] # => nil + * a[4..-1] # => nil + * + * When a single argument +aseq+ is given, + * ...(to be described) + * + * Raises an exception if given a single argument + * that is not an \Integer-convertible object or a \Range object: + * a = [:foo, 'bar', 2] + * # Raises TypeError (no implicit conversion of Symbol into Integer): + * a[:foo] * * Array#slice is an alias for Array#[]. */ @@ -1679,21 +1753,22 @@ rb_ary_aref2(VALUE ary, VALUE b, VALUE e) MJIT_FUNC_EXPORTED VALUE rb_ary_aref1(VALUE ary, VALUE arg) { - long beg, len; + long beg, len, step; /* special case - speeding up */ if (FIXNUM_P(arg)) { return rb_ary_entry(ary, FIX2LONG(arg)); } - /* check if idx is Range */ - switch (rb_range_beg_len(arg, &beg, &len, RARRAY_LEN(ary), 0)) { + /* check if idx is Range or ArithmeticSequence */ + switch (rb_arithmetic_sequence_beg_len_step(arg, &beg, &len, &step, RARRAY_LEN(ary), 0)) { case Qfalse: - break; + break; case Qnil: - return Qnil; + return Qnil; default: - return rb_ary_subseq(ary, beg, len); + return rb_ary_subseq_step(ary, beg, len, step); } + return rb_ary_entry(ary, NUM2LONG(arg)); } diff --git a/enumerator.c b/enumerator.c index 3ea308a7cd..6e88c5db4a 100644 --- a/enumerator.c +++ b/enumerator.c @@ -3410,17 +3410,53 @@ rb_arithmetic_sequence_extract(VALUE obj, rb_arithmetic_sequence_components_t *c component->exclude_end = arith_seq_exclude_end_p(obj); return 1; } - else if (rb_obj_is_kind_of(obj, rb_cRange)) { - component->begin = RANGE_BEG(obj); - component->end = RANGE_END(obj); + else if (rb_range_values(obj, &component->begin, &component->end, &component->exclude_end)) { component->step = INT2FIX(1); - component->exclude_end = RTEST(RANGE_EXCL(obj)); return 1; } return 0; } +VALUE +rb_arithmetic_sequence_beg_len_step(VALUE obj, long *begp, long *lenp, long *stepp, long len, int err) +{ + RUBY_ASSERT(begp != NULL); + RUBY_ASSERT(lenp != NULL); + RUBY_ASSERT(stepp != NULL); + + rb_arithmetic_sequence_components_t aseq; + if (!rb_arithmetic_sequence_extract(obj, &aseq)) { + return Qfalse; + } + + long step = NIL_P(aseq.step) ? 1 : NUM2LONG(aseq.step); + *stepp = step; + + if (step < 0) { + VALUE tmp = aseq.begin; + aseq.begin = aseq.end; + aseq.end = tmp; + } + + if (err == 0 && (step < -1 || step > 1)) { + if (rb_range_component_beg_len(aseq.begin, aseq.end, aseq.exclude_end, begp, lenp, len, 1) == Qtrue) { + if (*begp > len) + goto out_of_range; + if (*lenp > len) + goto out_of_range; + return Qtrue; + } + } + else { + return rb_range_component_beg_len(aseq.begin, aseq.end, aseq.exclude_end, begp, lenp, len, err); + } + + out_of_range: + rb_raise(rb_eRangeError, "%+"PRIsVALUE" out of range", obj); + return Qnil; +} + /* * call-seq: * aseq.first -> num or nil diff --git a/include/ruby/internal/intern/enumerator.h b/include/ruby/internal/intern/enumerator.h index 7698e24538..c81485155c 100644 --- a/include/ruby/internal/intern/enumerator.h +++ b/include/ruby/internal/intern/enumerator.h @@ -42,6 +42,7 @@ VALUE rb_enumeratorize(VALUE, VALUE, int, const VALUE *); VALUE rb_enumeratorize_with_size(VALUE, VALUE, int, const VALUE *, rb_enumerator_size_func *); VALUE rb_enumeratorize_with_size_kw(VALUE, VALUE, int, const VALUE *, rb_enumerator_size_func *, int); int rb_arithmetic_sequence_extract(VALUE, rb_arithmetic_sequence_components_t *); +VALUE rb_arithmetic_sequence_beg_len_step(VALUE, long *begp, long *lenp, long *stepp, long len, int err); RBIMPL_SYMBOL_EXPORT_END() diff --git a/internal/range.h b/internal/range.h index 0b60f42298..4fe6037c89 100644 --- a/internal/range.h +++ b/internal/range.h @@ -34,4 +34,8 @@ RANGE_EXCL(VALUE r) return RSTRUCT(r)->as.ary[2]; } +VALUE +rb_range_component_beg_len(VALUE b, VALUE e, int excl, + long *begp, long *lenp, long len, int err); + #endif /* INTERNAL_RANGE_H */ diff --git a/range.c b/range.c index c019fcf2e0..a82763ca76 100644 --- a/range.c +++ b/range.c @@ -1329,48 +1329,81 @@ rb_range_values(VALUE range, VALUE *begp, VALUE *endp, int *exclp) return (int)Qtrue; } +/* Extract the components of a Range. + * + * You can use +err+ to control the behavior of out-of-range and exception. + * + * When +err+ is 0 or 2, if the begin offset is greater than +len+, + * it is out-of-range. The +RangeError+ is raised only if +err+ is 2, + * in this case. If +err+ is 0, +Qnil+ will be returned. + * + * When +err+ is 1, the begin and end offsets won't be adjusted even if they + * are greater than +len+. It allows +rb_ary_aset+ extends arrays. + * + * If the begin component of the given range is negative and is too-large + * abstract value, the +RangeError+ is raised only +err+ is 1 or 2. + * + * The case of err = 0 is used in item accessing methods such as + * +rb_ary_aref+, +rb_ary_slice_bang+, and +rb_str_aref+. + * + * The case of err = 1 is used in Array's methods such as + * +rb_ary_aset+ and +rb_ary_fill+. + * + * The case of err = 2 is used in +rb_str_aset+. + */ VALUE -rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err) +rb_range_component_beg_len(VALUE b, VALUE e, int excl, + long *begp, long *lenp, long len, int err) { long beg, end; - VALUE b, e; - int excl; - if (!rb_range_values(range, &b, &e, &excl)) - return Qfalse; beg = NIL_P(b) ? 0 : NUM2LONG(b); end = NIL_P(e) ? -1 : NUM2LONG(e); if (NIL_P(e)) excl = 0; if (beg < 0) { - beg += len; - if (beg < 0) - goto out_of_range; + beg += len; + if (beg < 0) + goto out_of_range; } if (end < 0) - end += len; + end += len; if (!excl) - end++; /* include end point */ + end++; /* include end point */ if (err == 0 || err == 2) { - if (beg > len) - goto out_of_range; - if (end > len) - end = len; + if (beg > len) + goto out_of_range; + if (end > len) + end = len; } len = end - beg; if (len < 0) - len = 0; + len = 0; *begp = beg; *lenp = len; return Qtrue; out_of_range: - if (err) { - rb_raise(rb_eRangeError, "%+"PRIsVALUE" out of range", range); - } return Qnil; } +VALUE +rb_range_beg_len(VALUE range, long *begp, long *lenp, long len, int err) +{ + VALUE b, e; + int excl; + + if (!rb_range_values(range, &b, &e, &excl)) + return Qfalse; + + VALUE res = rb_range_component_beg_len(b, e, excl, begp, lenp, len, err); + if (NIL_P(res) && err) { + rb_raise(rb_eRangeError, "%+"PRIsVALUE" out of range", range); + } + + return res; +} + /* * call-seq: * rng.to_s -> string diff --git a/test/ruby/test_array.rb b/test/ruby/test_array.rb index bc5d86354e..d6c15b8673 100644 --- a/test/ruby/test_array.rb +++ b/test/ruby/test_array.rb @@ -1496,9 +1496,46 @@ class TestArray < Test::Unit::TestCase assert_equal(@cls[10, 11, 12], a.slice(-91..-89)) assert_equal(@cls[10, 11, 12], a.slice(-91..-89)) + assert_equal(@cls[5, 8, 11], a.slice((4..12)%3)) + assert_equal(@cls[95, 97, 99], a.slice((94..)%2)) + + # [0] [1] [2] [3] [4] [5] [6] [7] + # ary = [ 1 2 3 4 5 6 7 8 ... ] + # (0) (1) (2) <- (..7) % 3 + # (2) (1) (0) <- (7..) % -3 + assert_equal(@cls[1, 4, 7], a.slice((..7)%3)) + assert_equal(@cls[8, 5, 2], a.slice((7..)% -3)) + + # [-98] [-97] [-96] [-95] [-94] [-93] [-92] [-91] [-90] + # ary = [ ... 3 4 5 6 7 8 9 10 11 ... ] + # (0) (1) (2) <- (-98..-90) % 3 + # (2) (1) (0) <- (-90..-98) % -3 + assert_equal(@cls[3, 6, 9], a.slice((-98..-90)%3)) + assert_equal(@cls[11, 8, 5], a.slice((-90..-98)% -3)) + + # [ 48] [ 49] [ 50] [ 51] [ 52] [ 53] + # [-52] [-51] [-50] [-49] [-48] [-47] + # ary = [ ... 49 50 51 52 53 54 ... ] + # (0) (1) (2) <- (48..-47) % 2 + # (2) (1) (0) <- (-47..48) % -2 + assert_equal(@cls[49, 51, 53], a.slice((48..-47)%2)) + assert_equal(@cls[54, 52, 50], a.slice((-47..48)% -2)) + + idx = ((3..90) % 2).to_a + assert_equal(@cls[*a.values_at(*idx)], a.slice((3..90)%2)) + idx = 90.step(3, -2).to_a + assert_equal(@cls[*a.values_at(*idx)], a.slice((90 .. 3)% -2)) + end + + def test_slice_out_of_range + a = @cls[*(1..100).to_a] + assert_nil(a.slice(-101..-1)) assert_nil(a.slice(-101..)) + assert_raise_with_message(RangeError, "((-101..-1).%(2)) out of range") { a.slice((-101..-1)%2) } + assert_raise_with_message(RangeError, "((-101..).%(2)) out of range") { a.slice((-101..)%2) } + assert_nil(a.slice(10, -3)) assert_equal @cls[], a.slice(10..7) end @@ -2414,7 +2451,6 @@ class TestArray < Test::Unit::TestCase def test_aref assert_raise(ArgumentError) { [][0, 0, 0] } - assert_raise(TypeError) { [][(1..10).step(2)] } end def test_fetch From 587feb0b6e47477ec3b1872de0c951e3d062db98 Mon Sep 17 00:00:00 2001 From: git Date: Wed, 21 Oct 2020 02:40:38 +0900 Subject: [PATCH 20/41] * 2020-10-21 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index 0627a937c0..f3a3916756 100644 --- a/version.h +++ b/version.h @@ -16,7 +16,7 @@ #define RUBY_RELEASE_YEAR 2020 #define RUBY_RELEASE_MONTH 10 -#define RUBY_RELEASE_DAY 20 +#define RUBY_RELEASE_DAY 21 #include "ruby/version.h" From 2f50936cb913b7458cbaa03dc4652f1127a7631a Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 21 Oct 2020 00:54:03 +0900 Subject: [PATCH 21/41] Ractor.make_shareable(obj) Introduce new method Ractor.make_shareable(obj) which tries to make obj shareable object. Protocol is here. (1) If obj is shareable, it is shareable. (2) If obj is not a shareable object and if obj can be shareable object if it is frozen, then freeze obj. If obj has reachable objects (rs), do rs.each{|o| Ractor.make_shareable(o)} recursively (recursion is not Ruby-level, but C-level). (3) Otherwise, raise Ractor::Error. Now T_DATA is not a shareable object even if the object is frozen. If the method finished without error, given obj is marked as a sharable object. To allow makng a shareable frozen T_DATA object, then set `RUBY_TYPED_FROZEN_SHAREABLE` as type->flags. On default, this flag is not set. It means user defined T_DATA objects are not allowed to become shareable objects when it is frozen. You can make any object shareable by setting FL_SHAREABLE flag, so if you know that the T_DATA object is shareable (== thread-safe), set this flag, at creation time for example. `Ractor` object is one example, which is not a frozen, but a shareable object. --- bootstraptest/test_ractor.rb | 74 +++++ common.mk | 9 + include/ruby/internal/core/rtypeddata.h | 2 + internal/hash.h | 3 +- ractor.c | 413 +++++++++++++++++------- ractor.rb | 6 + ractor_pub.h | 2 + 7 files changed, 384 insertions(+), 125 deletions(-) diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index f951d4b938..6290b73c36 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -832,6 +832,80 @@ assert_equal '0', %q{ }.take } +# Ractor.make_shareable(obj) +assert_equal 'true', %q{ + class C + def initialize + @a = 'foo' + @b = 'bar' + end + attr_reader :a, :b + end + S = Struct.new(:s1, :s2) + str = "hello" + str.instance_variable_set("@iv", "hello") + /a/ =~ 'a' + m = $~ + class N < Numeric + def /(other) + 1 + end + end + ary = []; ary << ary + + a = [[1, ['2', '3']], + {Object.new => "hello"}, + C.new, + S.new("x", "y"), + ("a".."b"), + str, + ary, # cycle + /regexp/, + /#{'r'.upcase}/, + m, + Complex(N.new,0), + Rational(N.new,0), + true, + false, + nil, + 1, 1.2, 1+3r, 1+4i, # Numeric + ] + Ractor.make_shareable(a) + + # check all frozen + a.each{|o| + raise o.inspect unless o.frozen? + + case o + when C + raise o.a.inspect unless o.a.frozen? + raise o.b.inspect unless o.b.frozen? + when Rational + raise o.numerator.inspect unless o.numerator.frozen? + when Complex + raise o.real.inspect unless o.real.frozen? + when Array + if o[0] == 1 + raise o[1][1].inspect unless o[1][1].frozen? + end + when Hash + o.each{|k, v| + raise k.inspect unless k.frozen? + raise v.inspect unless v.frozen? + } + end + } + + Ractor.shareable?(a) +} + +# Ractor.make_shareable(obj) doesn't freeze shareable objects +assert_equal 'true', %q{ + r = Ractor.new{} + Ractor.make_shareable(a = [r]) + [a.frozen?, a[0].frozen?] == [true, false] +} + ### ### Synchronization tests ### diff --git a/common.mk b/common.mk index a8719ca4e6..7b5ab6fbdd 100644 --- a/common.mk +++ b/common.mk @@ -10193,10 +10193,17 @@ ractor.$(OBJEXT): $(CCAN_DIR)/list/list.h ractor.$(OBJEXT): $(CCAN_DIR)/str/str.h ractor.$(OBJEXT): $(hdrdir)/ruby/ruby.h ractor.$(OBJEXT): $(top_srcdir)/internal/array.h +ractor.$(OBJEXT): $(top_srcdir)/internal/bignum.h +ractor.$(OBJEXT): $(top_srcdir)/internal/bits.h ractor.$(OBJEXT): $(top_srcdir)/internal/compilers.h +ractor.$(OBJEXT): $(top_srcdir)/internal/complex.h ractor.$(OBJEXT): $(top_srcdir)/internal/error.h +ractor.$(OBJEXT): $(top_srcdir)/internal/fixnum.h ractor.$(OBJEXT): $(top_srcdir)/internal/gc.h +ractor.$(OBJEXT): $(top_srcdir)/internal/hash.h ractor.$(OBJEXT): $(top_srcdir)/internal/imemo.h +ractor.$(OBJEXT): $(top_srcdir)/internal/numeric.h +ractor.$(OBJEXT): $(top_srcdir)/internal/rational.h ractor.$(OBJEXT): $(top_srcdir)/internal/serial.h ractor.$(OBJEXT): $(top_srcdir)/internal/static_assert.h ractor.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -10220,6 +10227,7 @@ ractor.$(OBJEXT): {$(VPATH)}debug.h ractor.$(OBJEXT): {$(VPATH)}debug_counter.h ractor.$(OBJEXT): {$(VPATH)}defines.h ractor.$(OBJEXT): {$(VPATH)}encoding.h +ractor.$(OBJEXT): {$(VPATH)}gc.h ractor.$(OBJEXT): {$(VPATH)}id.h ractor.$(OBJEXT): {$(VPATH)}id_table.h ractor.$(OBJEXT): {$(VPATH)}intern.h @@ -10381,6 +10389,7 @@ ractor.$(OBJEXT): {$(VPATH)}subst.h ractor.$(OBJEXT): {$(VPATH)}thread.h ractor.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h ractor.$(OBJEXT): {$(VPATH)}thread_native.h +ractor.$(OBJEXT): {$(VPATH)}variable.h ractor.$(OBJEXT): {$(VPATH)}vm_core.h ractor.$(OBJEXT): {$(VPATH)}vm_debug.h ractor.$(OBJEXT): {$(VPATH)}vm_opts.h diff --git a/include/ruby/internal/core/rtypeddata.h b/include/ruby/internal/core/rtypeddata.h index 3ffe07ec5e..c038e6f2b8 100644 --- a/include/ruby/internal/core/rtypeddata.h +++ b/include/ruby/internal/core/rtypeddata.h @@ -52,6 +52,7 @@ #define RTYPEDDATA_P RTYPEDDATA_P #define RTYPEDDATA_TYPE RTYPEDDATA_TYPE #define RUBY_TYPED_FREE_IMMEDIATELY RUBY_TYPED_FREE_IMMEDIATELY +#define RUBY_TYPED_FROZEN_SHAREABLE RUBY_TYPED_FROZEN_SHAREABLE #define RUBY_TYPED_WB_PROTECTED RUBY_TYPED_WB_PROTECTED #define RUBY_TYPED_PROMOTED1 RUBY_TYPED_PROMOTED1 /** @endcond */ @@ -59,6 +60,7 @@ /* bits for rb_data_type_struct::flags */ enum rbimpl_typeddata_flags { RUBY_TYPED_FREE_IMMEDIATELY = 1, + RUBY_TYPED_FROZEN_SHAREABLE = RUBY_FL_SHAREABLE, RUBY_TYPED_WB_PROTECTED = RUBY_FL_WB_PROTECTED, /* THIS FLAG DEPENDS ON Ruby version */ RUBY_TYPED_PROMOTED1 = RUBY_FL_PROMOTED1 /* THIS FLAG DEPENDS ON Ruby version */ }; diff --git a/internal/hash.h b/internal/hash.h index 237ce58603..a4677c581b 100644 --- a/internal/hash.h +++ b/internal/hash.h @@ -83,6 +83,8 @@ VALUE rb_hash_set_pair(VALUE hash, VALUE pair); int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval); int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg); int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg); +extern st_table *rb_hash_st_table(VALUE hash); + static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h); static inline VALUE RHASH_IFNONE(VALUE h); static inline size_t RHASH_SIZE(VALUE h); @@ -135,7 +137,6 @@ RHASH_AR_TABLE(VALUE h) static inline st_table * RHASH_ST_TABLE(VALUE h) { - extern st_table *rb_hash_st_table(VALUE hash); return rb_hash_st_table(h) } diff --git a/ractor.c b/ractor.c index 68ac5a25fe..8c498a86b1 100644 --- a/ractor.c +++ b/ractor.c @@ -6,8 +6,13 @@ #include "vm_core.h" #include "vm_sync.h" #include "ractor.h" +#include "internal/complex.h" #include "internal/error.h" +#include "internal/hash.h" +#include "internal/rational.h" #include "internal/struct.h" +#include "variable.h" +#include "gc.h" static VALUE rb_cRactor; static VALUE rb_eRactorError; @@ -1743,8 +1748,6 @@ rb_vm_main_ractor_ec(rb_vm_t *vm) return vm->ractor.main_ractor->threads.running_ec; } -#include "ractor.rbinc" - static VALUE ractor_moved_missing(int argc, VALUE *argv, VALUE self) { @@ -1777,128 +1780,6 @@ Init_Ractor(void) rb_obj_freeze(rb_cRactorMovedObject); } -static int -rb_ractor_shareable_p_hash_i(VALUE key, VALUE value, VALUE arg) -{ - // TODO: should we need to avoid recursion to prevent stack overflow? - if (!rb_ractor_shareable_p(key) || !rb_ractor_shareable_p(value)) { - bool *shareable = (bool*)arg; - *shareable = false; - return ST_STOP; - } - return ST_CONTINUE; -} - -static bool -ractor_struct_shareable_members_p(VALUE obj) -{ - VM_ASSERT(RB_TYPE_P(obj, T_STRUCT)); - - long len = RSTRUCT_LEN(obj); - const VALUE *ptr = RSTRUCT_CONST_PTR(obj); - - for (long i=0; iself, &cr->r_stderr, err); } } + +/// traverse function + +// 2: stop search +// 1: skip child +// 0: continue +typedef int (*rb_obj_traverse_enter_func)(VALUE obj, void *data); +typedef int (*rb_obj_traverse_leave_func)(VALUE obj, void *data); + +struct obj_traverse_data { + rb_obj_traverse_enter_func enter_func; + rb_obj_traverse_leave_func leave_func; + void *data; + + st_table *rec; +}; + + +struct obj_traverse_callback_data { + bool stop; + struct obj_traverse_data *data; +}; + +static int rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data); + +static int +obj_hash_traverse_i(VALUE key, VALUE val, VALUE ptr) +{ + struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr; + + if (rb_obj_traverse_i(key, d->data)) { + d->stop = true; + return ST_STOP; + } + + if (rb_obj_traverse_i(val, d->data)) { + d->stop = true; + return ST_STOP; + } + + return ST_CONTINUE; +} + +static void +obj_tdata_traverse_i(VALUE obj, void *ptr) +{ + struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr; + + if (rb_obj_traverse_i(obj, d->data)) { + d->stop = true; + } +} + +static int +rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) +{ + if (RB_SPECIAL_CONST_P(obj)) return 0; + + switch (data->enter_func(obj, data->data)) { + case 0: break; + case 1: return 0; // skip children + case 2: return 1; // stop search + default: rb_bug("rb_obj_traverse_func should return 0 to 2"); + } + + if (st_insert(data->rec, obj, 1)) { + // already traversed + return 0; + } + + if (FL_TEST(obj, FL_EXIVAR)) { + struct gen_ivtbl *ivtbl; + rb_ivar_generic_ivtbl_lookup(obj, &ivtbl); + for (uint32_t i = 0; i < ivtbl->numiv; i++) { + VALUE val = ivtbl->ivptr[i]; + if (val != Qundef && rb_obj_traverse_i(val, data)) return 1; + } + } + + switch (BUILTIN_TYPE(obj)) { + // no child node + case T_STRING: + case T_FLOAT: + case T_BIGNUM: + case T_REGEXP: + case T_FILE: + case T_SYMBOL: + case T_MATCH: + break; + + case T_OBJECT: + { + uint32_t len = ROBJECT_NUMIV(obj); + VALUE *ptr = ROBJECT_IVPTR(obj); + + for (uint32_t i=0; inum, data)) return 1; + if (rb_obj_traverse_i(RRATIONAL(obj)->den, data)) return 1; + break; + case T_COMPLEX: + if (rb_obj_traverse_i(RCOMPLEX(obj)->real, data)) return 1; + if (rb_obj_traverse_i(RCOMPLEX(obj)->imag, data)) return 1; + break; + + case T_DATA: + { + struct obj_traverse_callback_data d = { + .stop = false, + .data = data, + }; + rb_objspace_reachable_objects_from(obj, obj_tdata_traverse_i, &d); + if (d.stop) return 1; + } + break; + + // unreachable + case T_CLASS: + case T_MODULE: + case T_ICLASS: + default: + rp(obj); + rb_bug("unreachable"); + } + + switch (data->leave_func(obj, data->data)) { + case 0: + case 1: return 0; // terminate + case 2: return 1; // stop search + default: rb_bug("rb_obj_traverse_func should return 0 to 2"); + } +} + +// 0: traverse all +// 1: stopped +static int +rb_obj_traverse(VALUE obj, + rb_obj_traverse_enter_func enter_func, + rb_obj_traverse_leave_func leave_func, + void *passed_data) +{ + VALUE h = rb_ident_hash_new(); + + struct obj_traverse_data data = { + .enter_func = enter_func, + .leave_func = leave_func, + .data = passed_data, + .rec = rb_hash_st_table(h), + }; + + int r = rb_obj_traverse_i(obj, &data); + RB_GC_GUARD(h); + return r; +} + +static int +frozen_shareable_p(VALUE obj) +{ + switch (BUILTIN_TYPE(obj)) { + case T_DATA: + if (RTYPEDDATA_P(obj)) { + const rb_data_type_t *type = RTYPEDDATA_TYPE(obj); + if (type->flags & RUBY_TYPED_FROZEN_SHAREABLE) { + return true; + } + } + return false; + default: + return true; + } +} + +static int +make_shareable_check_shareable(VALUE obj, void *data) +{ + VM_ASSERT(!SPECIAL_CONST_P(obj)); + + if (RB_OBJ_SHAREABLE_P(obj)) { + return 1; + } + else { + if (!frozen_shareable_p(obj)) { + rb_raise(rb_eRactorError, "can not make shareable object for %"PRIsVALUE, obj); + } + } + + if (!OBJ_FROZEN(obj)) { + rb_funcall(obj, idFreeze, 0); + } + return 0; +} + +static int +mark_shareable(VALUE obj, void *data) +{ + FL_SET_RAW(obj, RUBY_FL_SHAREABLE); + return 0; +} + +VALUE +rb_ractor_make_shareable(VALUE obj) +{ + rb_obj_traverse(obj, + make_shareable_check_shareable, + mark_shareable, + NULL); + return obj; +} + +static int +shareable_p_enter(VALUE obj, void *ptr) +{ + if (RB_OBJ_SHAREABLE_P(obj)) { + return 1; + } + else if (RB_TYPE_P(obj, T_CLASS) || + RB_TYPE_P(obj, T_MODULE) || + RB_TYPE_P(obj, T_ICLASS)) { + // TODO: remove it + mark_shareable(obj, NULL); + return 1; + } + else if (RB_OBJ_FROZEN_RAW(obj) && + frozen_shareable_p(obj)) { + return 0; + } + + return 2; // fail +} + +MJIT_FUNC_EXPORTED bool +rb_ractor_shareable_p_continue(VALUE obj) +{ + if (rb_obj_traverse(obj, + shareable_p_enter, + mark_shareable, + NULL)) { + return false; + } + else { + return true; + } +} + +#include "ractor.rbinc" diff --git a/ractor.rb b/ractor.rb index c825fbe0da..936310d645 100644 --- a/ractor.rb +++ b/ractor.rb @@ -173,4 +173,10 @@ class Ractor rb_ractor_shareable_p(obj) ? Qtrue : Qfalse; } end + + def self.make_shareable obj + __builtin_cexpr! %q{ + rb_ractor_make_shareable(obj); + } + end end diff --git a/ractor_pub.h b/ractor_pub.h index 5347481429..f2869276f6 100644 --- a/ractor_pub.h +++ b/ractor_pub.h @@ -36,6 +36,8 @@ rb_ractor_shareable_p(VALUE obj) } } +VALUE rb_ractor_make_shareable(VALUE obj); + RUBY_SYMBOL_EXPORT_BEGIN VALUE rb_ractor_stdin(void); From 1c5f44cd728e8c42fd99a74151752e2980e65d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= Date: Mon, 19 Oct 2020 15:23:11 +0900 Subject: [PATCH 22/41] .travis.yml: reduce redundant tests These tests are (more or less) covered by github actions now. --- .travis.yml | 173 ---------------------------------------------------- 1 file changed, 173 deletions(-) diff --git a/.travis.yml b/.travis.yml index 94aaf70f31..ee22583aa9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -54,9 +54,6 @@ env: .org.ruby-lang.ci.matrix-definitions: - - &cron-only - if: (type = cron) AND (branch = master) AND (fork = false) - - &make-test-only script: - $SETARCH make -s test TESTOPTS="${TESTOPTS=$JOBS -q --tty=no}" @@ -79,15 +76,12 @@ env: g++-8 libffi-dev libgdbm-dev - libgmp-dev - libjemalloc-dev libncurses5-dev libncursesw5-dev libreadline6-dev libssl-dev libyaml-dev openssl - valgrind zlib1g-dev - &clang-8 @@ -107,15 +101,12 @@ env: llvm-8-tools libffi-dev libgdbm-dev - libgmp-dev - libjemalloc-dev libncurses5-dev libncursesw5-dev libreadline6-dev libssl-dev libyaml-dev openssl - valgrind zlib1g-dev # -------- @@ -134,92 +125,9 @@ env: arch: s390x <<: *gcc-8 - - &jemalloc - name: --with-jemalloc - <<: *gcc-8 - <<: *cron-only - env: - - CONFIG_FLAG='--with-gmp --with-jemalloc --with-valgrind' - - - &assertions - name: RUBY_DEBUG=1 - <<: *gcc-8 - #<<: *cron-only - <<: *make-test-only - env: - - GEMS_FOR_TEST= - - cppflags='-DRUBY_DEBUG -DVM_CHECK_MODE=1 -DTRANSIENT_HEAP_CHECK_MODE -DRGENGC_CHECK_MODE -DENC_DEBUG' - - - &VM_CHECK_MODE - name: VM_CHECK_MODE=3 - <<: *gcc-8 - <<: *cron-only - <<: *make-test-only - env: - - GEMS_FOR_TEST= - - cppflags=-DVM_CHECK_MODE=0x0003 - - - &SUPPORT_JOKE - name: SUPPORT_JOKE - <<: *gcc-8 - <<: *cron-only - <<: *make-test-only - env: - - BEFORE_INSTALL="sed vm_opts.h -e 's/OPT_SUPPORT_JOKE *0/OPT_SUPPORT_JOKE 1/' -i" - - - &CPDEBUG - name: CPDEBUG - <<: *gcc-8 - <<: *cron-only - <<: *make-test-only - env: - - cppflags=-DCPDEBUG - - - &WITH_COROUTINE_UCONTEXT - name: COROUTINE=ucontext - <<: *gcc-8 - <<: *cron-only - env: - - CONFIG_FLAG='--with-coroutine=ucontext' - - - &WITH_COROUTINE_COPY - name: COROUTINE=copy - <<: *gcc-8 - <<: *cron-only - env: - - CONFIG_FLAG='--with-coroutine=copy' - - - &TOKEN_THREADED_CODE - name: TOKEN_THREADED_CODE - <<: *gcc-8 - <<: *cron-only - <<: *make-test-only - env: - - GEMS_FOR_TEST= - - cppflags=-DOPT_THREADED_CODE=1 - - - &CALL_THREADED_CODE - name: CALL_THREADED_CODE - <<: *gcc-8 - <<: *cron-only - <<: *make-test-only - env: - - GEMS_FOR_TEST= - - cppflags=-DOPT_THREADED_CODE=2 - - - &NO_THREADED_CODE - name: NO_THREADED_CODE - <<: *gcc-8 - <<: *cron-only - <<: *make-test-only - env: - - GEMS_FOR_TEST= - - cppflags=-DOPT_THREADED_CODE=3 - - &ASAN name: -fsanitize=address <<: *clang-8 - #<<: *cron-only <<: *make-test-only env: - GEMS_FOR_TEST= @@ -234,7 +142,6 @@ env: - &MSAN name: -fsanitize=memory <<: *clang-8 - #<<: *cron-only <<: *make-test-only env: - GEMS_FOR_TEST= @@ -247,7 +154,6 @@ env: - &UBSAN name: -fsanitize=undefined <<: *clang-8 - #<<: *cron-only <<: *make-test-only env: - GEMS_FOR_TEST= @@ -327,39 +233,6 @@ env: zlib1g-dev:armhf zlib1g:armhf - - &pedanticism - name: -std=c99 -pedantic - compiler: clang - <<: *make-test-only - env: - - GEMS_FOR_TEST= - - GCC_FLAGS='-std=c99 -Werror=pedantic -pedantic-errors' - - CONFIG_FLAG= - - JOBS= - - >- - warnflags=' - -Wall - -Wextra - -Werror=deprecated-declarations - -Werror=division-by-zero - -Werror=extra-tokens - -Werror=implicit-function-declaration - -Werror=implicit-int - -Werror=pointer-arith - -Werror=shorten-64-to-32 - -Werror=write-strings - -Wmissing-noreturn - -Wno-constant-logical-operand - -Wno-missing-field-initializers - -Wno-overlength-strings - -Wno-parentheses-equality - -Wno-self-assign - -Wno-tautological-compare - -Wno-unused-local-typedef - -Wno-unused-parameter - -Wunused-variable' - - LDFLAGS=-Wno-unused-command-line-argument - - &spec-on-old-ruby language: ruby before_install: @@ -389,50 +262,14 @@ env: language: ruby rvm: 2.2 - - &dependency - name: Check dependencies in makefiles - language: ruby - before_install: - install: - before_script: - - |- - ruby -e 'new = [] - Dir.glob("ext/**/extconf.rb") {|ex| - unless File.exist?(dep = File.dirname(ex)+"/depend") - puts "Adding "+dep - File.copy_stream("template/depend.tmpl", dep) - new << dep - end - } - exec("git", "add", *new) unless new.empty?' - - git diff --cached - - "> config.status" - - "> .rbconfig.time" - - sed -f tool/prereq.status template/Makefile.in common.mk > Makefile - - make touch-unicode-files - - make -s $JOBS $UPDATE_UNICODE -o update-src up - - make -s $JOBS srcs - - rm -f config.status Makefile rbconfig.rb .rbconfig.time - - $SETARCH ./configure -C --disable-install-doc --prefix=$RUBY_PREFIX --disable-rubygems --with-gcc 'optflags=-O0' 'debugflags=-save-temps=obj -g' - - ruby tool/update-deps --fix - script: - - git diff --no-ext-diff --ignore-submodules --exit-code - after_failure: - - echo "Dependencies need to update" - env: - - CONFIG_FLAG= - matrix: include: # Build every commit: - <<: *x86_64-linux - <<: *i686-linux - - <<: *pedanticism - - <<: *assertions - <<: *baseruby - <<: *rubyspec25 - <<: *rubyspec27 - - <<: *dependency # Build every commit (Allowed Failures): - <<: *arm32-linux - <<: *arm64-linux @@ -440,16 +277,6 @@ matrix: - <<: *ASAN - <<: *MSAN - <<: *UBSAN - # Cron only: - - <<: *jemalloc - - <<: *VM_CHECK_MODE - - <<: *SUPPORT_JOKE - - <<: *CPDEBUG - - <<: *WITH_COROUTINE_UCONTEXT - - <<: *WITH_COROUTINE_COPY - - <<: *TOKEN_THREADED_CODE - - <<: *CALL_THREADED_CODE - - <<: *NO_THREADED_CODE allow_failures: - name: arm32-linux - name: arm64-linux From da25affdacc45dd54a1d4c12a5f8394145811276 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= Date: Mon, 19 Oct 2020 15:32:39 +0900 Subject: [PATCH 23/41] .github: reduce copy&paste Found that we can set default working directory for github actions. --- .github/workflows/check_dependencies.yml | 24 ++---------------------- .github/workflows/compilers.yml | 17 ++++++----------- .github/workflows/macos.yml | 12 ++++++------ .github/workflows/mingw.yml | 15 +++++++-------- .github/workflows/mjit.yml | 14 ++++++-------- .github/workflows/ubuntu.yml | 13 ++++++------- .github/workflows/windows.yml | 15 +++++++-------- 7 files changed, 40 insertions(+), 70 deletions(-) diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index 3439c04f9d..0ad2d5e757 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -2,11 +2,7 @@ name: Check Dependencies on: [push, pull_request] jobs: update-deps: - strategy: - matrix: - os: [ubuntu-20.04] - fail-fast: true - runs-on: ${{ matrix.os }} + runs-on: ubuntu-20.04 if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: - name: Install libraries @@ -18,28 +14,12 @@ jobs: run: | git config --global advice.detachedHead 0 - uses: actions/checkout@v2 - with: - path: src - - name: Fixed world writable dirs - run: | - chmod -v go-w $HOME $HOME/.config - sudo chmod -R go-w /usr/share - sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || : - - name: Set ENV - run: | - echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV - run: autoconf - working-directory: src - name: Run configure run: ./configure -C --disable-install-doc --disable-rubygems --with-gcc 'optflags=-O0' 'debugflags=-save-temps=obj -g' - working-directory: src - - name: Run make - run: make all golf - working-directory: src + - run: make all golf - run: ruby tool/update-deps --fix - working-directory: src - run: git diff --no-ext-diff --ignore-submodules --exit-code - working-directory: src - uses: k0kubun/action-slack@v2.0.0 with: payload: | diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml index 88b6c3ac51..17211b5e1e 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -159,18 +159,18 @@ jobs: container: ghcr.io/ruby/ruby-ci-image:latest if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: + - run: mkdir build + working-directory: - name: setenv run: | echo "${{ matrix.entry.key }}=${{ matrix.entry.value }}" >> $GITHUB_ENV echo "make=make -sj$((1 + $(nproc --all)))" >> $GITHUB_ENV - - run: mkdir build - uses: actions/checkout@v2 with: path: src - run: autoconf working-directory: src - name: Run configure - working-directory: build run: | if [ -n "${crosshost}" ]; then ../src/configure -C \ @@ -184,27 +184,18 @@ jobs: --with-gcc="${default_cc} ${append_cc}" fi - run: $make extract-extlibs - working-directory: build - run: $make incs - working-directory: build - run: $make - working-directory: build - run: $make test - working-directory: build - run: $make install - working-directory: build if: "matrix.entry.name == '-O3'" - run: /usr/local/bin/gem install --no-doc timezone tzinfo - working-directory: build if: "matrix.entry.name == '-O3'" - run: $make test-tool - working-directory: build if: "matrix.entry.name == '-O3'" - run: $make test-all TESTS='-- ruby -ext-' - working-directory: build if: "matrix.entry.name == '-O3'" - run: $make test-spec - working-directory: build if: "matrix.entry.name == '-O3'" - uses: k0kubun/action-slack@v2.0.0 @@ -220,3 +211,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot if: failure() && github.event_name == 'push' + +defaults: + run: + working-directory: build diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 34757ea193..f0355258f1 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -11,6 +11,8 @@ jobs: GITPULLOPTIONS: --no-tags origin ${{github.ref}} if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: + - run: mkdir build + working-directory: - name: Disable Firewall run: | sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off @@ -32,20 +34,14 @@ jobs: echo "JOBS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV - run: autoconf working-directory: src - - run: mkdir build - name: Run configure run: ../src/configure -C --disable-install-doc --with-openssl-dir=$(brew --prefix openssl@1.1) --with-readline-dir=$(brew --prefix readline) - working-directory: build - run: make $JOBS incs - working-directory: build - run: make $JOBS - working-directory: build - run: make prepare-gems - working-directory: build if: matrix.test_task == 'check' - run: make $JOBS -s ${{ matrix.test_task }} timeout-minutes: 60 - working-directory: build env: RUBY_TESTOPTS: "-q --tty=no" TEST_BUNDLED_GEMS_ALLOW_FAILURES: "rexml" @@ -62,3 +58,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot if: failure() && github.event_name == 'push' + +defaults: + run: + working-directory: build diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 8aacb7238f..36c8d747a7 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -24,6 +24,8 @@ jobs: fail-fast: false if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: + - run: mkdir build + working-directory: - name: git config run: | git config --system core.autocrlf false @@ -50,14 +52,13 @@ jobs: } - name: misc setup, autoreconf run: | - mkdir build mkdir install mkdir temp cd src sh -c "autoreconf -fi" + working-directory: - name: configure - working-directory: build run: | # Actions uses UTF8, causes test failures, similar to normal OS setup $PSDefaultParameterValues['*:Encoding'] = 'utf8' @@ -70,26 +71,22 @@ jobs: # Get-Content ./config.log | foreach {Write-Output $_} - name: update - working-directory: build run: | $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS) make -j $jobs incs - name: download gems - working-directory: build run: | $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS) make -j $jobs update-gems - name: make all timeout-minutes: 40 - working-directory: build run: | $jobs = [int](2 * $env:NUMBER_OF_PROCESSORS) make -j $jobs - name: make install - working-directory: build run: | # Actions uses UTF8, causes test failures, similar to normal OS setup $PSDefaultParameterValues['*:Encoding'] = 'utf8' @@ -99,13 +96,11 @@ jobs: - name: test timeout-minutes: 5 - working-directory: build run: | make test - name: test-all timeout-minutes: 60 - working-directory: build run: | # Actions uses UTF8, causes test failures, similar to normal OS setup $PSDefaultParameterValues['*:Encoding'] = 'utf8' @@ -139,3 +134,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot if: failure() && github.event_name == 'push' + +defaults: + run: + working-directory: build diff --git a/.github/workflows/mjit.yml b/.github/workflows/mjit.yml index 80ab351700..cdb6c940cb 100644 --- a/.github/workflows/mjit.yml +++ b/.github/workflows/mjit.yml @@ -14,6 +14,8 @@ jobs: RUN_OPTS: '--disable-gems ${{ matrix.jit_opts }}' GITPULLOPTIONS: --no-tags origin ${{github.ref}} steps: + - run: mkdir build + working-directory: - name: Install libraries run: | set -x @@ -35,25 +37,17 @@ jobs: echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV - run: autoconf working-directory: src - - run: mkdir build - name: Run configure run: ../src/configure -C --disable-install-doc - working-directory: build - run: make $JOBS incs - working-directory: build - run: make $JOBS - working-directory: build - run: sudo make $JOBS -s install - working-directory: build - run: make $JOBS -s test RUN_OPTS="$RUN_OPTS" timeout-minutes: 10 - working-directory: build - run: make $JOBS -s test-all RUN_OPTS="$RUN_OPTS" timeout-minutes: 10 - working-directory: build - run: make $JOBS -s test-spec RUN_OPTS="$RUN_OPTS" timeout-minutes: 5 - working-directory: build - uses: k0kubun/action-slack@v2.0.0 with: payload: | @@ -67,3 +61,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot if: failure() && github.event_name == 'push' + +defaults: + run: + working-directory: build diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index a5132ad053..38649d3f67 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -29,6 +29,8 @@ jobs: runs-on: ${{ matrix.os }} if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: + - run: mkdir build + working-directory: - name: Install libraries run: | set -x @@ -50,25 +52,18 @@ jobs: echo "JOBS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV - run: autoconf working-directory: src - - run: mkdir build - name: Run configure run: ../src/configure -C --disable-install-doc cppflags=${{ matrix.debug }} - working-directory: build - run: make $JOBS incs - working-directory: build - run: make $JOBS - working-directory: build - run: make prepare-gems - working-directory: build if: matrix.test_task == 'check' - name: Create dummy files in build dir run: | ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}' - working-directory: build if: matrix.test_task == 'check' - run: make $JOBS -s ${{ matrix.test_task }} timeout-minutes: 30 - working-directory: build env: RUBY_TESTOPTS: "-q --tty=no" TEST_BUNDLED_GEMS_ALLOW_FAILURES: "" @@ -85,3 +80,7 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot if: failure() && github.event_name == 'push' + +defaults: + run: + working-directory: build diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 0ae537959a..98e59ae188 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -14,6 +14,8 @@ jobs: VCVARS: C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: + - run: md build + working-directory: - uses: actions/cache@v2 with: path: C:\vcpkg\downloads @@ -41,14 +43,10 @@ jobs: - uses: actions/checkout@v2 with: path: src - - run: md build - shell: cmd - name: Configure run: | call "%VCVARS%" ../src/win32/configure.bat --disable-install-doc --without-ext=+,dbm,gdbm --enable-bundled-libffi --with-opt-dir=C:/vcpkg/installed/x64-windows --with-openssl-dir="C:/Program Files/OpenSSL-Win64" - working-directory: build - shell: cmd - name: nmake run: | call "%VCVARS%" @@ -57,15 +55,11 @@ jobs: nmake incs nmake extract-extlibs nmake - working-directory: build - shell: cmd - name: nmake test timeout-minutes: 30 run: | call "%VCVARS%" nmake ${{ matrix.test_task }} - working-directory: build - shell: cmd - uses: k0kubun/action-slack@v2.0.0 with: payload: | @@ -79,3 +73,8 @@ jobs: env: SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot if: failure() && github.event_name == 'push' + +defaults: + run: + working-directory: build + shell: cmd From 73834b5fc9d83180820de120db4350fa208cf743 Mon Sep 17 00:00:00 2001 From: Jacob Matthews Date: Tue, 6 Oct 2020 20:31:25 +1300 Subject: [PATCH 24/41] Calculate transient heap block usable size at compile time --- transient_heap.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/transient_heap.c b/transient_heap.c index 391dd59520..444f4fdcc4 100644 --- a/transient_heap.c +++ b/transient_heap.c @@ -62,6 +62,7 @@ #define TRANSIENT_HEAP_TOTAL_SIZE (1024 * 1024 * 32) /* 32 MB */ #define TRANSIENT_HEAP_ALLOC_MAX (1024 * 2 ) /* 2 KB */ #define TRANSIENT_HEAP_BLOCK_NUM (TRANSIENT_HEAP_TOTAL_SIZE / TRANSIENT_HEAP_BLOCK_SIZE) +#define TRANSIENT_HEAP_USABLE_SIZE TRANSIENT_HEAP_BLOCK_SIZE - sizeof(struct transient_heap_block_header) #define TRANSIENT_HEAP_ALLOC_MAGIC 0xfeab #define TRANSIENT_HEAP_ALLOC_ALIGN RUBY_ALIGNOF(void *) @@ -77,13 +78,12 @@ enum transient_heap_status { struct transient_heap_block { struct transient_heap_block_header { - int16_t size; /* sizeof(block) = TRANSIENT_HEAP_BLOCK_SIZE - sizeof(struct transient_heap_block_header) */ int16_t index; int16_t last_marked_index; int16_t objects; struct transient_heap_block *next_block; } info; - char buff[TRANSIENT_HEAP_BLOCK_SIZE - sizeof(struct transient_heap_block_header)]; + char buff[TRANSIENT_HEAP_USABLE_SIZE]; }; struct transient_heap { @@ -240,7 +240,6 @@ static void reset_block(struct transient_heap_block *block) { __msan_allocated_memory(block, sizeof block); - block->info.size = TRANSIENT_HEAP_BLOCK_SIZE - sizeof(struct transient_heap_block_header); block->info.index = 0; block->info.objects = 0; block->info.last_marked_index = TRANSIENT_HEAP_ALLOC_MARKING_LAST; @@ -345,9 +344,9 @@ transient_heap_allocatable_header(struct transient_heap* theap, size_t size) struct transient_heap_block *block = theap->using_blocks; while (block) { - TH_ASSERT(block->info.size >= block->info.index); + TH_ASSERT(block->info.index <= TRANSIENT_HEAP_USABLE_SIZE); - if (block->info.size - block->info.index >= (int32_t)size) { + if (TRANSIENT_HEAP_USABLE_SIZE - block->info.index >= size) { struct transient_alloc_header *header = (void *)&block->buff[block->info.index]; block->info.index += size; block->info.objects++; @@ -470,7 +469,7 @@ blocks_alloc_header_to_block(struct transient_heap *theap, struct transient_heap struct transient_heap_block *block = blocks; while (block) { - if (block->buff <= (char *)header && (char *)header < block->buff + block->info.size) { + if (block->buff <= (char *)header && (char *)header < block->buff + TRANSIENT_HEAP_USABLE_SIZE) { return block; } block = block->info.next_block; From 640b3405831d334d1297a32a686c7a74ab9229a9 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 21 Oct 2020 11:03:12 +0900 Subject: [PATCH 25/41] Check dependencies on macOS too --- .github/workflows/check_dependencies.yml | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index 0ad2d5e757..b5a3c67490 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -2,7 +2,11 @@ name: Check Dependencies on: [push, pull_request] jobs: update-deps: - runs-on: ubuntu-20.04 + strategy: + matrix: + os: [ubuntu-20.04, macos-latest] + fail-fast: true + runs-on: ${{ matrix.os }} if: "!contains(github.event.head_commit.message, '[ci skip]')" steps: - name: Install libraries @@ -10,6 +14,13 @@ jobs: set -x sudo apt-get update -q || : sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev libgdbm-dev bison autoconf ruby + if: "contains(matrix.os, 'ubuntu')" + - name: Install libraries + run: | + export WAITS='5 60' + brew upgrade + brew install gdbm gmp libffi openssl@1.1 zlib autoconf automake libtool readline + if: "contains(matrix.os, 'macos')" - name: git config run: | git config --global advice.detachedHead 0 From d497436d07bc02989d6af284011193d18f7b8368 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 21 Oct 2020 11:45:30 +0900 Subject: [PATCH 26/41] Update dependencies for macOS --- ext/-test-/memory_status/depend | 149 +++++++++++++++++++++++++ ext/digest/md5/depend | 191 +++++++++++++++++++++++++++++--- ext/digest/rmd160/depend | 191 +++++++++++++++++++++++++++++--- ext/digest/sha1/depend | 191 +++++++++++++++++++++++++++++--- ext/digest/sha2/depend | 190 ++++++++++++++++++++++++++++--- 5 files changed, 860 insertions(+), 52 deletions(-) diff --git a/ext/-test-/memory_status/depend b/ext/-test-/memory_status/depend index 657ef59c35..96a7821451 100644 --- a/ext/-test-/memory_status/depend +++ b/ext/-test-/memory_status/depend @@ -4,8 +4,157 @@ memory_status.o: $(arch_hdrdir)/ruby/config.h memory_status.o: $(hdrdir)/ruby.h memory_status.o: $(hdrdir)/ruby/assert.h memory_status.o: $(hdrdir)/ruby/backward.h +memory_status.o: $(hdrdir)/ruby/backward/2/assume.h +memory_status.o: $(hdrdir)/ruby/backward/2/attributes.h +memory_status.o: $(hdrdir)/ruby/backward/2/bool.h +memory_status.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +memory_status.o: $(hdrdir)/ruby/backward/2/inttypes.h +memory_status.o: $(hdrdir)/ruby/backward/2/limits.h +memory_status.o: $(hdrdir)/ruby/backward/2/long_long.h +memory_status.o: $(hdrdir)/ruby/backward/2/stdalign.h +memory_status.o: $(hdrdir)/ruby/backward/2/stdarg.h memory_status.o: $(hdrdir)/ruby/defines.h memory_status.o: $(hdrdir)/ruby/intern.h +memory_status.o: $(hdrdir)/ruby/internal/anyargs.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/char.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/double.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/int.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/long.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/short.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +memory_status.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +memory_status.o: $(hdrdir)/ruby/internal/assume.h +memory_status.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +memory_status.o: $(hdrdir)/ruby/internal/attr/artificial.h +memory_status.o: $(hdrdir)/ruby/internal/attr/cold.h +memory_status.o: $(hdrdir)/ruby/internal/attr/const.h +memory_status.o: $(hdrdir)/ruby/internal/attr/constexpr.h +memory_status.o: $(hdrdir)/ruby/internal/attr/deprecated.h +memory_status.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +memory_status.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +memory_status.o: $(hdrdir)/ruby/internal/attr/error.h +memory_status.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +memory_status.o: $(hdrdir)/ruby/internal/attr/forceinline.h +memory_status.o: $(hdrdir)/ruby/internal/attr/format.h +memory_status.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +memory_status.o: $(hdrdir)/ruby/internal/attr/noalias.h +memory_status.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +memory_status.o: $(hdrdir)/ruby/internal/attr/noexcept.h +memory_status.o: $(hdrdir)/ruby/internal/attr/noinline.h +memory_status.o: $(hdrdir)/ruby/internal/attr/nonnull.h +memory_status.o: $(hdrdir)/ruby/internal/attr/noreturn.h +memory_status.o: $(hdrdir)/ruby/internal/attr/pure.h +memory_status.o: $(hdrdir)/ruby/internal/attr/restrict.h +memory_status.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +memory_status.o: $(hdrdir)/ruby/internal/attr/warning.h +memory_status.o: $(hdrdir)/ruby/internal/attr/weakref.h +memory_status.o: $(hdrdir)/ruby/internal/cast.h +memory_status.o: $(hdrdir)/ruby/internal/compiler_is.h +memory_status.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +memory_status.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +memory_status.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +memory_status.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +memory_status.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +memory_status.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +memory_status.o: $(hdrdir)/ruby/internal/compiler_since.h +memory_status.o: $(hdrdir)/ruby/internal/config.h +memory_status.o: $(hdrdir)/ruby/internal/constant_p.h +memory_status.o: $(hdrdir)/ruby/internal/core.h +memory_status.o: $(hdrdir)/ruby/internal/core/rarray.h +memory_status.o: $(hdrdir)/ruby/internal/core/rbasic.h +memory_status.o: $(hdrdir)/ruby/internal/core/rbignum.h +memory_status.o: $(hdrdir)/ruby/internal/core/rclass.h +memory_status.o: $(hdrdir)/ruby/internal/core/rdata.h +memory_status.o: $(hdrdir)/ruby/internal/core/rfile.h +memory_status.o: $(hdrdir)/ruby/internal/core/rhash.h +memory_status.o: $(hdrdir)/ruby/internal/core/robject.h +memory_status.o: $(hdrdir)/ruby/internal/core/rregexp.h +memory_status.o: $(hdrdir)/ruby/internal/core/rstring.h +memory_status.o: $(hdrdir)/ruby/internal/core/rstruct.h +memory_status.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +memory_status.o: $(hdrdir)/ruby/internal/ctype.h +memory_status.o: $(hdrdir)/ruby/internal/dllexport.h +memory_status.o: $(hdrdir)/ruby/internal/dosish.h +memory_status.o: $(hdrdir)/ruby/internal/error.h +memory_status.o: $(hdrdir)/ruby/internal/eval.h +memory_status.o: $(hdrdir)/ruby/internal/event.h +memory_status.o: $(hdrdir)/ruby/internal/fl_type.h +memory_status.o: $(hdrdir)/ruby/internal/gc.h +memory_status.o: $(hdrdir)/ruby/internal/glob.h +memory_status.o: $(hdrdir)/ruby/internal/globals.h +memory_status.o: $(hdrdir)/ruby/internal/has/attribute.h +memory_status.o: $(hdrdir)/ruby/internal/has/builtin.h +memory_status.o: $(hdrdir)/ruby/internal/has/c_attribute.h +memory_status.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +memory_status.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +memory_status.o: $(hdrdir)/ruby/internal/has/extension.h +memory_status.o: $(hdrdir)/ruby/internal/has/feature.h +memory_status.o: $(hdrdir)/ruby/internal/has/warning.h +memory_status.o: $(hdrdir)/ruby/internal/intern/array.h +memory_status.o: $(hdrdir)/ruby/internal/intern/bignum.h +memory_status.o: $(hdrdir)/ruby/internal/intern/class.h +memory_status.o: $(hdrdir)/ruby/internal/intern/compar.h +memory_status.o: $(hdrdir)/ruby/internal/intern/complex.h +memory_status.o: $(hdrdir)/ruby/internal/intern/cont.h +memory_status.o: $(hdrdir)/ruby/internal/intern/dir.h +memory_status.o: $(hdrdir)/ruby/internal/intern/enum.h +memory_status.o: $(hdrdir)/ruby/internal/intern/enumerator.h +memory_status.o: $(hdrdir)/ruby/internal/intern/error.h +memory_status.o: $(hdrdir)/ruby/internal/intern/eval.h +memory_status.o: $(hdrdir)/ruby/internal/intern/file.h +memory_status.o: $(hdrdir)/ruby/internal/intern/gc.h +memory_status.o: $(hdrdir)/ruby/internal/intern/hash.h +memory_status.o: $(hdrdir)/ruby/internal/intern/io.h +memory_status.o: $(hdrdir)/ruby/internal/intern/load.h +memory_status.o: $(hdrdir)/ruby/internal/intern/marshal.h +memory_status.o: $(hdrdir)/ruby/internal/intern/numeric.h +memory_status.o: $(hdrdir)/ruby/internal/intern/object.h +memory_status.o: $(hdrdir)/ruby/internal/intern/parse.h +memory_status.o: $(hdrdir)/ruby/internal/intern/proc.h +memory_status.o: $(hdrdir)/ruby/internal/intern/process.h +memory_status.o: $(hdrdir)/ruby/internal/intern/random.h +memory_status.o: $(hdrdir)/ruby/internal/intern/range.h +memory_status.o: $(hdrdir)/ruby/internal/intern/rational.h +memory_status.o: $(hdrdir)/ruby/internal/intern/re.h +memory_status.o: $(hdrdir)/ruby/internal/intern/ruby.h +memory_status.o: $(hdrdir)/ruby/internal/intern/select.h +memory_status.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +memory_status.o: $(hdrdir)/ruby/internal/intern/signal.h +memory_status.o: $(hdrdir)/ruby/internal/intern/sprintf.h +memory_status.o: $(hdrdir)/ruby/internal/intern/string.h +memory_status.o: $(hdrdir)/ruby/internal/intern/struct.h +memory_status.o: $(hdrdir)/ruby/internal/intern/thread.h +memory_status.o: $(hdrdir)/ruby/internal/intern/time.h +memory_status.o: $(hdrdir)/ruby/internal/intern/variable.h +memory_status.o: $(hdrdir)/ruby/internal/intern/vm.h +memory_status.o: $(hdrdir)/ruby/internal/interpreter.h +memory_status.o: $(hdrdir)/ruby/internal/iterator.h +memory_status.o: $(hdrdir)/ruby/internal/memory.h +memory_status.o: $(hdrdir)/ruby/internal/method.h +memory_status.o: $(hdrdir)/ruby/internal/module.h +memory_status.o: $(hdrdir)/ruby/internal/newobj.h +memory_status.o: $(hdrdir)/ruby/internal/rgengc.h +memory_status.o: $(hdrdir)/ruby/internal/scan_args.h +memory_status.o: $(hdrdir)/ruby/internal/special_consts.h +memory_status.o: $(hdrdir)/ruby/internal/static_assert.h +memory_status.o: $(hdrdir)/ruby/internal/stdalign.h +memory_status.o: $(hdrdir)/ruby/internal/stdbool.h +memory_status.o: $(hdrdir)/ruby/internal/symbol.h +memory_status.o: $(hdrdir)/ruby/internal/token_paste.h +memory_status.o: $(hdrdir)/ruby/internal/value.h +memory_status.o: $(hdrdir)/ruby/internal/value_type.h +memory_status.o: $(hdrdir)/ruby/internal/variable.h +memory_status.o: $(hdrdir)/ruby/internal/warning_push.h +memory_status.o: $(hdrdir)/ruby/internal/xmalloc.h memory_status.o: $(hdrdir)/ruby/missing.h memory_status.o: $(hdrdir)/ruby/ruby.h memory_status.o: $(hdrdir)/ruby/st.h diff --git a/ext/digest/md5/depend b/ext/digest/md5/depend index 5ebb658bd5..9c3f6e55e0 100644 --- a/ext/digest/md5/depend +++ b/ext/digest/md5/depend @@ -2,9 +2,185 @@ md5.o: md5.c md5.h $(srcdir)/../defs.h md5init.o: $(LOCAL_HDRS) # AUTOGENERATED DEPENDENCIES START +md5.o: $(RUBY_EXTCONF_H) +md5.o: $(arch_hdrdir)/ruby/config.h +md5.o: $(hdrdir)/ruby.h +md5.o: $(hdrdir)/ruby/assert.h +md5.o: $(hdrdir)/ruby/backward.h +md5.o: $(hdrdir)/ruby/backward/2/assume.h +md5.o: $(hdrdir)/ruby/backward/2/attributes.h +md5.o: $(hdrdir)/ruby/backward/2/bool.h +md5.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +md5.o: $(hdrdir)/ruby/backward/2/inttypes.h +md5.o: $(hdrdir)/ruby/backward/2/limits.h +md5.o: $(hdrdir)/ruby/backward/2/long_long.h +md5.o: $(hdrdir)/ruby/backward/2/stdalign.h +md5.o: $(hdrdir)/ruby/backward/2/stdarg.h +md5.o: $(hdrdir)/ruby/defines.h +md5.o: $(hdrdir)/ruby/intern.h +md5.o: $(hdrdir)/ruby/internal/anyargs.h +md5.o: $(hdrdir)/ruby/internal/arithmetic.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/char.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/double.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/int.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/long.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/short.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +md5.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +md5.o: $(hdrdir)/ruby/internal/assume.h +md5.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +md5.o: $(hdrdir)/ruby/internal/attr/artificial.h +md5.o: $(hdrdir)/ruby/internal/attr/cold.h +md5.o: $(hdrdir)/ruby/internal/attr/const.h +md5.o: $(hdrdir)/ruby/internal/attr/constexpr.h +md5.o: $(hdrdir)/ruby/internal/attr/deprecated.h +md5.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +md5.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +md5.o: $(hdrdir)/ruby/internal/attr/error.h +md5.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +md5.o: $(hdrdir)/ruby/internal/attr/forceinline.h +md5.o: $(hdrdir)/ruby/internal/attr/format.h +md5.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +md5.o: $(hdrdir)/ruby/internal/attr/noalias.h +md5.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +md5.o: $(hdrdir)/ruby/internal/attr/noexcept.h +md5.o: $(hdrdir)/ruby/internal/attr/noinline.h +md5.o: $(hdrdir)/ruby/internal/attr/nonnull.h +md5.o: $(hdrdir)/ruby/internal/attr/noreturn.h +md5.o: $(hdrdir)/ruby/internal/attr/pure.h +md5.o: $(hdrdir)/ruby/internal/attr/restrict.h +md5.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +md5.o: $(hdrdir)/ruby/internal/attr/warning.h +md5.o: $(hdrdir)/ruby/internal/attr/weakref.h +md5.o: $(hdrdir)/ruby/internal/cast.h +md5.o: $(hdrdir)/ruby/internal/compiler_is.h +md5.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +md5.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +md5.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +md5.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +md5.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +md5.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +md5.o: $(hdrdir)/ruby/internal/compiler_since.h +md5.o: $(hdrdir)/ruby/internal/config.h +md5.o: $(hdrdir)/ruby/internal/constant_p.h +md5.o: $(hdrdir)/ruby/internal/core.h +md5.o: $(hdrdir)/ruby/internal/core/rarray.h +md5.o: $(hdrdir)/ruby/internal/core/rbasic.h +md5.o: $(hdrdir)/ruby/internal/core/rbignum.h +md5.o: $(hdrdir)/ruby/internal/core/rclass.h +md5.o: $(hdrdir)/ruby/internal/core/rdata.h +md5.o: $(hdrdir)/ruby/internal/core/rfile.h +md5.o: $(hdrdir)/ruby/internal/core/rhash.h +md5.o: $(hdrdir)/ruby/internal/core/robject.h +md5.o: $(hdrdir)/ruby/internal/core/rregexp.h +md5.o: $(hdrdir)/ruby/internal/core/rstring.h +md5.o: $(hdrdir)/ruby/internal/core/rstruct.h +md5.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +md5.o: $(hdrdir)/ruby/internal/ctype.h +md5.o: $(hdrdir)/ruby/internal/dllexport.h +md5.o: $(hdrdir)/ruby/internal/dosish.h +md5.o: $(hdrdir)/ruby/internal/error.h +md5.o: $(hdrdir)/ruby/internal/eval.h +md5.o: $(hdrdir)/ruby/internal/event.h +md5.o: $(hdrdir)/ruby/internal/fl_type.h +md5.o: $(hdrdir)/ruby/internal/gc.h +md5.o: $(hdrdir)/ruby/internal/glob.h +md5.o: $(hdrdir)/ruby/internal/globals.h +md5.o: $(hdrdir)/ruby/internal/has/attribute.h +md5.o: $(hdrdir)/ruby/internal/has/builtin.h +md5.o: $(hdrdir)/ruby/internal/has/c_attribute.h +md5.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +md5.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +md5.o: $(hdrdir)/ruby/internal/has/extension.h +md5.o: $(hdrdir)/ruby/internal/has/feature.h +md5.o: $(hdrdir)/ruby/internal/has/warning.h +md5.o: $(hdrdir)/ruby/internal/intern/array.h +md5.o: $(hdrdir)/ruby/internal/intern/bignum.h +md5.o: $(hdrdir)/ruby/internal/intern/class.h +md5.o: $(hdrdir)/ruby/internal/intern/compar.h +md5.o: $(hdrdir)/ruby/internal/intern/complex.h +md5.o: $(hdrdir)/ruby/internal/intern/cont.h +md5.o: $(hdrdir)/ruby/internal/intern/dir.h +md5.o: $(hdrdir)/ruby/internal/intern/enum.h +md5.o: $(hdrdir)/ruby/internal/intern/enumerator.h +md5.o: $(hdrdir)/ruby/internal/intern/error.h +md5.o: $(hdrdir)/ruby/internal/intern/eval.h +md5.o: $(hdrdir)/ruby/internal/intern/file.h +md5.o: $(hdrdir)/ruby/internal/intern/gc.h +md5.o: $(hdrdir)/ruby/internal/intern/hash.h +md5.o: $(hdrdir)/ruby/internal/intern/io.h +md5.o: $(hdrdir)/ruby/internal/intern/load.h +md5.o: $(hdrdir)/ruby/internal/intern/marshal.h +md5.o: $(hdrdir)/ruby/internal/intern/numeric.h +md5.o: $(hdrdir)/ruby/internal/intern/object.h +md5.o: $(hdrdir)/ruby/internal/intern/parse.h +md5.o: $(hdrdir)/ruby/internal/intern/proc.h +md5.o: $(hdrdir)/ruby/internal/intern/process.h +md5.o: $(hdrdir)/ruby/internal/intern/random.h +md5.o: $(hdrdir)/ruby/internal/intern/range.h +md5.o: $(hdrdir)/ruby/internal/intern/rational.h +md5.o: $(hdrdir)/ruby/internal/intern/re.h +md5.o: $(hdrdir)/ruby/internal/intern/ruby.h +md5.o: $(hdrdir)/ruby/internal/intern/select.h +md5.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +md5.o: $(hdrdir)/ruby/internal/intern/signal.h +md5.o: $(hdrdir)/ruby/internal/intern/sprintf.h +md5.o: $(hdrdir)/ruby/internal/intern/string.h +md5.o: $(hdrdir)/ruby/internal/intern/struct.h +md5.o: $(hdrdir)/ruby/internal/intern/thread.h +md5.o: $(hdrdir)/ruby/internal/intern/time.h +md5.o: $(hdrdir)/ruby/internal/intern/variable.h +md5.o: $(hdrdir)/ruby/internal/intern/vm.h +md5.o: $(hdrdir)/ruby/internal/interpreter.h +md5.o: $(hdrdir)/ruby/internal/iterator.h +md5.o: $(hdrdir)/ruby/internal/memory.h +md5.o: $(hdrdir)/ruby/internal/method.h +md5.o: $(hdrdir)/ruby/internal/module.h +md5.o: $(hdrdir)/ruby/internal/newobj.h +md5.o: $(hdrdir)/ruby/internal/rgengc.h +md5.o: $(hdrdir)/ruby/internal/scan_args.h +md5.o: $(hdrdir)/ruby/internal/special_consts.h +md5.o: $(hdrdir)/ruby/internal/static_assert.h +md5.o: $(hdrdir)/ruby/internal/stdalign.h +md5.o: $(hdrdir)/ruby/internal/stdbool.h +md5.o: $(hdrdir)/ruby/internal/symbol.h +md5.o: $(hdrdir)/ruby/internal/token_paste.h +md5.o: $(hdrdir)/ruby/internal/value.h +md5.o: $(hdrdir)/ruby/internal/value_type.h +md5.o: $(hdrdir)/ruby/internal/variable.h +md5.o: $(hdrdir)/ruby/internal/warning_push.h +md5.o: $(hdrdir)/ruby/internal/xmalloc.h +md5.o: $(hdrdir)/ruby/missing.h +md5.o: $(hdrdir)/ruby/ruby.h +md5.o: $(hdrdir)/ruby/st.h +md5.o: $(hdrdir)/ruby/subst.h +md5.o: $(srcdir)/../defs.h +md5.o: md5.c +md5.o: md5.h md5init.o: $(RUBY_EXTCONF_H) md5init.o: $(arch_hdrdir)/ruby/config.h md5init.o: $(hdrdir)/ruby.h +md5init.o: $(hdrdir)/ruby/assert.h +md5init.o: $(hdrdir)/ruby/backward.h +md5init.o: $(hdrdir)/ruby/backward/2/assume.h +md5init.o: $(hdrdir)/ruby/backward/2/attributes.h +md5init.o: $(hdrdir)/ruby/backward/2/bool.h +md5init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +md5init.o: $(hdrdir)/ruby/backward/2/inttypes.h +md5init.o: $(hdrdir)/ruby/backward/2/limits.h +md5init.o: $(hdrdir)/ruby/backward/2/long_long.h +md5init.o: $(hdrdir)/ruby/backward/2/stdalign.h +md5init.o: $(hdrdir)/ruby/backward/2/stdarg.h +md5init.o: $(hdrdir)/ruby/defines.h +md5init.o: $(hdrdir)/ruby/intern.h md5init.o: $(hdrdir)/ruby/internal/anyargs.h md5init.o: $(hdrdir)/ruby/internal/arithmetic.h md5init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -145,24 +321,13 @@ md5init.o: $(hdrdir)/ruby/internal/value_type.h md5init.o: $(hdrdir)/ruby/internal/variable.h md5init.o: $(hdrdir)/ruby/internal/warning_push.h md5init.o: $(hdrdir)/ruby/internal/xmalloc.h -md5init.o: $(hdrdir)/ruby/assert.h -md5init.o: $(hdrdir)/ruby/backward.h -md5init.o: $(hdrdir)/ruby/backward/2/assume.h -md5init.o: $(hdrdir)/ruby/backward/2/attributes.h -md5init.o: $(hdrdir)/ruby/backward/2/bool.h -md5init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -md5init.o: $(hdrdir)/ruby/backward/2/inttypes.h -md5init.o: $(hdrdir)/ruby/backward/2/limits.h -md5init.o: $(hdrdir)/ruby/backward/2/long_long.h -md5init.o: $(hdrdir)/ruby/backward/2/stdalign.h -md5init.o: $(hdrdir)/ruby/backward/2/stdarg.h -md5init.o: $(hdrdir)/ruby/defines.h -md5init.o: $(hdrdir)/ruby/intern.h md5init.o: $(hdrdir)/ruby/missing.h md5init.o: $(hdrdir)/ruby/ruby.h md5init.o: $(hdrdir)/ruby/st.h md5init.o: $(hdrdir)/ruby/subst.h +md5init.o: $(srcdir)/../defs.h md5init.o: $(srcdir)/../digest.h +md5init.o: md5.h md5init.o: md5init.c md5init.o: md5ossl.h # AUTOGENERATED DEPENDENCIES END diff --git a/ext/digest/rmd160/depend b/ext/digest/rmd160/depend index f6c2f554cb..424aa43b0c 100644 --- a/ext/digest/rmd160/depend +++ b/ext/digest/rmd160/depend @@ -2,9 +2,185 @@ rmd160.o: rmd160.c rmd160.h $(srcdir)/../defs.h rmd160init.o: $(LOCAL_HDRS) # AUTOGENERATED DEPENDENCIES START +rmd160.o: $(RUBY_EXTCONF_H) +rmd160.o: $(arch_hdrdir)/ruby/config.h +rmd160.o: $(hdrdir)/ruby.h +rmd160.o: $(hdrdir)/ruby/assert.h +rmd160.o: $(hdrdir)/ruby/backward.h +rmd160.o: $(hdrdir)/ruby/backward/2/assume.h +rmd160.o: $(hdrdir)/ruby/backward/2/attributes.h +rmd160.o: $(hdrdir)/ruby/backward/2/bool.h +rmd160.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +rmd160.o: $(hdrdir)/ruby/backward/2/inttypes.h +rmd160.o: $(hdrdir)/ruby/backward/2/limits.h +rmd160.o: $(hdrdir)/ruby/backward/2/long_long.h +rmd160.o: $(hdrdir)/ruby/backward/2/stdalign.h +rmd160.o: $(hdrdir)/ruby/backward/2/stdarg.h +rmd160.o: $(hdrdir)/ruby/defines.h +rmd160.o: $(hdrdir)/ruby/intern.h +rmd160.o: $(hdrdir)/ruby/internal/anyargs.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/char.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/double.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/int.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/long.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/short.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +rmd160.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +rmd160.o: $(hdrdir)/ruby/internal/assume.h +rmd160.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +rmd160.o: $(hdrdir)/ruby/internal/attr/artificial.h +rmd160.o: $(hdrdir)/ruby/internal/attr/cold.h +rmd160.o: $(hdrdir)/ruby/internal/attr/const.h +rmd160.o: $(hdrdir)/ruby/internal/attr/constexpr.h +rmd160.o: $(hdrdir)/ruby/internal/attr/deprecated.h +rmd160.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +rmd160.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +rmd160.o: $(hdrdir)/ruby/internal/attr/error.h +rmd160.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +rmd160.o: $(hdrdir)/ruby/internal/attr/forceinline.h +rmd160.o: $(hdrdir)/ruby/internal/attr/format.h +rmd160.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +rmd160.o: $(hdrdir)/ruby/internal/attr/noalias.h +rmd160.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +rmd160.o: $(hdrdir)/ruby/internal/attr/noexcept.h +rmd160.o: $(hdrdir)/ruby/internal/attr/noinline.h +rmd160.o: $(hdrdir)/ruby/internal/attr/nonnull.h +rmd160.o: $(hdrdir)/ruby/internal/attr/noreturn.h +rmd160.o: $(hdrdir)/ruby/internal/attr/pure.h +rmd160.o: $(hdrdir)/ruby/internal/attr/restrict.h +rmd160.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +rmd160.o: $(hdrdir)/ruby/internal/attr/warning.h +rmd160.o: $(hdrdir)/ruby/internal/attr/weakref.h +rmd160.o: $(hdrdir)/ruby/internal/cast.h +rmd160.o: $(hdrdir)/ruby/internal/compiler_is.h +rmd160.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +rmd160.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +rmd160.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +rmd160.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +rmd160.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +rmd160.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +rmd160.o: $(hdrdir)/ruby/internal/compiler_since.h +rmd160.o: $(hdrdir)/ruby/internal/config.h +rmd160.o: $(hdrdir)/ruby/internal/constant_p.h +rmd160.o: $(hdrdir)/ruby/internal/core.h +rmd160.o: $(hdrdir)/ruby/internal/core/rarray.h +rmd160.o: $(hdrdir)/ruby/internal/core/rbasic.h +rmd160.o: $(hdrdir)/ruby/internal/core/rbignum.h +rmd160.o: $(hdrdir)/ruby/internal/core/rclass.h +rmd160.o: $(hdrdir)/ruby/internal/core/rdata.h +rmd160.o: $(hdrdir)/ruby/internal/core/rfile.h +rmd160.o: $(hdrdir)/ruby/internal/core/rhash.h +rmd160.o: $(hdrdir)/ruby/internal/core/robject.h +rmd160.o: $(hdrdir)/ruby/internal/core/rregexp.h +rmd160.o: $(hdrdir)/ruby/internal/core/rstring.h +rmd160.o: $(hdrdir)/ruby/internal/core/rstruct.h +rmd160.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +rmd160.o: $(hdrdir)/ruby/internal/ctype.h +rmd160.o: $(hdrdir)/ruby/internal/dllexport.h +rmd160.o: $(hdrdir)/ruby/internal/dosish.h +rmd160.o: $(hdrdir)/ruby/internal/error.h +rmd160.o: $(hdrdir)/ruby/internal/eval.h +rmd160.o: $(hdrdir)/ruby/internal/event.h +rmd160.o: $(hdrdir)/ruby/internal/fl_type.h +rmd160.o: $(hdrdir)/ruby/internal/gc.h +rmd160.o: $(hdrdir)/ruby/internal/glob.h +rmd160.o: $(hdrdir)/ruby/internal/globals.h +rmd160.o: $(hdrdir)/ruby/internal/has/attribute.h +rmd160.o: $(hdrdir)/ruby/internal/has/builtin.h +rmd160.o: $(hdrdir)/ruby/internal/has/c_attribute.h +rmd160.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +rmd160.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +rmd160.o: $(hdrdir)/ruby/internal/has/extension.h +rmd160.o: $(hdrdir)/ruby/internal/has/feature.h +rmd160.o: $(hdrdir)/ruby/internal/has/warning.h +rmd160.o: $(hdrdir)/ruby/internal/intern/array.h +rmd160.o: $(hdrdir)/ruby/internal/intern/bignum.h +rmd160.o: $(hdrdir)/ruby/internal/intern/class.h +rmd160.o: $(hdrdir)/ruby/internal/intern/compar.h +rmd160.o: $(hdrdir)/ruby/internal/intern/complex.h +rmd160.o: $(hdrdir)/ruby/internal/intern/cont.h +rmd160.o: $(hdrdir)/ruby/internal/intern/dir.h +rmd160.o: $(hdrdir)/ruby/internal/intern/enum.h +rmd160.o: $(hdrdir)/ruby/internal/intern/enumerator.h +rmd160.o: $(hdrdir)/ruby/internal/intern/error.h +rmd160.o: $(hdrdir)/ruby/internal/intern/eval.h +rmd160.o: $(hdrdir)/ruby/internal/intern/file.h +rmd160.o: $(hdrdir)/ruby/internal/intern/gc.h +rmd160.o: $(hdrdir)/ruby/internal/intern/hash.h +rmd160.o: $(hdrdir)/ruby/internal/intern/io.h +rmd160.o: $(hdrdir)/ruby/internal/intern/load.h +rmd160.o: $(hdrdir)/ruby/internal/intern/marshal.h +rmd160.o: $(hdrdir)/ruby/internal/intern/numeric.h +rmd160.o: $(hdrdir)/ruby/internal/intern/object.h +rmd160.o: $(hdrdir)/ruby/internal/intern/parse.h +rmd160.o: $(hdrdir)/ruby/internal/intern/proc.h +rmd160.o: $(hdrdir)/ruby/internal/intern/process.h +rmd160.o: $(hdrdir)/ruby/internal/intern/random.h +rmd160.o: $(hdrdir)/ruby/internal/intern/range.h +rmd160.o: $(hdrdir)/ruby/internal/intern/rational.h +rmd160.o: $(hdrdir)/ruby/internal/intern/re.h +rmd160.o: $(hdrdir)/ruby/internal/intern/ruby.h +rmd160.o: $(hdrdir)/ruby/internal/intern/select.h +rmd160.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +rmd160.o: $(hdrdir)/ruby/internal/intern/signal.h +rmd160.o: $(hdrdir)/ruby/internal/intern/sprintf.h +rmd160.o: $(hdrdir)/ruby/internal/intern/string.h +rmd160.o: $(hdrdir)/ruby/internal/intern/struct.h +rmd160.o: $(hdrdir)/ruby/internal/intern/thread.h +rmd160.o: $(hdrdir)/ruby/internal/intern/time.h +rmd160.o: $(hdrdir)/ruby/internal/intern/variable.h +rmd160.o: $(hdrdir)/ruby/internal/intern/vm.h +rmd160.o: $(hdrdir)/ruby/internal/interpreter.h +rmd160.o: $(hdrdir)/ruby/internal/iterator.h +rmd160.o: $(hdrdir)/ruby/internal/memory.h +rmd160.o: $(hdrdir)/ruby/internal/method.h +rmd160.o: $(hdrdir)/ruby/internal/module.h +rmd160.o: $(hdrdir)/ruby/internal/newobj.h +rmd160.o: $(hdrdir)/ruby/internal/rgengc.h +rmd160.o: $(hdrdir)/ruby/internal/scan_args.h +rmd160.o: $(hdrdir)/ruby/internal/special_consts.h +rmd160.o: $(hdrdir)/ruby/internal/static_assert.h +rmd160.o: $(hdrdir)/ruby/internal/stdalign.h +rmd160.o: $(hdrdir)/ruby/internal/stdbool.h +rmd160.o: $(hdrdir)/ruby/internal/symbol.h +rmd160.o: $(hdrdir)/ruby/internal/token_paste.h +rmd160.o: $(hdrdir)/ruby/internal/value.h +rmd160.o: $(hdrdir)/ruby/internal/value_type.h +rmd160.o: $(hdrdir)/ruby/internal/variable.h +rmd160.o: $(hdrdir)/ruby/internal/warning_push.h +rmd160.o: $(hdrdir)/ruby/internal/xmalloc.h +rmd160.o: $(hdrdir)/ruby/missing.h +rmd160.o: $(hdrdir)/ruby/ruby.h +rmd160.o: $(hdrdir)/ruby/st.h +rmd160.o: $(hdrdir)/ruby/subst.h +rmd160.o: $(srcdir)/../defs.h +rmd160.o: rmd160.c +rmd160.o: rmd160.h rmd160init.o: $(RUBY_EXTCONF_H) rmd160init.o: $(arch_hdrdir)/ruby/config.h rmd160init.o: $(hdrdir)/ruby.h +rmd160init.o: $(hdrdir)/ruby/assert.h +rmd160init.o: $(hdrdir)/ruby/backward.h +rmd160init.o: $(hdrdir)/ruby/backward/2/assume.h +rmd160init.o: $(hdrdir)/ruby/backward/2/attributes.h +rmd160init.o: $(hdrdir)/ruby/backward/2/bool.h +rmd160init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +rmd160init.o: $(hdrdir)/ruby/backward/2/inttypes.h +rmd160init.o: $(hdrdir)/ruby/backward/2/limits.h +rmd160init.o: $(hdrdir)/ruby/backward/2/long_long.h +rmd160init.o: $(hdrdir)/ruby/backward/2/stdalign.h +rmd160init.o: $(hdrdir)/ruby/backward/2/stdarg.h +rmd160init.o: $(hdrdir)/ruby/defines.h +rmd160init.o: $(hdrdir)/ruby/intern.h rmd160init.o: $(hdrdir)/ruby/internal/anyargs.h rmd160init.o: $(hdrdir)/ruby/internal/arithmetic.h rmd160init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -145,24 +321,13 @@ rmd160init.o: $(hdrdir)/ruby/internal/value_type.h rmd160init.o: $(hdrdir)/ruby/internal/variable.h rmd160init.o: $(hdrdir)/ruby/internal/warning_push.h rmd160init.o: $(hdrdir)/ruby/internal/xmalloc.h -rmd160init.o: $(hdrdir)/ruby/assert.h -rmd160init.o: $(hdrdir)/ruby/backward.h -rmd160init.o: $(hdrdir)/ruby/backward/2/assume.h -rmd160init.o: $(hdrdir)/ruby/backward/2/attributes.h -rmd160init.o: $(hdrdir)/ruby/backward/2/bool.h -rmd160init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -rmd160init.o: $(hdrdir)/ruby/backward/2/inttypes.h -rmd160init.o: $(hdrdir)/ruby/backward/2/limits.h -rmd160init.o: $(hdrdir)/ruby/backward/2/long_long.h -rmd160init.o: $(hdrdir)/ruby/backward/2/stdalign.h -rmd160init.o: $(hdrdir)/ruby/backward/2/stdarg.h -rmd160init.o: $(hdrdir)/ruby/defines.h -rmd160init.o: $(hdrdir)/ruby/intern.h rmd160init.o: $(hdrdir)/ruby/missing.h rmd160init.o: $(hdrdir)/ruby/ruby.h rmd160init.o: $(hdrdir)/ruby/st.h rmd160init.o: $(hdrdir)/ruby/subst.h +rmd160init.o: $(srcdir)/../defs.h rmd160init.o: $(srcdir)/../digest.h +rmd160init.o: rmd160.h rmd160init.o: rmd160init.c rmd160init.o: rmd160ossl.h # AUTOGENERATED DEPENDENCIES END diff --git a/ext/digest/sha1/depend b/ext/digest/sha1/depend index f2c07de945..f11e9e31f7 100644 --- a/ext/digest/sha1/depend +++ b/ext/digest/sha1/depend @@ -2,9 +2,185 @@ sha1.o: sha1.c sha1.h $(srcdir)/../defs.h sha1init.o: $(LOCAL_HDRS) # AUTOGENERATED DEPENDENCIES START +sha1.o: $(RUBY_EXTCONF_H) +sha1.o: $(arch_hdrdir)/ruby/config.h +sha1.o: $(hdrdir)/ruby.h +sha1.o: $(hdrdir)/ruby/assert.h +sha1.o: $(hdrdir)/ruby/backward.h +sha1.o: $(hdrdir)/ruby/backward/2/assume.h +sha1.o: $(hdrdir)/ruby/backward/2/attributes.h +sha1.o: $(hdrdir)/ruby/backward/2/bool.h +sha1.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +sha1.o: $(hdrdir)/ruby/backward/2/inttypes.h +sha1.o: $(hdrdir)/ruby/backward/2/limits.h +sha1.o: $(hdrdir)/ruby/backward/2/long_long.h +sha1.o: $(hdrdir)/ruby/backward/2/stdalign.h +sha1.o: $(hdrdir)/ruby/backward/2/stdarg.h +sha1.o: $(hdrdir)/ruby/defines.h +sha1.o: $(hdrdir)/ruby/intern.h +sha1.o: $(hdrdir)/ruby/internal/anyargs.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/char.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/double.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/int.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/long.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/short.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +sha1.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +sha1.o: $(hdrdir)/ruby/internal/assume.h +sha1.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +sha1.o: $(hdrdir)/ruby/internal/attr/artificial.h +sha1.o: $(hdrdir)/ruby/internal/attr/cold.h +sha1.o: $(hdrdir)/ruby/internal/attr/const.h +sha1.o: $(hdrdir)/ruby/internal/attr/constexpr.h +sha1.o: $(hdrdir)/ruby/internal/attr/deprecated.h +sha1.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +sha1.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +sha1.o: $(hdrdir)/ruby/internal/attr/error.h +sha1.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +sha1.o: $(hdrdir)/ruby/internal/attr/forceinline.h +sha1.o: $(hdrdir)/ruby/internal/attr/format.h +sha1.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +sha1.o: $(hdrdir)/ruby/internal/attr/noalias.h +sha1.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +sha1.o: $(hdrdir)/ruby/internal/attr/noexcept.h +sha1.o: $(hdrdir)/ruby/internal/attr/noinline.h +sha1.o: $(hdrdir)/ruby/internal/attr/nonnull.h +sha1.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sha1.o: $(hdrdir)/ruby/internal/attr/pure.h +sha1.o: $(hdrdir)/ruby/internal/attr/restrict.h +sha1.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +sha1.o: $(hdrdir)/ruby/internal/attr/warning.h +sha1.o: $(hdrdir)/ruby/internal/attr/weakref.h +sha1.o: $(hdrdir)/ruby/internal/cast.h +sha1.o: $(hdrdir)/ruby/internal/compiler_is.h +sha1.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +sha1.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +sha1.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +sha1.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +sha1.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +sha1.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +sha1.o: $(hdrdir)/ruby/internal/compiler_since.h +sha1.o: $(hdrdir)/ruby/internal/config.h +sha1.o: $(hdrdir)/ruby/internal/constant_p.h +sha1.o: $(hdrdir)/ruby/internal/core.h +sha1.o: $(hdrdir)/ruby/internal/core/rarray.h +sha1.o: $(hdrdir)/ruby/internal/core/rbasic.h +sha1.o: $(hdrdir)/ruby/internal/core/rbignum.h +sha1.o: $(hdrdir)/ruby/internal/core/rclass.h +sha1.o: $(hdrdir)/ruby/internal/core/rdata.h +sha1.o: $(hdrdir)/ruby/internal/core/rfile.h +sha1.o: $(hdrdir)/ruby/internal/core/rhash.h +sha1.o: $(hdrdir)/ruby/internal/core/robject.h +sha1.o: $(hdrdir)/ruby/internal/core/rregexp.h +sha1.o: $(hdrdir)/ruby/internal/core/rstring.h +sha1.o: $(hdrdir)/ruby/internal/core/rstruct.h +sha1.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +sha1.o: $(hdrdir)/ruby/internal/ctype.h +sha1.o: $(hdrdir)/ruby/internal/dllexport.h +sha1.o: $(hdrdir)/ruby/internal/dosish.h +sha1.o: $(hdrdir)/ruby/internal/error.h +sha1.o: $(hdrdir)/ruby/internal/eval.h +sha1.o: $(hdrdir)/ruby/internal/event.h +sha1.o: $(hdrdir)/ruby/internal/fl_type.h +sha1.o: $(hdrdir)/ruby/internal/gc.h +sha1.o: $(hdrdir)/ruby/internal/glob.h +sha1.o: $(hdrdir)/ruby/internal/globals.h +sha1.o: $(hdrdir)/ruby/internal/has/attribute.h +sha1.o: $(hdrdir)/ruby/internal/has/builtin.h +sha1.o: $(hdrdir)/ruby/internal/has/c_attribute.h +sha1.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +sha1.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +sha1.o: $(hdrdir)/ruby/internal/has/extension.h +sha1.o: $(hdrdir)/ruby/internal/has/feature.h +sha1.o: $(hdrdir)/ruby/internal/has/warning.h +sha1.o: $(hdrdir)/ruby/internal/intern/array.h +sha1.o: $(hdrdir)/ruby/internal/intern/bignum.h +sha1.o: $(hdrdir)/ruby/internal/intern/class.h +sha1.o: $(hdrdir)/ruby/internal/intern/compar.h +sha1.o: $(hdrdir)/ruby/internal/intern/complex.h +sha1.o: $(hdrdir)/ruby/internal/intern/cont.h +sha1.o: $(hdrdir)/ruby/internal/intern/dir.h +sha1.o: $(hdrdir)/ruby/internal/intern/enum.h +sha1.o: $(hdrdir)/ruby/internal/intern/enumerator.h +sha1.o: $(hdrdir)/ruby/internal/intern/error.h +sha1.o: $(hdrdir)/ruby/internal/intern/eval.h +sha1.o: $(hdrdir)/ruby/internal/intern/file.h +sha1.o: $(hdrdir)/ruby/internal/intern/gc.h +sha1.o: $(hdrdir)/ruby/internal/intern/hash.h +sha1.o: $(hdrdir)/ruby/internal/intern/io.h +sha1.o: $(hdrdir)/ruby/internal/intern/load.h +sha1.o: $(hdrdir)/ruby/internal/intern/marshal.h +sha1.o: $(hdrdir)/ruby/internal/intern/numeric.h +sha1.o: $(hdrdir)/ruby/internal/intern/object.h +sha1.o: $(hdrdir)/ruby/internal/intern/parse.h +sha1.o: $(hdrdir)/ruby/internal/intern/proc.h +sha1.o: $(hdrdir)/ruby/internal/intern/process.h +sha1.o: $(hdrdir)/ruby/internal/intern/random.h +sha1.o: $(hdrdir)/ruby/internal/intern/range.h +sha1.o: $(hdrdir)/ruby/internal/intern/rational.h +sha1.o: $(hdrdir)/ruby/internal/intern/re.h +sha1.o: $(hdrdir)/ruby/internal/intern/ruby.h +sha1.o: $(hdrdir)/ruby/internal/intern/select.h +sha1.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sha1.o: $(hdrdir)/ruby/internal/intern/signal.h +sha1.o: $(hdrdir)/ruby/internal/intern/sprintf.h +sha1.o: $(hdrdir)/ruby/internal/intern/string.h +sha1.o: $(hdrdir)/ruby/internal/intern/struct.h +sha1.o: $(hdrdir)/ruby/internal/intern/thread.h +sha1.o: $(hdrdir)/ruby/internal/intern/time.h +sha1.o: $(hdrdir)/ruby/internal/intern/variable.h +sha1.o: $(hdrdir)/ruby/internal/intern/vm.h +sha1.o: $(hdrdir)/ruby/internal/interpreter.h +sha1.o: $(hdrdir)/ruby/internal/iterator.h +sha1.o: $(hdrdir)/ruby/internal/memory.h +sha1.o: $(hdrdir)/ruby/internal/method.h +sha1.o: $(hdrdir)/ruby/internal/module.h +sha1.o: $(hdrdir)/ruby/internal/newobj.h +sha1.o: $(hdrdir)/ruby/internal/rgengc.h +sha1.o: $(hdrdir)/ruby/internal/scan_args.h +sha1.o: $(hdrdir)/ruby/internal/special_consts.h +sha1.o: $(hdrdir)/ruby/internal/static_assert.h +sha1.o: $(hdrdir)/ruby/internal/stdalign.h +sha1.o: $(hdrdir)/ruby/internal/stdbool.h +sha1.o: $(hdrdir)/ruby/internal/symbol.h +sha1.o: $(hdrdir)/ruby/internal/token_paste.h +sha1.o: $(hdrdir)/ruby/internal/value.h +sha1.o: $(hdrdir)/ruby/internal/value_type.h +sha1.o: $(hdrdir)/ruby/internal/variable.h +sha1.o: $(hdrdir)/ruby/internal/warning_push.h +sha1.o: $(hdrdir)/ruby/internal/xmalloc.h +sha1.o: $(hdrdir)/ruby/missing.h +sha1.o: $(hdrdir)/ruby/ruby.h +sha1.o: $(hdrdir)/ruby/st.h +sha1.o: $(hdrdir)/ruby/subst.h +sha1.o: $(srcdir)/../defs.h +sha1.o: sha1.c +sha1.o: sha1.h sha1init.o: $(RUBY_EXTCONF_H) sha1init.o: $(arch_hdrdir)/ruby/config.h sha1init.o: $(hdrdir)/ruby.h +sha1init.o: $(hdrdir)/ruby/assert.h +sha1init.o: $(hdrdir)/ruby/backward.h +sha1init.o: $(hdrdir)/ruby/backward/2/assume.h +sha1init.o: $(hdrdir)/ruby/backward/2/attributes.h +sha1init.o: $(hdrdir)/ruby/backward/2/bool.h +sha1init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +sha1init.o: $(hdrdir)/ruby/backward/2/inttypes.h +sha1init.o: $(hdrdir)/ruby/backward/2/limits.h +sha1init.o: $(hdrdir)/ruby/backward/2/long_long.h +sha1init.o: $(hdrdir)/ruby/backward/2/stdalign.h +sha1init.o: $(hdrdir)/ruby/backward/2/stdarg.h +sha1init.o: $(hdrdir)/ruby/defines.h +sha1init.o: $(hdrdir)/ruby/intern.h sha1init.o: $(hdrdir)/ruby/internal/anyargs.h sha1init.o: $(hdrdir)/ruby/internal/arithmetic.h sha1init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -145,24 +321,13 @@ sha1init.o: $(hdrdir)/ruby/internal/value_type.h sha1init.o: $(hdrdir)/ruby/internal/variable.h sha1init.o: $(hdrdir)/ruby/internal/warning_push.h sha1init.o: $(hdrdir)/ruby/internal/xmalloc.h -sha1init.o: $(hdrdir)/ruby/assert.h -sha1init.o: $(hdrdir)/ruby/backward.h -sha1init.o: $(hdrdir)/ruby/backward/2/assume.h -sha1init.o: $(hdrdir)/ruby/backward/2/attributes.h -sha1init.o: $(hdrdir)/ruby/backward/2/bool.h -sha1init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -sha1init.o: $(hdrdir)/ruby/backward/2/inttypes.h -sha1init.o: $(hdrdir)/ruby/backward/2/limits.h -sha1init.o: $(hdrdir)/ruby/backward/2/long_long.h -sha1init.o: $(hdrdir)/ruby/backward/2/stdalign.h -sha1init.o: $(hdrdir)/ruby/backward/2/stdarg.h -sha1init.o: $(hdrdir)/ruby/defines.h -sha1init.o: $(hdrdir)/ruby/intern.h sha1init.o: $(hdrdir)/ruby/missing.h sha1init.o: $(hdrdir)/ruby/ruby.h sha1init.o: $(hdrdir)/ruby/st.h sha1init.o: $(hdrdir)/ruby/subst.h +sha1init.o: $(srcdir)/../defs.h sha1init.o: $(srcdir)/../digest.h +sha1init.o: sha1.h sha1init.o: sha1init.c sha1init.o: sha1ossl.h # AUTOGENERATED DEPENDENCIES END diff --git a/ext/digest/sha2/depend b/ext/digest/sha2/depend index 127bbf3f44..7aa445d8a7 100644 --- a/ext/digest/sha2/depend +++ b/ext/digest/sha2/depend @@ -2,9 +2,185 @@ sha2.o: sha2.c sha2.h $(srcdir)/../defs.h sha2init.o: $(LOCAL_HDRS) # AUTOGENERATED DEPENDENCIES START +sha2.o: $(RUBY_EXTCONF_H) +sha2.o: $(arch_hdrdir)/ruby/config.h +sha2.o: $(hdrdir)/ruby.h +sha2.o: $(hdrdir)/ruby/assert.h +sha2.o: $(hdrdir)/ruby/backward.h +sha2.o: $(hdrdir)/ruby/backward/2/assume.h +sha2.o: $(hdrdir)/ruby/backward/2/attributes.h +sha2.o: $(hdrdir)/ruby/backward/2/bool.h +sha2.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +sha2.o: $(hdrdir)/ruby/backward/2/inttypes.h +sha2.o: $(hdrdir)/ruby/backward/2/limits.h +sha2.o: $(hdrdir)/ruby/backward/2/long_long.h +sha2.o: $(hdrdir)/ruby/backward/2/stdalign.h +sha2.o: $(hdrdir)/ruby/backward/2/stdarg.h +sha2.o: $(hdrdir)/ruby/defines.h +sha2.o: $(hdrdir)/ruby/intern.h +sha2.o: $(hdrdir)/ruby/internal/anyargs.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/char.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/double.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/fixnum.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/gid_t.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/int.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/intptr_t.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/long.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/long_long.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/mode_t.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/off_t.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/pid_t.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/short.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/size_t.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/st_data_t.h +sha2.o: $(hdrdir)/ruby/internal/arithmetic/uid_t.h +sha2.o: $(hdrdir)/ruby/internal/assume.h +sha2.o: $(hdrdir)/ruby/internal/attr/alloc_size.h +sha2.o: $(hdrdir)/ruby/internal/attr/artificial.h +sha2.o: $(hdrdir)/ruby/internal/attr/cold.h +sha2.o: $(hdrdir)/ruby/internal/attr/const.h +sha2.o: $(hdrdir)/ruby/internal/attr/constexpr.h +sha2.o: $(hdrdir)/ruby/internal/attr/deprecated.h +sha2.o: $(hdrdir)/ruby/internal/attr/diagnose_if.h +sha2.o: $(hdrdir)/ruby/internal/attr/enum_extensibility.h +sha2.o: $(hdrdir)/ruby/internal/attr/error.h +sha2.o: $(hdrdir)/ruby/internal/attr/flag_enum.h +sha2.o: $(hdrdir)/ruby/internal/attr/forceinline.h +sha2.o: $(hdrdir)/ruby/internal/attr/format.h +sha2.o: $(hdrdir)/ruby/internal/attr/maybe_unused.h +sha2.o: $(hdrdir)/ruby/internal/attr/noalias.h +sha2.o: $(hdrdir)/ruby/internal/attr/nodiscard.h +sha2.o: $(hdrdir)/ruby/internal/attr/noexcept.h +sha2.o: $(hdrdir)/ruby/internal/attr/noinline.h +sha2.o: $(hdrdir)/ruby/internal/attr/nonnull.h +sha2.o: $(hdrdir)/ruby/internal/attr/noreturn.h +sha2.o: $(hdrdir)/ruby/internal/attr/pure.h +sha2.o: $(hdrdir)/ruby/internal/attr/restrict.h +sha2.o: $(hdrdir)/ruby/internal/attr/returns_nonnull.h +sha2.o: $(hdrdir)/ruby/internal/attr/warning.h +sha2.o: $(hdrdir)/ruby/internal/attr/weakref.h +sha2.o: $(hdrdir)/ruby/internal/cast.h +sha2.o: $(hdrdir)/ruby/internal/compiler_is.h +sha2.o: $(hdrdir)/ruby/internal/compiler_is/apple.h +sha2.o: $(hdrdir)/ruby/internal/compiler_is/clang.h +sha2.o: $(hdrdir)/ruby/internal/compiler_is/gcc.h +sha2.o: $(hdrdir)/ruby/internal/compiler_is/intel.h +sha2.o: $(hdrdir)/ruby/internal/compiler_is/msvc.h +sha2.o: $(hdrdir)/ruby/internal/compiler_is/sunpro.h +sha2.o: $(hdrdir)/ruby/internal/compiler_since.h +sha2.o: $(hdrdir)/ruby/internal/config.h +sha2.o: $(hdrdir)/ruby/internal/constant_p.h +sha2.o: $(hdrdir)/ruby/internal/core.h +sha2.o: $(hdrdir)/ruby/internal/core/rarray.h +sha2.o: $(hdrdir)/ruby/internal/core/rbasic.h +sha2.o: $(hdrdir)/ruby/internal/core/rbignum.h +sha2.o: $(hdrdir)/ruby/internal/core/rclass.h +sha2.o: $(hdrdir)/ruby/internal/core/rdata.h +sha2.o: $(hdrdir)/ruby/internal/core/rfile.h +sha2.o: $(hdrdir)/ruby/internal/core/rhash.h +sha2.o: $(hdrdir)/ruby/internal/core/robject.h +sha2.o: $(hdrdir)/ruby/internal/core/rregexp.h +sha2.o: $(hdrdir)/ruby/internal/core/rstring.h +sha2.o: $(hdrdir)/ruby/internal/core/rstruct.h +sha2.o: $(hdrdir)/ruby/internal/core/rtypeddata.h +sha2.o: $(hdrdir)/ruby/internal/ctype.h +sha2.o: $(hdrdir)/ruby/internal/dllexport.h +sha2.o: $(hdrdir)/ruby/internal/dosish.h +sha2.o: $(hdrdir)/ruby/internal/error.h +sha2.o: $(hdrdir)/ruby/internal/eval.h +sha2.o: $(hdrdir)/ruby/internal/event.h +sha2.o: $(hdrdir)/ruby/internal/fl_type.h +sha2.o: $(hdrdir)/ruby/internal/gc.h +sha2.o: $(hdrdir)/ruby/internal/glob.h +sha2.o: $(hdrdir)/ruby/internal/globals.h +sha2.o: $(hdrdir)/ruby/internal/has/attribute.h +sha2.o: $(hdrdir)/ruby/internal/has/builtin.h +sha2.o: $(hdrdir)/ruby/internal/has/c_attribute.h +sha2.o: $(hdrdir)/ruby/internal/has/cpp_attribute.h +sha2.o: $(hdrdir)/ruby/internal/has/declspec_attribute.h +sha2.o: $(hdrdir)/ruby/internal/has/extension.h +sha2.o: $(hdrdir)/ruby/internal/has/feature.h +sha2.o: $(hdrdir)/ruby/internal/has/warning.h +sha2.o: $(hdrdir)/ruby/internal/intern/array.h +sha2.o: $(hdrdir)/ruby/internal/intern/bignum.h +sha2.o: $(hdrdir)/ruby/internal/intern/class.h +sha2.o: $(hdrdir)/ruby/internal/intern/compar.h +sha2.o: $(hdrdir)/ruby/internal/intern/complex.h +sha2.o: $(hdrdir)/ruby/internal/intern/cont.h +sha2.o: $(hdrdir)/ruby/internal/intern/dir.h +sha2.o: $(hdrdir)/ruby/internal/intern/enum.h +sha2.o: $(hdrdir)/ruby/internal/intern/enumerator.h +sha2.o: $(hdrdir)/ruby/internal/intern/error.h +sha2.o: $(hdrdir)/ruby/internal/intern/eval.h +sha2.o: $(hdrdir)/ruby/internal/intern/file.h +sha2.o: $(hdrdir)/ruby/internal/intern/gc.h +sha2.o: $(hdrdir)/ruby/internal/intern/hash.h +sha2.o: $(hdrdir)/ruby/internal/intern/io.h +sha2.o: $(hdrdir)/ruby/internal/intern/load.h +sha2.o: $(hdrdir)/ruby/internal/intern/marshal.h +sha2.o: $(hdrdir)/ruby/internal/intern/numeric.h +sha2.o: $(hdrdir)/ruby/internal/intern/object.h +sha2.o: $(hdrdir)/ruby/internal/intern/parse.h +sha2.o: $(hdrdir)/ruby/internal/intern/proc.h +sha2.o: $(hdrdir)/ruby/internal/intern/process.h +sha2.o: $(hdrdir)/ruby/internal/intern/random.h +sha2.o: $(hdrdir)/ruby/internal/intern/range.h +sha2.o: $(hdrdir)/ruby/internal/intern/rational.h +sha2.o: $(hdrdir)/ruby/internal/intern/re.h +sha2.o: $(hdrdir)/ruby/internal/intern/ruby.h +sha2.o: $(hdrdir)/ruby/internal/intern/select.h +sha2.o: $(hdrdir)/ruby/internal/intern/select/largesize.h +sha2.o: $(hdrdir)/ruby/internal/intern/signal.h +sha2.o: $(hdrdir)/ruby/internal/intern/sprintf.h +sha2.o: $(hdrdir)/ruby/internal/intern/string.h +sha2.o: $(hdrdir)/ruby/internal/intern/struct.h +sha2.o: $(hdrdir)/ruby/internal/intern/thread.h +sha2.o: $(hdrdir)/ruby/internal/intern/time.h +sha2.o: $(hdrdir)/ruby/internal/intern/variable.h +sha2.o: $(hdrdir)/ruby/internal/intern/vm.h +sha2.o: $(hdrdir)/ruby/internal/interpreter.h +sha2.o: $(hdrdir)/ruby/internal/iterator.h +sha2.o: $(hdrdir)/ruby/internal/memory.h +sha2.o: $(hdrdir)/ruby/internal/method.h +sha2.o: $(hdrdir)/ruby/internal/module.h +sha2.o: $(hdrdir)/ruby/internal/newobj.h +sha2.o: $(hdrdir)/ruby/internal/rgengc.h +sha2.o: $(hdrdir)/ruby/internal/scan_args.h +sha2.o: $(hdrdir)/ruby/internal/special_consts.h +sha2.o: $(hdrdir)/ruby/internal/static_assert.h +sha2.o: $(hdrdir)/ruby/internal/stdalign.h +sha2.o: $(hdrdir)/ruby/internal/stdbool.h +sha2.o: $(hdrdir)/ruby/internal/symbol.h +sha2.o: $(hdrdir)/ruby/internal/token_paste.h +sha2.o: $(hdrdir)/ruby/internal/value.h +sha2.o: $(hdrdir)/ruby/internal/value_type.h +sha2.o: $(hdrdir)/ruby/internal/variable.h +sha2.o: $(hdrdir)/ruby/internal/warning_push.h +sha2.o: $(hdrdir)/ruby/internal/xmalloc.h +sha2.o: $(hdrdir)/ruby/missing.h +sha2.o: $(hdrdir)/ruby/ruby.h +sha2.o: $(hdrdir)/ruby/st.h +sha2.o: $(hdrdir)/ruby/subst.h +sha2.o: $(srcdir)/../defs.h +sha2.o: sha2.c +sha2.o: sha2.h sha2init.o: $(RUBY_EXTCONF_H) sha2init.o: $(arch_hdrdir)/ruby/config.h sha2init.o: $(hdrdir)/ruby.h +sha2init.o: $(hdrdir)/ruby/assert.h +sha2init.o: $(hdrdir)/ruby/backward.h +sha2init.o: $(hdrdir)/ruby/backward/2/assume.h +sha2init.o: $(hdrdir)/ruby/backward/2/attributes.h +sha2init.o: $(hdrdir)/ruby/backward/2/bool.h +sha2init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h +sha2init.o: $(hdrdir)/ruby/backward/2/inttypes.h +sha2init.o: $(hdrdir)/ruby/backward/2/limits.h +sha2init.o: $(hdrdir)/ruby/backward/2/long_long.h +sha2init.o: $(hdrdir)/ruby/backward/2/stdalign.h +sha2init.o: $(hdrdir)/ruby/backward/2/stdarg.h +sha2init.o: $(hdrdir)/ruby/defines.h +sha2init.o: $(hdrdir)/ruby/intern.h sha2init.o: $(hdrdir)/ruby/internal/anyargs.h sha2init.o: $(hdrdir)/ruby/internal/arithmetic.h sha2init.o: $(hdrdir)/ruby/internal/arithmetic/char.h @@ -145,24 +321,12 @@ sha2init.o: $(hdrdir)/ruby/internal/value_type.h sha2init.o: $(hdrdir)/ruby/internal/variable.h sha2init.o: $(hdrdir)/ruby/internal/warning_push.h sha2init.o: $(hdrdir)/ruby/internal/xmalloc.h -sha2init.o: $(hdrdir)/ruby/assert.h -sha2init.o: $(hdrdir)/ruby/backward.h -sha2init.o: $(hdrdir)/ruby/backward/2/assume.h -sha2init.o: $(hdrdir)/ruby/backward/2/attributes.h -sha2init.o: $(hdrdir)/ruby/backward/2/bool.h -sha2init.o: $(hdrdir)/ruby/backward/2/gcc_version_since.h -sha2init.o: $(hdrdir)/ruby/backward/2/inttypes.h -sha2init.o: $(hdrdir)/ruby/backward/2/limits.h -sha2init.o: $(hdrdir)/ruby/backward/2/long_long.h -sha2init.o: $(hdrdir)/ruby/backward/2/stdalign.h -sha2init.o: $(hdrdir)/ruby/backward/2/stdarg.h -sha2init.o: $(hdrdir)/ruby/defines.h -sha2init.o: $(hdrdir)/ruby/intern.h sha2init.o: $(hdrdir)/ruby/missing.h sha2init.o: $(hdrdir)/ruby/ruby.h sha2init.o: $(hdrdir)/ruby/st.h sha2init.o: $(hdrdir)/ruby/subst.h sha2init.o: $(srcdir)/../digest.h +sha2init.o: sha2.h sha2init.o: sha2init.c sha2init.o: sha2ossl.h # AUTOGENERATED DEPENDENCIES END From 8c2e5bbf58e562ea410b53c2f77e4186d5ca9da3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Stu=CC=88ben?= Date: Fri, 25 Sep 2020 19:56:30 +0200 Subject: [PATCH 27/41] Don't redefine #rb_intern over and over again --- array.c | 3 -- compar.c | 3 -- compile.c | 32 +++++++++---------- complex.c | 25 +++++++-------- encoding.c | 2 -- enum.c | 5 +-- ext/date/date_core.c | 11 +++---- ext/openssl/ossl_ssl.c | 66 +++++++++++++++++++--------------------- ext/racc/cparse/cparse.c | 26 ++++++++-------- hash.c | 8 ++--- io.c | 59 +++++++++++++++++------------------ load.c | 6 ++-- marshal.c | 3 -- numeric.c | 9 ++---- object.c | 3 -- process.c | 62 ++++++++++++++++++------------------- range.c | 9 ++---- rational.c | 11 +++---- string.c | 15 ++++----- template/id.c.tmpl | 2 -- thread.c | 11 +++---- time.c | 43 ++++++++++++-------------- vm_method.c | 3 -- 23 files changed, 178 insertions(+), 239 deletions(-) diff --git a/array.c b/array.c index 9183dfc3e6..6cd64129af 100644 --- a/array.c +++ b/array.c @@ -8018,9 +8018,6 @@ rb_ary_deconstruct(VALUE ary) void Init_Array(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - rb_cArray = rb_define_class("Array", rb_cObject); rb_include_module(rb_cArray, rb_mEnumerable); diff --git a/compar.c b/compar.c index 6e64e3d9ef..04d4ff8c70 100644 --- a/compar.c +++ b/compar.c @@ -294,9 +294,6 @@ cmp_clamp(int argc, VALUE *argv, VALUE x) void Init_Comparable(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - rb_mComparable = rb_define_module("Comparable"); rb_define_method(rb_mComparable, "==", cmp_equal, 1); rb_define_method(rb_mComparable, ">", cmp_gt, 1); diff --git a/compile.c b/compile.c index ff63dfe9aa..5086e3349f 100644 --- a/compile.c +++ b/compile.c @@ -9134,18 +9134,16 @@ register_label(rb_iseq_t *iseq, struct st_table *labels_table, VALUE obj) static VALUE get_exception_sym2type(VALUE sym) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) static VALUE symRescue, symEnsure, symRetry; static VALUE symBreak, symRedo, symNext; if (symRescue == 0) { - symRescue = ID2SYM(rb_intern("rescue")); - symEnsure = ID2SYM(rb_intern("ensure")); - symRetry = ID2SYM(rb_intern("retry")); - symBreak = ID2SYM(rb_intern("break")); - symRedo = ID2SYM(rb_intern("redo")); - symNext = ID2SYM(rb_intern("next")); + symRescue = ID2SYM(rb_intern_const("rescue")); + symEnsure = ID2SYM(rb_intern_const("ensure")); + symRetry = ID2SYM(rb_intern_const("retry")); + symBreak = ID2SYM(rb_intern_const("break")); + symRedo = ID2SYM(rb_intern_const("redo")); + symNext = ID2SYM(rb_intern_const("next")); } if (sym == symRescue) return CATCH_TYPE_RESCUE; @@ -9211,7 +9209,7 @@ insn_make_insn_table(void) table = st_init_numtable_with_size(VM_INSTRUCTION_SIZE); for (i=0; ibody->param.flags.has_kw = TRUE; keyword->num = len; -#define SYM(s) ID2SYM(rb_intern(#s)) +#define SYM(s) ID2SYM(rb_intern_const(#s)) (void)int_param(&keyword->bits_start, params, SYM(kwbits)); i = keyword->bits_start - keyword->num; ids = (ID *)&iseq->body->local_table[i]; @@ -9596,7 +9594,7 @@ void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, VALUE exception, VALUE body) { -#define SYM(s) ID2SYM(rb_intern(#s)) +#define SYM(s) ID2SYM(rb_intern_const(#s)) int i, len; unsigned int arg_size, local_size, stack_max; ID *tbl; @@ -9604,7 +9602,7 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, VALUE labels_wrapper = Data_Wrap_Struct(0, rb_mark_set, st_free_table, labels_table); VALUE arg_opt_labels = rb_hash_aref(params, SYM(opt)); VALUE keywords = rb_hash_aref(params, SYM(keyword)); - VALUE sym_arg_rest = ID2SYM(rb_intern("#arg_rest")); + VALUE sym_arg_rest = ID2SYM(rb_intern_const("#arg_rest")); DECL_ANCHOR(anchor); INIT_ANCHOR(anchor); diff --git a/complex.c b/complex.c index 4100fac082..377aae5a93 100644 --- a/complex.c +++ b/complex.c @@ -2337,20 +2337,17 @@ void Init_Complex(void) { VALUE compat; -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - - id_abs = rb_intern("abs"); - id_arg = rb_intern("arg"); - id_denominator = rb_intern("denominator"); - id_numerator = rb_intern("numerator"); - id_real_p = rb_intern("real?"); - id_i_real = rb_intern("@real"); - id_i_imag = rb_intern("@image"); /* @image, not @imag */ - id_finite_p = rb_intern("finite?"); - id_infinite_p = rb_intern("infinite?"); - id_rationalize = rb_intern("rationalize"); - id_PI = rb_intern("PI"); + id_abs = rb_intern_const("abs"); + id_arg = rb_intern_const("arg"); + id_denominator = rb_intern_const("denominator"); + id_numerator = rb_intern_const("numerator"); + id_real_p = rb_intern_const("real?"); + id_i_real = rb_intern_const("@real"); + id_i_imag = rb_intern_const("@image"); /* @image, not @imag */ + id_finite_p = rb_intern_const("finite?"); + id_infinite_p = rb_intern_const("infinite?"); + id_rationalize = rb_intern_const("rationalize"); + id_PI = rb_intern_const("PI"); rb_cComplex = rb_define_class("Complex", rb_cNumeric); diff --git a/encoding.c b/encoding.c index 7f798cd78d..7336421862 100644 --- a/encoding.c +++ b/encoding.c @@ -2145,8 +2145,6 @@ rb_enc_aliases(VALUE klass) void Init_Encoding(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) VALUE list; int i; diff --git a/enum.c b/enum.c index 69c1641a2f..88d6730ce8 100644 --- a/enum.c +++ b/enum.c @@ -4172,9 +4172,6 @@ enum_uniq(VALUE obj) void Init_Enumerable(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - rb_mEnumerable = rb_define_module("Enumerable"); rb_define_method(rb_mEnumerable, "to_a", enum_to_a, -1); @@ -4236,5 +4233,5 @@ Init_Enumerable(void) rb_define_method(rb_mEnumerable, "sum", enum_sum, -1); rb_define_method(rb_mEnumerable, "uniq", enum_uniq, 0); - id_next = rb_intern("next"); + id_next = rb_intern_const("next"); } diff --git a/ext/date/date_core.c b/ext/date/date_core.c index f9567e23e8..bb0482c279 100644 --- a/ext/date/date_core.c +++ b/ext/date/date_core.c @@ -9116,13 +9116,10 @@ d_lite_zero(VALUE x) void Init_date_core(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - - id_cmp = rb_intern("<=>"); - id_le_p = rb_intern("<="); - id_ge_p = rb_intern(">="); - id_eqeq_p = rb_intern("=="); + id_cmp = rb_intern_const("<=>"); + id_le_p = rb_intern_const("<="); + id_ge_p = rb_intern_const(">="); + id_eqeq_p = rb_intern_const("=="); half_days_in_day = rb_rational_new2(INT2FIX(1), INT2FIX(2)); diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index fe2e85b866..4b7efa39f5 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -2456,8 +2456,6 @@ ossl_ssl_tmp_key(VALUE self) # endif /* defined(HAVE_SSL_GET_SERVER_TMP_KEY) */ #endif /* !defined(OPENSSL_NO_SOCK) */ -#undef rb_intern -#define rb_intern(s) rb_intern_const(s) void Init_ossl_ssl(void) { @@ -2468,8 +2466,8 @@ Init_ossl_ssl(void) rb_mWaitWritable = rb_define_module_under(rb_cIO, "WaitWritable"); #endif - id_call = rb_intern("call"); - ID_callback_state = rb_intern("callback_state"); + id_call = rb_intern_const("call"); + ID_callback_state = rb_intern_const("callback_state"); ossl_ssl_ex_vcb_idx = SSL_get_ex_new_index(0, (void *)"ossl_ssl_ex_vcb_idx", 0, 0, 0); if (ossl_ssl_ex_vcb_idx < 0) @@ -2536,7 +2534,7 @@ Init_ossl_ssl(void) * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated. * It is recommended to use #add_certificate instead. */ - rb_attr(cSSLContext, rb_intern("cert"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("cert"), 1, 1, Qfalse); /* * Context private key @@ -2544,29 +2542,29 @@ Init_ossl_ssl(void) * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated. * It is recommended to use #add_certificate instead. */ - rb_attr(cSSLContext, rb_intern("key"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("key"), 1, 1, Qfalse); /* * A certificate or Array of certificates that will be sent to the client. */ - rb_attr(cSSLContext, rb_intern("client_ca"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("client_ca"), 1, 1, Qfalse); /* * The path to a file containing a PEM-format CA certificate */ - rb_attr(cSSLContext, rb_intern("ca_file"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("ca_file"), 1, 1, Qfalse); /* * The path to a directory containing CA certificates in PEM format. * * Files are looked up by subject's X509 name's hash value. */ - rb_attr(cSSLContext, rb_intern("ca_path"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("ca_path"), 1, 1, Qfalse); /* * Maximum session lifetime in seconds. */ - rb_attr(cSSLContext, rb_intern("timeout"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("timeout"), 1, 1, Qfalse); /* * Session verification mode. @@ -2579,12 +2577,12 @@ Init_ossl_ssl(void) * * See SSL_CTX_set_verify(3) for details. */ - rb_attr(cSSLContext, rb_intern("verify_mode"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("verify_mode"), 1, 1, Qfalse); /* * Number of CA certificates to walk when verifying a certificate chain. */ - rb_attr(cSSLContext, rb_intern("verify_depth"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("verify_depth"), 1, 1, Qfalse); /* * A callback for additional certificate verification. The callback is @@ -2598,7 +2596,7 @@ Init_ossl_ssl(void) * If the callback returns +false+, the chain verification is immediately * stopped and a bad_certificate alert is then sent. */ - rb_attr(cSSLContext, rb_intern("verify_callback"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("verify_callback"), 1, 1, Qfalse); /* * Whether to check the server certificate is valid for the hostname. @@ -2606,12 +2604,12 @@ Init_ossl_ssl(void) * In order to make this work, verify_mode must be set to VERIFY_PEER and * the server hostname must be given by OpenSSL::SSL::SSLSocket#hostname=. */ - rb_attr(cSSLContext, rb_intern("verify_hostname"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("verify_hostname"), 1, 1, Qfalse); /* * An OpenSSL::X509::Store used for certificate verification. */ - rb_attr(cSSLContext, rb_intern("cert_store"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("cert_store"), 1, 1, Qfalse); /* * An Array of extra X509 certificates to be added to the certificate @@ -2620,7 +2618,7 @@ Init_ossl_ssl(void) * The _cert_, _key_, and _extra_chain_cert_ attributes are deprecated. * It is recommended to use #add_certificate instead. */ - rb_attr(cSSLContext, rb_intern("extra_chain_cert"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("extra_chain_cert"), 1, 1, Qfalse); /* * A callback invoked when a client certificate is requested by a server @@ -2630,7 +2628,7 @@ Init_ossl_ssl(void) * containing an OpenSSL::X509::Certificate and an OpenSSL::PKey. If any * other value is returned the handshake is suspended. */ - rb_attr(cSSLContext, rb_intern("client_cert_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("client_cert_cb"), 1, 1, Qfalse); #if !defined(OPENSSL_NO_EC) && defined(HAVE_SSL_CTX_SET_TMP_ECDH_CALLBACK) /* @@ -2643,7 +2641,7 @@ Init_ossl_ssl(void) * The callback is deprecated. This does not work with recent versions of * OpenSSL. Use OpenSSL::SSL::SSLContext#ecdh_curves= instead. */ - rb_attr(cSSLContext, rb_intern("tmp_ecdh_callback"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("tmp_ecdh_callback"), 1, 1, Qfalse); #endif /* @@ -2651,7 +2649,7 @@ Init_ossl_ssl(void) * sessions for multiple applications to be distinguished, for example, by * name. */ - rb_attr(cSSLContext, rb_intern("session_id_context"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("session_id_context"), 1, 1, Qfalse); /* * A callback invoked on a server when a session is proposed by the client @@ -2660,7 +2658,7 @@ Init_ossl_ssl(void) * The callback is invoked with the SSLSocket and session id. The * callback may return a Session from an external cache. */ - rb_attr(cSSLContext, rb_intern("session_get_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("session_get_cb"), 1, 1, Qfalse); /* * A callback invoked when a new session was negotiated. @@ -2668,7 +2666,7 @@ Init_ossl_ssl(void) * The callback is invoked with an SSLSocket. If +false+ is returned the * session will be removed from the internal cache. */ - rb_attr(cSSLContext, rb_intern("session_new_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("session_new_cb"), 1, 1, Qfalse); /* * A callback invoked when a session is removed from the internal cache. @@ -2679,7 +2677,7 @@ Init_ossl_ssl(void) * multi-threaded application. The callback is called inside a global lock * and it can randomly cause deadlock on Ruby thread switching. */ - rb_attr(cSSLContext, rb_intern("session_remove_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("session_remove_cb"), 1, 1, Qfalse); rb_define_const(mSSLExtConfig, "HAVE_TLSEXT_HOST_NAME", Qtrue); @@ -2702,7 +2700,7 @@ Init_ossl_ssl(void) * raise RuntimeError, "Client renegotiation disabled" * end */ - rb_attr(cSSLContext, rb_intern("renegotiation_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("renegotiation_cb"), 1, 1, Qfalse); #ifndef OPENSSL_NO_NEXTPROTONEG /* * An Enumerable of Strings. Each String represents a protocol to be @@ -2715,7 +2713,7 @@ Init_ossl_ssl(void) * * ctx.npn_protocols = ["http/1.1", "spdy/2"] */ - rb_attr(cSSLContext, rb_intern("npn_protocols"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("npn_protocols"), 1, 1, Qfalse); /* * A callback invoked on the client side when the client needs to select * a protocol from the list sent by the server. Supported in OpenSSL 1.0.1 @@ -2732,7 +2730,7 @@ Init_ossl_ssl(void) * protocols.first * end */ - rb_attr(cSSLContext, rb_intern("npn_select_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("npn_select_cb"), 1, 1, Qfalse); #endif #ifdef HAVE_SSL_CTX_SET_ALPN_SELECT_CB @@ -2747,7 +2745,7 @@ Init_ossl_ssl(void) * * ctx.alpn_protocols = ["http/1.1", "spdy/2", "h2"] */ - rb_attr(cSSLContext, rb_intern("alpn_protocols"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("alpn_protocols"), 1, 1, Qfalse); /* * A callback invoked on the server side when the server needs to select * a protocol from the list sent by the client. Supported in OpenSSL 1.0.2 @@ -2764,7 +2762,7 @@ Init_ossl_ssl(void) * protocols.first * end */ - rb_attr(cSSLContext, rb_intern("alpn_select_cb"), 1, 1, Qfalse); + rb_attr(cSSLContext, rb_intern_const("alpn_select_cb"), 1, 1, Qfalse); #endif rb_define_alias(cSSLContext, "ssl_timeout", "timeout"); @@ -2992,16 +2990,16 @@ Init_ossl_ssl(void) #endif - sym_exception = ID2SYM(rb_intern("exception")); - sym_wait_readable = ID2SYM(rb_intern("wait_readable")); - sym_wait_writable = ID2SYM(rb_intern("wait_writable")); + sym_exception = ID2SYM(rb_intern_const("exception")); + sym_wait_readable = ID2SYM(rb_intern_const("wait_readable")); + sym_wait_writable = ID2SYM(rb_intern_const("wait_writable")); - id_tmp_dh_callback = rb_intern("tmp_dh_callback"); - id_tmp_ecdh_callback = rb_intern("tmp_ecdh_callback"); - id_npn_protocols_encoded = rb_intern("npn_protocols_encoded"); + id_tmp_dh_callback = rb_intern_const("tmp_dh_callback"); + id_tmp_ecdh_callback = rb_intern_const("tmp_ecdh_callback"); + id_npn_protocols_encoded = rb_intern_const("npn_protocols_encoded"); #define DefIVarID(name) do \ - id_i_##name = rb_intern("@"#name); while (0) + id_i_##name = rb_intern_const("@"#name); while (0) DefIVarID(cert_store); DefIVarID(ca_file); diff --git a/ext/racc/cparse/cparse.c b/ext/racc/cparse/cparse.c index 4d77bbf298..487784a149 100644 --- a/ext/racc/cparse/cparse.c +++ b/ext/racc/cparse/cparse.c @@ -819,14 +819,12 @@ reduce0(RB_BLOCK_CALL_FUNC_ARGLIST(_, data)) void Init_cparse(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) VALUE Racc, Parser; ID id_racc = rb_intern("Racc"); if (rb_const_defined(rb_cObject, id_racc)) { Racc = rb_const_get(rb_cObject, id_racc); - Parser = rb_const_get_at(Racc, rb_intern("Parser")); + Parser = rb_const_get_at(Racc, rb_intern_const("Parser")); } else { Racc = rb_define_module("Racc"); @@ -846,16 +844,16 @@ Init_cparse(void) RaccBug = rb_eRuntimeError; - id_yydebug = rb_intern("@yydebug"); - id_nexttoken = rb_intern("next_token"); - id_onerror = rb_intern("on_error"); - id_noreduce = rb_intern("_reduce_none"); - id_errstatus = rb_intern("@racc_error_status"); + id_yydebug = rb_intern_const("@yydebug"); + id_nexttoken = rb_intern_const("next_token"); + id_onerror = rb_intern_const("on_error"); + id_noreduce = rb_intern_const("_reduce_none"); + id_errstatus = rb_intern_const("@racc_error_status"); - id_d_shift = rb_intern("racc_shift"); - id_d_reduce = rb_intern("racc_reduce"); - id_d_accept = rb_intern("racc_accept"); - id_d_read_token = rb_intern("racc_read_token"); - id_d_next_state = rb_intern("racc_next_state"); - id_d_e_pop = rb_intern("racc_e_pop"); + id_d_shift = rb_intern_const("racc_shift"); + id_d_reduce = rb_intern_const("racc_reduce"); + id_d_accept = rb_intern_const("racc_accept"); + id_d_read_token = rb_intern_const("racc_read_token"); + id_d_next_state = rb_intern_const("racc_next_state"); + id_d_e_pop = rb_intern_const("racc_e_pop"); } diff --git a/hash.c b/hash.c index 928c4b4cf2..a8d6978f45 100644 --- a/hash.c +++ b/hash.c @@ -6913,11 +6913,9 @@ env_update(VALUE env, VALUE hash) void Init_Hash(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - id_hash = rb_intern("hash"); - id_default = rb_intern("default"); - id_flatten_bang = rb_intern("flatten!"); + id_hash = rb_intern_const("hash"); + id_default = rb_intern_const("default"); + id_flatten_bang = rb_intern_const("flatten!"); id_hash_iter_lev = rb_make_internal_id(); rb_cHash = rb_define_class("Hash", rb_cObject); diff --git a/io.c b/io.c index 3b4ae6d60b..faf8331c58 100644 --- a/io.c +++ b/io.c @@ -13423,9 +13423,6 @@ set_LAST_READ_LINE(VALUE val, ID _x, VALUE *_y) void Init_IO(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - VALUE rb_cARGF; #ifdef __CYGWIN__ #include @@ -13443,12 +13440,12 @@ Init_IO(void) rb_eIOError = rb_define_class("IOError", rb_eStandardError); rb_eEOFError = rb_define_class("EOFError", rb_eIOError); - id_write = rb_intern("write"); - id_read = rb_intern("read"); - id_getc = rb_intern("getc"); - id_flush = rb_intern("flush"); - id_readpartial = rb_intern("readpartial"); - id_set_encoding = rb_intern("set_encoding"); + id_write = rb_intern_const("write"); + id_read = rb_intern_const("read"); + id_getc = rb_intern_const("getc"); + id_flush = rb_intern_const("flush"); + id_readpartial = rb_intern_const("readpartial"); + id_set_encoding = rb_intern_const("set_encoding"); rb_define_global_function("syscall", rb_f_syscall, -1); @@ -13777,33 +13774,33 @@ Init_IO(void) rb_define_method(rb_cFile, "initialize", rb_file_initialize, -1); - sym_mode = ID2SYM(rb_intern("mode")); - sym_perm = ID2SYM(rb_intern("perm")); - sym_flags = ID2SYM(rb_intern("flags")); - sym_extenc = ID2SYM(rb_intern("external_encoding")); - sym_intenc = ID2SYM(rb_intern("internal_encoding")); + sym_mode = ID2SYM(rb_intern_const("mode")); + sym_perm = ID2SYM(rb_intern_const("perm")); + sym_flags = ID2SYM(rb_intern_const("flags")); + sym_extenc = ID2SYM(rb_intern_const("external_encoding")); + sym_intenc = ID2SYM(rb_intern_const("internal_encoding")); sym_encoding = ID2SYM(rb_id_encoding()); - sym_open_args = ID2SYM(rb_intern("open_args")); - sym_textmode = ID2SYM(rb_intern("textmode")); - sym_binmode = ID2SYM(rb_intern("binmode")); - sym_autoclose = ID2SYM(rb_intern("autoclose")); - sym_normal = ID2SYM(rb_intern("normal")); - sym_sequential = ID2SYM(rb_intern("sequential")); - sym_random = ID2SYM(rb_intern("random")); - sym_willneed = ID2SYM(rb_intern("willneed")); - sym_dontneed = ID2SYM(rb_intern("dontneed")); - sym_noreuse = ID2SYM(rb_intern("noreuse")); - sym_SET = ID2SYM(rb_intern("SET")); - sym_CUR = ID2SYM(rb_intern("CUR")); - sym_END = ID2SYM(rb_intern("END")); + sym_open_args = ID2SYM(rb_intern_const("open_args")); + sym_textmode = ID2SYM(rb_intern_const("textmode")); + sym_binmode = ID2SYM(rb_intern_const("binmode")); + sym_autoclose = ID2SYM(rb_intern_const("autoclose")); + sym_normal = ID2SYM(rb_intern_const("normal")); + sym_sequential = ID2SYM(rb_intern_const("sequential")); + sym_random = ID2SYM(rb_intern_const("random")); + sym_willneed = ID2SYM(rb_intern_const("willneed")); + sym_dontneed = ID2SYM(rb_intern_const("dontneed")); + sym_noreuse = ID2SYM(rb_intern_const("noreuse")); + sym_SET = ID2SYM(rb_intern_const("SET")); + sym_CUR = ID2SYM(rb_intern_const("CUR")); + sym_END = ID2SYM(rb_intern_const("END")); #ifdef SEEK_DATA - sym_DATA = ID2SYM(rb_intern("DATA")); + sym_DATA = ID2SYM(rb_intern_const("DATA")); #endif #ifdef SEEK_HOLE - sym_HOLE = ID2SYM(rb_intern("HOLE")); + sym_HOLE = ID2SYM(rb_intern_const("HOLE")); #endif - sym_wait_readable = ID2SYM(rb_intern("wait_readable")); - sym_wait_writable = ID2SYM(rb_intern("wait_writable")); + sym_wait_readable = ID2SYM(rb_intern_const("wait_readable")); + sym_wait_writable = ID2SYM(rb_intern_const("wait_writable")); } #include "io.rbinc" diff --git a/load.c b/load.c index cb3a6c03b1..00ae31e705 100644 --- a/load.c +++ b/load.c @@ -1265,15 +1265,13 @@ rb_f_autoload_p(int argc, VALUE *argv, VALUE obj) void Init_load(void) { -#undef rb_intern -#define rb_intern(str) rb_intern2((str), strlen(str)) rb_vm_t *vm = GET_VM(); static const char var_load_path[] = "$:"; ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1); rb_define_hooked_variable(var_load_path, (VALUE*)vm, load_path_getter, rb_gvar_readonly_setter); - rb_alias_variable(rb_intern("$-I"), id_load_path); - rb_alias_variable(rb_intern("$LOAD_PATH"), id_load_path); + rb_alias_variable(rb_intern_const("$-I"), id_load_path); + rb_alias_variable(rb_intern_const("$LOAD_PATH"), id_load_path); vm->load_path = rb_ary_new(); vm->expanded_load_path = rb_ary_tmp_new(0); vm->load_path_snapshot = rb_ary_tmp_new(0); diff --git a/marshal.c b/marshal.c index 10114dd3e3..d629a11046 100644 --- a/marshal.c +++ b/marshal.c @@ -2323,9 +2323,6 @@ rb_marshal_load_with_proc(VALUE port, VALUE proc) void Init_marshal(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - VALUE rb_mMarshal = rb_define_module("Marshal"); #define set_id(sym) sym = rb_intern_const(name_##sym) set_id(s_dump); diff --git a/numeric.c b/numeric.c index 4a61d64368..fb9b28bcb3 100644 --- a/numeric.c +++ b/numeric.c @@ -5542,16 +5542,13 @@ rb_int_s_isqrt(VALUE self, VALUE num) void Init_Numeric(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - #ifdef _UNICOSMP /* Turn off floating point exceptions for divide by zero, etc. */ _set_Creg(0, 0); #endif - id_coerce = rb_intern("coerce"); - id_to = rb_intern("to"); - id_by = rb_intern("by"); + id_coerce = rb_intern_const("coerce"); + id_to = rb_intern_const("to"); + id_by = rb_intern_const("by"); rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError); rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eRangeError); diff --git a/object.c b/object.c index 68f7dc2653..572bfd5a5b 100644 --- a/object.c +++ b/object.c @@ -4479,9 +4479,6 @@ InitVM_Object(void) rb_cClass = rb_define_class("Class", rb_cModule); #endif -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - rb_define_private_method(rb_cBasicObject, "initialize", rb_obj_dummy0, 0); rb_define_alloc_func(rb_cBasicObject, rb_class_allocate_instance); rb_define_method(rb_cBasicObject, "==", rb_obj_equal, 1); diff --git a/process.c b/process.c index 90db3c5677..5ec02f445d 100644 --- a/process.c +++ b/process.c @@ -8441,8 +8441,6 @@ static VALUE rb_mProcID_Syscall; void InitVM_process(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) rb_define_virtual_variable("$?", get_CHILD_STATUS, 0); rb_define_virtual_variable("$$", get_PROCESS_ID, 0); @@ -8872,46 +8870,46 @@ InitVM_process(void) void Init_process(void) { - id_in = rb_intern("in"); - id_out = rb_intern("out"); - id_err = rb_intern("err"); - id_pid = rb_intern("pid"); - id_uid = rb_intern("uid"); - id_gid = rb_intern("gid"); - id_close = rb_intern("close"); - id_child = rb_intern("child"); + id_in = rb_intern_const("in"); + id_out = rb_intern_const("out"); + id_err = rb_intern_const("err"); + id_pid = rb_intern_const("pid"); + id_uid = rb_intern_const("uid"); + id_gid = rb_intern_const("gid"); + id_close = rb_intern_const("close"); + id_child = rb_intern_const("child"); #ifdef HAVE_SETPGID - id_pgroup = rb_intern("pgroup"); + id_pgroup = rb_intern_const("pgroup"); #endif #ifdef _WIN32 - id_new_pgroup = rb_intern("new_pgroup"); + id_new_pgroup = rb_intern_const("new_pgroup"); #endif - id_unsetenv_others = rb_intern("unsetenv_others"); - id_chdir = rb_intern("chdir"); - id_umask = rb_intern("umask"); - id_close_others = rb_intern("close_others"); - id_ENV = rb_intern("ENV"); - id_nanosecond = rb_intern("nanosecond"); - id_microsecond = rb_intern("microsecond"); - id_millisecond = rb_intern("millisecond"); - id_second = rb_intern("second"); - id_float_microsecond = rb_intern("float_microsecond"); - id_float_millisecond = rb_intern("float_millisecond"); - id_float_second = rb_intern("float_second"); - id_GETTIMEOFDAY_BASED_CLOCK_REALTIME = rb_intern("GETTIMEOFDAY_BASED_CLOCK_REALTIME"); - id_TIME_BASED_CLOCK_REALTIME = rb_intern("TIME_BASED_CLOCK_REALTIME"); + id_unsetenv_others = rb_intern_const("unsetenv_others"); + id_chdir = rb_intern_const("chdir"); + id_umask = rb_intern_const("umask"); + id_close_others = rb_intern_const("close_others"); + id_ENV = rb_intern_const("ENV"); + id_nanosecond = rb_intern_const("nanosecond"); + id_microsecond = rb_intern_const("microsecond"); + id_millisecond = rb_intern_const("millisecond"); + id_second = rb_intern_const("second"); + id_float_microsecond = rb_intern_const("float_microsecond"); + id_float_millisecond = rb_intern_const("float_millisecond"); + id_float_second = rb_intern_const("float_second"); + id_GETTIMEOFDAY_BASED_CLOCK_REALTIME = rb_intern_const("GETTIMEOFDAY_BASED_CLOCK_REALTIME"); + id_TIME_BASED_CLOCK_REALTIME = rb_intern_const("TIME_BASED_CLOCK_REALTIME"); #ifdef HAVE_TIMES - id_TIMES_BASED_CLOCK_MONOTONIC = rb_intern("TIMES_BASED_CLOCK_MONOTONIC"); - id_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern("TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID"); + id_TIMES_BASED_CLOCK_MONOTONIC = rb_intern_const("TIMES_BASED_CLOCK_MONOTONIC"); + id_TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern_const("TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID"); #endif #ifdef RUSAGE_SELF - id_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern("GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID"); + id_GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern_const("GETRUSAGE_BASED_CLOCK_PROCESS_CPUTIME_ID"); #endif - id_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern("CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID"); + id_CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID = rb_intern_const("CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID"); #ifdef __APPLE__ - id_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC = rb_intern("MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC"); + id_MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC = rb_intern_const("MACH_ABSOLUTE_TIME_BASED_CLOCK_MONOTONIC"); #endif - id_hertz = rb_intern("hertz"); + id_hertz = rb_intern_const("hertz"); InitVM(process); } diff --git a/range.c b/range.c index a82763ca76..c59662da0d 100644 --- a/range.c +++ b/range.c @@ -1839,12 +1839,9 @@ range_count(int argc, VALUE *argv, VALUE range) void Init_Range(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - - id_beg = rb_intern("begin"); - id_end = rb_intern("end"); - id_excl = rb_intern("excl"); + id_beg = rb_intern_const("begin"); + id_end = rb_intern_const("end"); + id_excl = rb_intern_const("excl"); rb_cRange = rb_struct_define_without_accessor( "Range", rb_cObject, range_alloc, diff --git a/rational.c b/rational.c index aa90342027..6ac42bff04 100644 --- a/rational.c +++ b/rational.c @@ -2723,13 +2723,10 @@ void Init_Rational(void) { VALUE compat; -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - - id_abs = rb_intern("abs"); - id_integer_p = rb_intern("integer?"); - id_i_num = rb_intern("@numerator"); - id_i_den = rb_intern("@denominator"); + id_abs = rb_intern_const("abs"); + id_integer_p = rb_intern_const("integer?"); + id_i_num = rb_intern_const("@numerator"); + id_i_den = rb_intern_const("@denominator"); rb_cRational = rb_define_class("Rational", rb_cNumeric); diff --git a/string.c b/string.c index 556b03addc..069aef199e 100644 --- a/string.c +++ b/string.c @@ -11418,9 +11418,6 @@ sym_all_symbols(VALUE _) void Init_String(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - rb_cString = rb_define_class("String", rb_cObject); assert(rb_vm_fstring_table()); st_foreach(rb_vm_fstring_table(), fstring_set_class_i, rb_cString); @@ -11476,10 +11473,10 @@ Init_String(void) rb_define_method(rb_cString, "dump", rb_str_dump, 0); rb_define_method(rb_cString, "undump", str_undump, 0); - sym_ascii = ID2SYM(rb_intern("ascii")); - sym_turkic = ID2SYM(rb_intern("turkic")); - sym_lithuanian = ID2SYM(rb_intern("lithuanian")); - sym_fold = ID2SYM(rb_intern("fold")); + sym_ascii = ID2SYM(rb_intern_const("ascii")); + sym_turkic = ID2SYM(rb_intern_const("turkic")); + sym_lithuanian = ID2SYM(rb_intern_const("lithuanian")); + sym_fold = ID2SYM(rb_intern_const("fold")); rb_define_method(rb_cString, "upcase", rb_str_upcase, -1); rb_define_method(rb_cString, "downcase", rb_str_downcase, -1); @@ -11572,8 +11569,8 @@ Init_String(void) /* define UnicodeNormalize module here so that we don't have to look it up */ mUnicodeNormalize = rb_define_module("UnicodeNormalize"); - id_normalize = rb_intern("normalize"); - id_normalized_p = rb_intern("normalized?"); + id_normalize = rb_intern_const("normalize"); + id_normalized_p = rb_intern_const("normalized?"); rb_define_method(rb_cString, "unicode_normalize", rb_str_unicode_normalize, -1); rb_define_method(rb_cString, "unicode_normalize!", rb_str_unicode_normalize_bang, -1); diff --git a/template/id.c.tmpl b/template/id.c.tmpl index 477a76bc26..4f30875c04 100644 --- a/template/id.c.tmpl +++ b/template/id.c.tmpl @@ -33,8 +33,6 @@ static const struct { static void Init_id(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) rb_encoding *enc = rb_usascii_encoding(); % ids[:predefined].each do |token, name| diff --git a/thread.c b/thread.c index 40c84f8e55..64d9ac03dd 100644 --- a/thread.c +++ b/thread.c @@ -5459,15 +5459,12 @@ Init_Thread_Mutex() void Init_Thread(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - VALUE cThGroup; rb_thread_t *th = GET_THREAD(); - sym_never = ID2SYM(rb_intern("never")); - sym_immediate = ID2SYM(rb_intern("immediate")); - sym_on_blocking = ID2SYM(rb_intern("on_blocking")); + sym_never = ID2SYM(rb_intern_const("never")); + sym_immediate = ID2SYM(rb_intern_const("immediate")); + sym_on_blocking = ID2SYM(rb_intern_const("on_blocking")); rb_define_singleton_method(rb_cThread, "new", thread_s_new, -1); rb_define_singleton_method(rb_cThread, "start", thread_start, -2); @@ -5547,7 +5544,7 @@ Init_Thread(void) rb_define_const(cThGroup, "Default", th->thgroup); } - recursive_key = rb_intern("__recursive_key__"); + recursive_key = rb_intern_const("__recursive_key__"); rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError); /* init thread core */ diff --git a/time.c b/time.c index 3073e154c9..0b3692f494 100644 --- a/time.c +++ b/time.c @@ -5860,29 +5860,26 @@ rb_time_zone_abbreviation(VALUE zone, VALUE time) void Init_Time(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - - id_submicro = rb_intern("submicro"); - id_nano_num = rb_intern("nano_num"); - id_nano_den = rb_intern("nano_den"); - id_offset = rb_intern("offset"); - id_zone = rb_intern("zone"); - id_nanosecond = rb_intern("nanosecond"); - id_microsecond = rb_intern("microsecond"); - id_millisecond = rb_intern("millisecond"); - id_nsec = rb_intern("nsec"); - id_usec = rb_intern("usec"); - id_local_to_utc = rb_intern("local_to_utc"); - id_utc_to_local = rb_intern("utc_to_local"); - id_year = rb_intern("year"); - id_mon = rb_intern("mon"); - id_mday = rb_intern("mday"); - id_hour = rb_intern("hour"); - id_min = rb_intern("min"); - id_sec = rb_intern("sec"); - id_isdst = rb_intern("isdst"); - id_find_timezone = rb_intern("find_timezone"); + id_submicro = rb_intern_const("submicro"); + id_nano_num = rb_intern_const("nano_num"); + id_nano_den = rb_intern_const("nano_den"); + id_offset = rb_intern_const("offset"); + id_zone = rb_intern_const("zone"); + id_nanosecond = rb_intern_const("nanosecond"); + id_microsecond = rb_intern_const("microsecond"); + id_millisecond = rb_intern_const("millisecond"); + id_nsec = rb_intern_const("nsec"); + id_usec = rb_intern_const("usec"); + id_local_to_utc = rb_intern_const("local_to_utc"); + id_utc_to_local = rb_intern_const("utc_to_local"); + id_year = rb_intern_const("year"); + id_mon = rb_intern_const("mon"); + id_mday = rb_intern_const("mday"); + id_hour = rb_intern_const("hour"); + id_min = rb_intern_const("min"); + id_sec = rb_intern_const("sec"); + id_isdst = rb_intern_const("isdst"); + id_find_timezone = rb_intern_const("find_timezone"); str_utc = rb_fstring_lit("UTC"); rb_gc_register_mark_object(str_utc); diff --git a/vm_method.c b/vm_method.c index 47ad040914..e229d8b356 100644 --- a/vm_method.c +++ b/vm_method.c @@ -2482,9 +2482,6 @@ Init_Method(void) void Init_eval_method(void) { -#undef rb_intern -#define rb_intern(str) rb_intern_const(str) - rb_define_method(rb_mKernel, "respond_to?", obj_respond_to, -1); rb_define_method(rb_mKernel, "respond_to_missing?", obj_respond_to_missing, 2); From 5a77e90fe843a2bfbde3df1867f142efb0ffe9fe Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 21 Oct 2020 12:46:40 +0900 Subject: [PATCH 28/41] Use rb_intern_const instead of rb_intern in Init functions ``` find . -name \*.o -exec nm {} + |& sed '/Init_.*\.rbimpl_id/!d;s/^.* b //;s/\.[1-9][0-9]*$//;s/\.rbimpl_id$//' | uniq ``` should be empty. --- error.c | 2 +- ext/-test-/memory_view/memory_view.c | 42 ++++++++++++++-------------- ext/-test-/string/coderange.c | 8 +++--- ext/openssl/ossl_ts.c | 26 ++++++++--------- ext/racc/cparse/cparse.c | 2 +- memory_view.c | 2 +- time.c | 2 +- 7 files changed, 42 insertions(+), 42 deletions(-) diff --git a/error.c b/error.c index 4d534f7c04..d58075f4b5 100644 --- a/error.c +++ b/error.c @@ -2817,7 +2817,7 @@ Init_Exception(void) warning_categories = rb_hash_new(); rb_gc_register_mark_object(warning_categories); - rb_hash_aset(warning_categories, ID2SYM(rb_intern("deprecated")), Qtrue); + rb_hash_aset(warning_categories, ID2SYM(rb_intern_const("deprecated")), Qtrue); rb_obj_freeze(warning_categories); } diff --git a/ext/-test-/memory_view/memory_view.c b/ext/-test-/memory_view/memory_view.c index a59e7b872b..0ae9f457ac 100644 --- a/ext/-test-/memory_view/memory_view.c +++ b/ext/-test-/memory_view/memory_view.c @@ -350,35 +350,35 @@ Init_memory_view(void) rb_define_method(cMDView, "[]", mdview_aref, 1); rb_memory_view_register(cMDView, &mdview_memory_view_entry); - id_str = rb_intern("__str__"); - sym_format = ID2SYM(rb_intern("format")); - sym_native_size_p = ID2SYM(rb_intern("native_size_p")); - sym_offset = ID2SYM(rb_intern("offset")); - sym_size = ID2SYM(rb_intern("size")); - sym_repeat = ID2SYM(rb_intern("repeat")); - sym_obj = ID2SYM(rb_intern("obj")); - sym_len = ID2SYM(rb_intern("len")); - sym_readonly = ID2SYM(rb_intern("readonly")); - sym_format = ID2SYM(rb_intern("format")); - sym_item_size = ID2SYM(rb_intern("item_size")); - sym_ndim = ID2SYM(rb_intern("ndim")); - sym_shape = ID2SYM(rb_intern("shape")); - sym_strides = ID2SYM(rb_intern("strides")); - sym_sub_offsets = ID2SYM(rb_intern("sub_offsets")); - sym_endianness = ID2SYM(rb_intern("endianness")); - sym_little_endian = ID2SYM(rb_intern("little_endian")); - sym_big_endian = ID2SYM(rb_intern("big_endian")); + id_str = rb_intern_const("__str__"); + sym_format = ID2SYM(rb_intern_const("format")); + sym_native_size_p = ID2SYM(rb_intern_const("native_size_p")); + sym_offset = ID2SYM(rb_intern_const("offset")); + sym_size = ID2SYM(rb_intern_const("size")); + sym_repeat = ID2SYM(rb_intern_const("repeat")); + sym_obj = ID2SYM(rb_intern_const("obj")); + sym_len = ID2SYM(rb_intern_const("len")); + sym_readonly = ID2SYM(rb_intern_const("readonly")); + sym_format = ID2SYM(rb_intern_const("format")); + sym_item_size = ID2SYM(rb_intern_const("item_size")); + sym_ndim = ID2SYM(rb_intern_const("ndim")); + sym_shape = ID2SYM(rb_intern_const("shape")); + sym_strides = ID2SYM(rb_intern_const("strides")); + sym_sub_offsets = ID2SYM(rb_intern_const("sub_offsets")); + sym_endianness = ID2SYM(rb_intern_const("endianness")); + sym_little_endian = ID2SYM(rb_intern_const("little_endian")); + sym_big_endian = ID2SYM(rb_intern_const("big_endian")); #ifdef WORDS_BIGENDIAN - rb_const_set(mMemoryViewTestUtils, rb_intern("NATIVE_ENDIAN"), sym_big_endian); + rb_const_set(mMemoryViewTestUtils, rb_intern_const("NATIVE_ENDIAN"), sym_big_endian); #else - rb_const_set(mMemoryViewTestUtils, rb_intern("NATIVE_ENDIAN"), sym_little_endian); + rb_const_set(mMemoryViewTestUtils, rb_intern_const("NATIVE_ENDIAN"), sym_little_endian); #endif #define DEF_ALIGNMENT_CONST(type, TYPE) do { \ int alignment; \ STRUCT_ALIGNOF(type, alignment); \ - rb_const_set(mMemoryViewTestUtils, rb_intern(#TYPE "_ALIGNMENT"), INT2FIX(alignment)); \ + rb_const_set(mMemoryViewTestUtils, rb_intern_const(#TYPE "_ALIGNMENT"), INT2FIX(alignment)); \ } while(0) DEF_ALIGNMENT_CONST(short, SHORT); diff --git a/ext/-test-/string/coderange.c b/ext/-test-/string/coderange.c index 1342ce20da..bc998ca372 100644 --- a/ext/-test-/string/coderange.c +++ b/ext/-test-/string/coderange.c @@ -38,10 +38,10 @@ str_coderange_scan(VALUE str) void Init_string_coderange(VALUE klass) { - sym_7bit = ID2SYM(rb_intern("7bit")); - sym_valid = ID2SYM(rb_intern("valid")); - sym_unknown = ID2SYM(rb_intern("unknown")); - sym_broken = ID2SYM(rb_intern("broken")); + sym_7bit = ID2SYM(rb_intern_const("7bit")); + sym_valid = ID2SYM(rb_intern_const("valid")); + sym_unknown = ID2SYM(rb_intern_const("unknown")); + sym_broken = ID2SYM(rb_intern_const("broken")); rb_define_method(klass, "coderange", str_coderange, 0); rb_define_method(klass, "coderange_scan", str_coderange_scan, 0); } diff --git a/ext/openssl/ossl_ts.c b/ext/openssl/ossl_ts.c index 160ec0d8dd..d3209c3d40 100644 --- a/ext/openssl/ossl_ts.c +++ b/ext/openssl/ossl_ts.c @@ -1247,24 +1247,24 @@ Init_ossl_ts(void) * timestamp server rejects the message imprint algorithm used in the * +Request+ */ - sBAD_ALG = rb_intern("BAD_ALG"); + sBAD_ALG = rb_intern_const("BAD_ALG"); /* * Possible return value for +Response#failure_info+. Indicates that the * timestamp server was not able to process the +Request+ properly. */ - sBAD_REQUEST = rb_intern("BAD_REQUEST"); + sBAD_REQUEST = rb_intern_const("BAD_REQUEST"); /* * Possible return value for +Response#failure_info+. Indicates that the * timestamp server was not able to parse certain data in the +Request+. */ - sBAD_DATA_FORMAT = rb_intern("BAD_DATA_FORMAT"); + sBAD_DATA_FORMAT = rb_intern_const("BAD_DATA_FORMAT"); - sTIME_NOT_AVAILABLE = rb_intern("TIME_NOT_AVAILABLE"); - sUNACCEPTED_POLICY = rb_intern("UNACCEPTED_POLICY"); - sUNACCEPTED_EXTENSION = rb_intern("UNACCEPTED_EXTENSION"); - sADD_INFO_NOT_AVAILABLE = rb_intern("ADD_INFO_NOT_AVAILABLE"); - sSYSTEM_FAILURE = rb_intern("SYSTEM_FAILURE"); + sTIME_NOT_AVAILABLE = rb_intern_const("TIME_NOT_AVAILABLE"); + sUNACCEPTED_POLICY = rb_intern_const("UNACCEPTED_POLICY"); + sUNACCEPTED_EXTENSION = rb_intern_const("UNACCEPTED_EXTENSION"); + sADD_INFO_NOT_AVAILABLE = rb_intern_const("ADD_INFO_NOT_AVAILABLE"); + sSYSTEM_FAILURE = rb_intern_const("SYSTEM_FAILURE"); /* Document-class: OpenSSL::Timestamp * Provides classes and methods to request, create and validate @@ -1503,11 +1503,11 @@ Init_ossl_ts(void) * */ cTimestampFactory = rb_define_class_under(mTimestamp, "Factory", rb_cObject); - rb_attr(cTimestampFactory, rb_intern("allowed_digests"), 1, 1, 0); - rb_attr(cTimestampFactory, rb_intern("default_policy_id"), 1, 1, 0); - rb_attr(cTimestampFactory, rb_intern("serial_number"), 1, 1, 0); - rb_attr(cTimestampFactory, rb_intern("gen_time"), 1, 1, 0); - rb_attr(cTimestampFactory, rb_intern("additional_certs"), 1, 1, 0); + rb_attr(cTimestampFactory, rb_intern_const("allowed_digests"), 1, 1, 0); + rb_attr(cTimestampFactory, rb_intern_const("default_policy_id"), 1, 1, 0); + rb_attr(cTimestampFactory, rb_intern_const("serial_number"), 1, 1, 0); + rb_attr(cTimestampFactory, rb_intern_const("gen_time"), 1, 1, 0); + rb_attr(cTimestampFactory, rb_intern_const("additional_certs"), 1, 1, 0); rb_define_method(cTimestampFactory, "create_timestamp", ossl_tsfac_create_ts, 3); } diff --git a/ext/racc/cparse/cparse.c b/ext/racc/cparse/cparse.c index 487784a149..8fa10693ed 100644 --- a/ext/racc/cparse/cparse.c +++ b/ext/racc/cparse/cparse.c @@ -820,7 +820,7 @@ void Init_cparse(void) { VALUE Racc, Parser; - ID id_racc = rb_intern("Racc"); + ID id_racc = rb_intern_const("Racc"); if (rb_const_defined(rb_cObject, id_racc)) { Racc = rb_const_get(rb_cObject, id_racc); diff --git a/memory_view.c b/memory_view.c index 4f3d8e3c55..b2d81cb957 100644 --- a/memory_view.c +++ b/memory_view.c @@ -502,5 +502,5 @@ rb_memory_view_release(rb_memory_view_t* view) void Init_MemoryView(void) { - id_memory_view = rb_intern("__memory_view__"); + id_memory_view = rb_intern_const("__memory_view__"); } diff --git a/time.c b/time.c index 0b3692f494..ff236ce45b 100644 --- a/time.c +++ b/time.c @@ -5686,7 +5686,7 @@ Init_tm(VALUE outer, const char *name) #endif rb_define_method(tm, "initialize", tm_initialize, -1); rb_define_method(tm, "utc", tm_to_time, 0); - rb_alias(tm, rb_intern("to_time"), rb_intern("utc")); + rb_alias(tm, rb_intern_const("to_time"), rb_intern_const("utc")); rb_define_singleton_method(tm, "from_time", tm_from_time, 1); /* :startdoc:*/ From 4640c4ea8a693a9a8468251135afff837904a3a5 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Wed, 21 Oct 2020 13:03:07 +0900 Subject: [PATCH 29/41] Removed more unnecessary ID caches ``` find . -name \*.o -exec nm {} + |& grep -e 'InitVM_.*\.rbimpl_id' -e 'Init_.*\.rbimpl_id' | sed 's/^.* b //;s/\.[1-9][0-9]*$//;s/\.rbimpl_id$//' | uniq ``` should be empty. --- enumerator.c | 107 ++++++++++++++++++++++++++------------------------- 1 file changed, 54 insertions(+), 53 deletions(-) diff --git a/enumerator.c b/enumerator.c index 6e88c5db4a..953d8f13a9 100644 --- a/enumerator.c +++ b/enumerator.c @@ -3933,10 +3933,11 @@ arith_seq_size(VALUE self) return len; } +#define sym(name) ID2SYM(rb_intern_const(name)) void InitVM_Enumerator(void) { - ID id_private = rb_intern("private"); + ID id_private = rb_intern_const("private"); rb_define_method(rb_mKernel, "to_enum", obj_to_enum, -1); rb_define_method(rb_mKernel, "enum_for", obj_to_enum, -1); @@ -3986,23 +3987,23 @@ InitVM_Enumerator(void) rb_define_alias(rb_cLazy, "_enumerable_uniq", "uniq"); rb_define_private_method(rb_cLazy, "_enumerable_with_index", enumerator_with_index, -1); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_map"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_collect"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_flat_map"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_collect_concat"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_select"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_find_all"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_filter"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_filter_map"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_reject"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_grep"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_grep_v"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_zip"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_take"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_take_while"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_drop"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_drop_while"))); - rb_funcall(rb_cLazy, id_private, 1, ID2SYM(rb_intern("_enumerable_uniq"))); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_map")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_collect")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_flat_map")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_collect_concat")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_select")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_find_all")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_filter")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_filter_map")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_reject")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_grep")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_grep_v")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_zip")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_take")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_take_while")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_drop")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_drop_while")); + rb_funcall(rb_cLazy, id_private, 1, sym("_enumerable_uniq")); rb_define_method(rb_cLazy, "initialize", lazy_initialize, -1); rb_define_method(rb_cLazy, "to_enum", lazy_to_enum, -1); @@ -4034,24 +4035,24 @@ InitVM_Enumerator(void) rb_define_method(rb_cLazy, "with_index", lazy_with_index, -1); lazy_use_super_method = rb_hash_new_with_size(18); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("map")), ID2SYM(rb_intern("_enumerable_map"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("collect")), ID2SYM(rb_intern("_enumerable_collect"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("flat_map")), ID2SYM(rb_intern("_enumerable_flat_map"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("collect_concat")), ID2SYM(rb_intern("_enumerable_collect_concat"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("select")), ID2SYM(rb_intern("_enumerable_select"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("find_all")), ID2SYM(rb_intern("_enumerable_find_all"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("filter")), ID2SYM(rb_intern("_enumerable_filter"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("filter_map")), ID2SYM(rb_intern("_enumerable_filter_map"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("reject")), ID2SYM(rb_intern("_enumerable_reject"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("grep")), ID2SYM(rb_intern("_enumerable_grep"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("grep_v")), ID2SYM(rb_intern("_enumerable_grep_v"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("zip")), ID2SYM(rb_intern("_enumerable_zip"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("take")), ID2SYM(rb_intern("_enumerable_take"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("take_while")), ID2SYM(rb_intern("_enumerable_take_while"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("drop")), ID2SYM(rb_intern("_enumerable_drop"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("drop_while")), ID2SYM(rb_intern("_enumerable_drop_while"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("uniq")), ID2SYM(rb_intern("_enumerable_uniq"))); - rb_hash_aset(lazy_use_super_method, ID2SYM(rb_intern("with_index")), ID2SYM(rb_intern("_enumerable_with_index"))); + rb_hash_aset(lazy_use_super_method, sym("map"), sym("_enumerable_map")); + rb_hash_aset(lazy_use_super_method, sym("collect"), sym("_enumerable_collect")); + rb_hash_aset(lazy_use_super_method, sym("flat_map"), sym("_enumerable_flat_map")); + rb_hash_aset(lazy_use_super_method, sym("collect_concat"), sym("_enumerable_collect_concat")); + rb_hash_aset(lazy_use_super_method, sym("select"), sym("_enumerable_select")); + rb_hash_aset(lazy_use_super_method, sym("find_all"), sym("_enumerable_find_all")); + rb_hash_aset(lazy_use_super_method, sym("filter"), sym("_enumerable_filter")); + rb_hash_aset(lazy_use_super_method, sym("filter_map"), sym("_enumerable_filter_map")); + rb_hash_aset(lazy_use_super_method, sym("reject"), sym("_enumerable_reject")); + rb_hash_aset(lazy_use_super_method, sym("grep"), sym("_enumerable_grep")); + rb_hash_aset(lazy_use_super_method, sym("grep_v"), sym("_enumerable_grep_v")); + rb_hash_aset(lazy_use_super_method, sym("zip"), sym("_enumerable_zip")); + rb_hash_aset(lazy_use_super_method, sym("take"), sym("_enumerable_take")); + rb_hash_aset(lazy_use_super_method, sym("take_while"), sym("_enumerable_take_while")); + rb_hash_aset(lazy_use_super_method, sym("drop"), sym("_enumerable_drop")); + rb_hash_aset(lazy_use_super_method, sym("drop_while"), sym("_enumerable_drop_while")); + rb_hash_aset(lazy_use_super_method, sym("uniq"), sym("_enumerable_uniq")); + rb_hash_aset(lazy_use_super_method, sym("with_index"), sym("_enumerable_with_index")); rb_obj_freeze(lazy_use_super_method); rb_gc_register_mark_object(lazy_use_super_method); @@ -4120,28 +4121,28 @@ InitVM_Enumerator(void) rb_provide("enumerator.so"); /* for backward compatibility */ } +#undef sym -#undef rb_intern void Init_Enumerator(void) { - id_rewind = rb_intern("rewind"); - id_new = rb_intern("new"); - id_next = rb_intern("next"); - id_result = rb_intern("result"); - id_receiver = rb_intern("receiver"); - id_arguments = rb_intern("arguments"); - id_memo = rb_intern("memo"); - id_method = rb_intern("method"); - id_force = rb_intern("force"); - id_to_enum = rb_intern("to_enum"); - id_begin = rb_intern("begin"); - id_end = rb_intern("end"); - id_step = rb_intern("step"); - id_exclude_end = rb_intern("exclude_end"); + id_rewind = rb_intern_const("rewind"); + id_new = rb_intern_const("new"); + id_next = rb_intern_const("next"); + id_result = rb_intern_const("result"); + id_receiver = rb_intern_const("receiver"); + id_arguments = rb_intern_const("arguments"); + id_memo = rb_intern_const("memo"); + id_method = rb_intern_const("method"); + id_force = rb_intern_const("force"); + id_to_enum = rb_intern_const("to_enum"); + id_begin = rb_intern_const("begin"); + id_end = rb_intern_const("end"); + id_step = rb_intern_const("step"); + id_exclude_end = rb_intern_const("exclude_end"); sym_each = ID2SYM(id_each); - sym_cycle = ID2SYM(rb_intern("cycle")); - sym_yield = ID2SYM(rb_intern("yield")); + sym_cycle = ID2SYM(rb_intern_const("cycle")); + sym_yield = ID2SYM(rb_intern_const("yield")); InitVM(Enumerator); } From b59077eecf912a16efefc0256f6e94a000ce3888 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 21 Oct 2020 13:53:46 +0900 Subject: [PATCH 30/41] Ractor-safe rb_objspace_reachable_objects_from rb_objspace_reachable_objects_from(obj) is used to traverse all reachable objects from obj. This function modify objspace but it is not ractor-safe (thread-safe). This patch fix the problem. Strategy: (1) call GC mark process during_gc (2) call Ractor-local custom mark func when !during_gc --- gc.c | 160 +++++++++++++++++++++++++++++-------------------------- ractor.h | 7 ++- 2 files changed, 89 insertions(+), 78 deletions(-) diff --git a/gc.c b/gc.c index f72d76e857..6c3fc50229 100644 --- a/gc.c +++ b/gc.c @@ -690,11 +690,6 @@ typedef struct rb_objspace { rb_atomic_t finalizing; } atomic_flags; - struct mark_func_data_struct { - void *data; - void (*mark_func)(VALUE v, void *data); - } *mark_func_data; - mark_stack_t mark_stack; size_t marked_slots; @@ -1072,12 +1067,6 @@ static inline void gc_prof_set_heap_info(rb_objspace_t *); PRINTF_ARGS(static void gc_report_body(int level, rb_objspace_t *objspace, const char *fmt, ...), 3, 4); static const char *obj_info(VALUE obj); -#define PUSH_MARK_FUNC_DATA(v) do { \ - struct mark_func_data_struct *prev_mark_func_data = objspace->mark_func_data; \ - objspace->mark_func_data = (v); - -#define POP_MARK_FUNC_DATA() objspace->mark_func_data = prev_mark_func_data;} while (0) - /* * 1 - TSC (H/W Time Stamp Counter) * 2 - getrusage @@ -5138,7 +5127,7 @@ mark_hash(rb_objspace_t *objspace, VALUE hash) } if (RHASH_AR_TABLE_P(hash)) { - if (objspace->mark_func_data == NULL && RHASH_TRANSIENT_P(hash)) { + if (LIKELY(during_gc) && RHASH_TRANSIENT_P(hash)) { rb_transient_heap_mark(hash, RHASH_AR_TABLE(hash)); } } @@ -5453,11 +5442,12 @@ gc_aging(rb_objspace_t *objspace, VALUE obj) } NOINLINE(static void gc_mark_ptr(rb_objspace_t *objspace, VALUE obj)); +static void reachable_objects_from_callback(VALUE obj); static void gc_mark_ptr(rb_objspace_t *objspace, VALUE obj) { - if (LIKELY(objspace->mark_func_data == NULL)) { + if (LIKELY(during_gc)) { rgengc_check_relation(objspace, obj); if (!gc_mark_set(objspace, obj)) return; /* already marked */ if (RB_TYPE_P(obj, T_NONE)) { @@ -5468,7 +5458,7 @@ gc_mark_ptr(rb_objspace_t *objspace, VALUE obj) gc_grey(objspace, obj); } else { - objspace->mark_func_data->mark_func(obj, objspace->mark_func_data->data); + reachable_objects_from_callback(obj); } } @@ -5477,7 +5467,7 @@ gc_pin(rb_objspace_t *objspace, VALUE obj) { GC_ASSERT(is_markable_object(objspace, obj)); if (UNLIKELY(objspace->flags.during_compacting)) { - if (LIKELY(objspace->mark_func_data == NULL)) { + if (LIKELY(during_gc)) { MARK_IN_BITMAP(GET_HEAP_PINNED_BITS(obj), obj); } } @@ -5678,7 +5668,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) gc_mark(objspace, ptr[i]); } - if (objspace->mark_func_data == NULL) { + if (LIKELY(during_gc)) { if (!FL_TEST_RAW(obj, RARRAY_EMBED_FLAG) && RARRAY_TRANSIENT_P(obj)) { rb_transient_heap_mark(obj, ptr); @@ -5719,7 +5709,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) gc_mark(objspace, ptr[i]); } - if (objspace->mark_func_data == NULL && + if (LIKELY(during_gc) && ROBJ_TRANSIENT_P(obj)) { rb_transient_heap_mark(obj, ptr); } @@ -5770,7 +5760,7 @@ gc_mark_children(rb_objspace_t *objspace, VALUE obj) gc_mark(objspace, ptr[i]); } - if (objspace->mark_func_data == NULL && + if (LIKELY(during_gc) && RSTRUCT_TRANSIENT_P(obj)) { rb_transient_heap_mark(obj, ptr); } @@ -6429,7 +6419,7 @@ gc_verify_internal_consistency_m(VALUE dummy) } static void -gc_verify_internal_consistency(rb_objspace_t *objspace) +gc_verify_internal_consistency_(rb_objspace_t *objspace) { struct verify_internal_consistency_struct data = {0}; @@ -6502,6 +6492,17 @@ gc_verify_internal_consistency(rb_objspace_t *objspace) gc_report(5, objspace, "gc_verify_internal_consistency: OK\n"); } +static void +gc_verify_internal_consistency(rb_objspace_t *objspace) +{ + unsigned int prev_during_gc = during_gc; + during_gc = FALSE; // stop gc here + { + gc_verify_internal_consistency_(objspace); + } + during_gc = prev_during_gc; +} + void rb_gc_verify_internal_consistency(void) { @@ -6780,35 +6781,31 @@ gc_marks_continue(rb_objspace_t *objspace, rb_heap_t *heap) unsigned int lock_lev; gc_enter(objspace, "marks_continue", &lock_lev); - PUSH_MARK_FUNC_DATA(NULL); - { - int slots = 0; - const char *from; + int slots = 0; + const char *from; - if (heap->pooled_pages) { - while (heap->pooled_pages && slots < HEAP_PAGE_OBJ_LIMIT) { - struct heap_page *page = heap_move_pooled_pages_to_free_pages(heap); - slots += page->free_slots; - } - from = "pooled-pages"; - } - else if (heap_increment(objspace, heap)) { - slots = heap->free_pages->free_slots; - from = "incremented-pages"; - } - - if (slots > 0) { - gc_report(2, objspace, "gc_marks_continue: provide %d slots from %s.\n", - slots, from); - gc_marks_step(objspace, objspace->rincgc.step_slots); - } - else { - gc_report(2, objspace, "gc_marks_continue: no more pooled pages (stack depth: %"PRIdSIZE").\n", - mark_stack_size(&objspace->mark_stack)); - gc_marks_rest(objspace); - } + if (heap->pooled_pages) { + while (heap->pooled_pages && slots < HEAP_PAGE_OBJ_LIMIT) { + struct heap_page *page = heap_move_pooled_pages_to_free_pages(heap); + slots += page->free_slots; + } + from = "pooled-pages"; + } + else if (heap_increment(objspace, heap)) { + slots = heap->free_pages->free_slots; + from = "incremented-pages"; + } + + if (slots > 0) { + gc_report(2, objspace, "gc_marks_continue: provide %d slots from %s.\n", + slots, from); + gc_marks_step(objspace, objspace->rincgc.step_slots); + } + else { + gc_report(2, objspace, "gc_marks_continue: no more pooled pages (stack depth: %"PRIdSIZE").\n", + mark_stack_size(&objspace->mark_stack)); + gc_marks_rest(objspace); } - POP_MARK_FUNC_DATA(); gc_exit(objspace, "marks_continue", &lock_lev); #endif @@ -6819,23 +6816,19 @@ gc_marks(rb_objspace_t *objspace, int full_mark) { gc_prof_mark_timer_start(objspace); - PUSH_MARK_FUNC_DATA(NULL); - { - /* setup marking */ + /* setup marking */ - gc_marks_start(objspace, full_mark); - if (!is_incremental_marking(objspace)) { - gc_marks_rest(objspace); - } + gc_marks_start(objspace, full_mark); + if (!is_incremental_marking(objspace)) { + gc_marks_rest(objspace); + } #if RGENGC_PROFILE > 0 - if (gc_prof_record(objspace)) { - gc_profile_record *record = gc_prof_record(objspace); - record->old_objects = objspace->rgengc.old_objects; - } -#endif + if (gc_prof_record(objspace)) { + gc_profile_record *record = gc_prof_record(objspace); + record->old_objects = objspace->rgengc.old_objects; } - POP_MARK_FUNC_DATA(); +#endif gc_prof_mark_timer_stop(objspace); } @@ -7677,10 +7670,8 @@ gc_rest(rb_objspace_t *objspace) if (RGENGC_CHECK_MODE >= 2) gc_verify_internal_consistency(objspace); if (is_incremental_marking(objspace)) { - PUSH_MARK_FUNC_DATA(NULL); - gc_marks_rest(objspace); - POP_MARK_FUNC_DATA(); - } + gc_marks_rest(objspace); + } if (is_lazy_sweeping(heap_eden)) { gc_sweep_rest(objspace); } @@ -9805,18 +9796,30 @@ ruby_gc_set_params(void) #endif } +static void +reachable_objects_from_callback(VALUE obj) +{ + rb_ractor_t *cr = GET_RACTOR(); + cr->mfd->mark_func(obj, cr->mfd->data); +} + void rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data) { rb_objspace_t *objspace = &rb_objspace; + if (during_gc) rb_bug("rb_objspace_reachable_objects_from() is not supported while during_gc == true"); + if (is_markable_object(objspace, obj)) { - struct mark_func_data_struct mfd; - mfd.mark_func = func; - mfd.data = data; - PUSH_MARK_FUNC_DATA(&mfd); + rb_ractor_t *cr = GET_RACTOR(); + struct gc_mark_func_data_struct mfd = { + .mark_func = func, + .data = data, + }, *prev_mfd = cr->mfd; + + cr->mfd = &mfd; gc_mark_children(objspace, obj); - POP_MARK_FUNC_DATA(); + cr->mfd = prev_mfd; } } @@ -9843,18 +9846,21 @@ rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, static void objspace_reachable_objects_from_root(rb_objspace_t *objspace, void (func)(const char *category, VALUE, void *), void *passing_data) { - struct root_objects_data data; - struct mark_func_data_struct mfd; + if (during_gc) rb_bug("objspace_reachable_objects_from_root() is not supported while during_gc == true"); - data.func = func; - data.data = passing_data; + rb_ractor_t *cr = GET_RACTOR(); + struct root_objects_data data = { + .func = func, + .data = passing_data, + }; + struct gc_mark_func_data_struct mfd = { + .mark_func = root_objects_from, + .data = &data, + }, *prev_mfd = cr->mfd; - mfd.mark_func = root_objects_from; - mfd.data = &data; - - PUSH_MARK_FUNC_DATA(&mfd); + cr->mfd = &mfd; gc_mark_roots(objspace, &data.category); - POP_MARK_FUNC_DATA(); + cr->mfd = prev_mfd; } /* diff --git a/ractor.h b/ractor.h index 1afd91b77c..50c16ff451 100644 --- a/ractor.h +++ b/ractor.h @@ -121,12 +121,17 @@ struct rb_ractor_struct { struct list_node vmlr_node; - VALUE r_stdin; VALUE r_stdout; VALUE r_stderr; VALUE verbose; VALUE debug; + + // gc.c rb_objspace_reachable_objects_from + struct gc_mark_func_data_struct { + void *data; + void (*mark_func)(VALUE v, void *data); + } *mfd; }; // rb_ractor_t is defined in vm_core.h rb_ractor_t *rb_ractor_main_alloc(void); From 441403173595ddf80d11c99ebe70d4c7ccd49188 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 21 Oct 2020 17:58:12 +0900 Subject: [PATCH 31/41] extend timeout of rbs test on rbs tests --- tool/test-bundled-gems.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tool/test-bundled-gems.rb b/tool/test-bundled-gems.rb index 7f04ff3eb3..6928c7691c 100644 --- a/tool/test-bundled-gems.rb +++ b/tool/test-bundled-gems.rb @@ -14,17 +14,20 @@ File.foreach("#{gem_dir}/bundled_gems") do |line| puts "\nTesting the #{gem} gem" test_command = "#{ruby} -C #{gem_dir}/src/#{gem} -Ilib #{rake} test" + first_timeout = 600 # 10min if gem == "rbs" racc = File.realpath("../../libexec/racc", __FILE__) pid = Process.spawn("#{ruby} -C #{gem_dir}/src/#{gem} -Ilib #{racc} -v -o lib/rbs/parser.rb lib/rbs/parser.y") Process.waitpid(pid) test_command << " stdlib_test validate" + + first_timeout *= 3 end puts test_command pid = Process.spawn(test_command, "#{/mingw|mswin/ =~ RUBY_PLATFORM ? 'new_' : ''}pgroup": true) - {nil => 600, INT: 30, TERM: 10, KILL: nil}.each do |sig, sec| + {nil => first_timeout, INT: 30, TERM: 10, KILL: nil}.each do |sig, sec| if sig puts "Sending #{sig} signal" Process.kill("-#{sig}", pid) From 762be87759385cd495246b13c8c8eff5c3db0a3c Mon Sep 17 00:00:00 2001 From: Yusuke Endoh Date: Wed, 21 Oct 2020 23:36:49 +0900 Subject: [PATCH 32/41] test/json/json_parser_test.rb: suppress warnings http://rubyci.s3.amazonaws.com/ubuntu/ruby-master/log/20201021T123003Z.log.html.gz ``` /home/chkbuild/chkbuild/tmp/build/20201021T123003Z/ruby/test/json/json_parser_test.rb:227: warning: ambiguous first argument; put parentheses or a space even after `-' operator /home/chkbuild/chkbuild/tmp/build/20201021T123003Z/ruby/test/json/json_parser_test.rb:228: warning: ambiguous first argument; put parentheses or a space even after `-' operator ``` --- test/json/json_parser_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/json/json_parser_test.rb b/test/json/json_parser_test.rb index c7f1a5f3b4..dce693e548 100644 --- a/test/json/json_parser_test.rb +++ b/test/json/json_parser_test.rb @@ -224,8 +224,8 @@ class JSONParserTest < Test::Unit::TestCase assert_predicate parse('"foo"', :freeze => true), :frozen? if string_deduplication_available? - assert_same -'foo', parse('"foo"', :freeze => true) - assert_same -'foo', parse('{"foo": 1}', :freeze => true).keys.first + assert_same(-'foo', parse('"foo"', :freeze => true)) + assert_same(-'foo', parse('{"foo": 1}', :freeze => true).keys.first) end end From 631eaa85109e4d6fa31eaeed393858e1e63300a4 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 21 Oct 2020 22:54:39 +0900 Subject: [PATCH 33/41] check main-ractor or not first On non-multi-ractor-mode, the cost of rb_ractor_main_p() is low so check it first. --- variable.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/variable.c b/variable.c index 4ed60b626d..795ee3fb0a 100644 --- a/variable.c +++ b/variable.c @@ -923,7 +923,8 @@ generic_ivtbl(VALUE obj, ID id, bool force_check_ractor) ASSERT_vm_locking(); if ((force_check_ractor || rb_is_instance_id(id)) && // not internal ID - UNLIKELY(rb_ractor_shareable_p(obj) && !rb_ractor_main_p())) { + UNLIKELY(!rb_ractor_main_p()) && + UNLIKELY(rb_ractor_shareable_p(obj))) { rb_raise(rb_eRuntimeError, "can not access instance variables of shareable objects from non-main Ractors"); } return generic_iv_tbl_; @@ -2952,7 +2953,7 @@ rb_const_set(VALUE klass, ID id, VALUE val) QUOTE_ID(id)); } - if (!rb_ractor_shareable_p(val) && !rb_ractor_main_p()) { + if (!rb_ractor_main_p() && !rb_ractor_shareable_p(val)) { rb_raise(rb_eNameError, "can not set constants with non-shareable objects by non-main Ractors"); } From af2471365fedaf89759eb00f87164fbaa0afaa39 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 21 Oct 2020 22:56:35 +0900 Subject: [PATCH 34/41] refactoring rb_ractor_confirm_belonging() rb_ractor_belonging() returns 0 only if it has sharable flag. rb_ractor_confirm_belonging() checks rb_ractor_shareable_p() if the belonging ractor id is different from current ractor id. --- ractor.h | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/ractor.h b/ractor.h index 50c16ff451..e3adeb8d07 100644 --- a/ractor.h +++ b/ractor.h @@ -257,7 +257,7 @@ rb_ractor_setup_belonging(VALUE obj) static inline uint32_t rb_ractor_belonging(VALUE obj) { - if (rb_ractor_shareable_p(obj)) { + if (SPECIAL_CONST_P(obj) || RB_OBJ_SHAREABLE_P(obj)) { return 0; } else { @@ -277,8 +277,13 @@ rb_ractor_confirm_belonging(VALUE obj) } } else if (UNLIKELY(id != rb_ractor_current_id())) { - rp(obj); - rb_bug("rb_ractor_confirm_belonging object-ractor id:%u, current-ractor id:%u", id, rb_ractor_current_id()); + if (rb_ractor_shareable_p(obj)) { + // ok + } + else { + rp(obj); + rb_bug("rb_ractor_confirm_belonging object-ractor id:%u, current-ractor id:%u", id, rb_ractor_current_id()); + } } return obj; } From 89f6644de71b7dfbdbdba216a8667b9c3348203b Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 21 Oct 2020 23:00:36 +0900 Subject: [PATCH 35/41] refactoring rb_obj_traverse() * create rec check hash lazily * do not pass *data pointer for enter/leave function because it is not used. --- ractor.c | 80 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/ractor.c b/ractor.c index 8c498a86b1..93a1fc59fd 100644 --- a/ractor.c +++ b/ractor.c @@ -1870,15 +1870,15 @@ rb_ractor_stderr_set(VALUE err) // 2: stop search // 1: skip child // 0: continue -typedef int (*rb_obj_traverse_enter_func)(VALUE obj, void *data); -typedef int (*rb_obj_traverse_leave_func)(VALUE obj, void *data); +typedef int (*rb_obj_traverse_enter_func)(VALUE obj); +typedef int (*rb_obj_traverse_leave_func)(VALUE obj); struct obj_traverse_data { rb_obj_traverse_enter_func enter_func; rb_obj_traverse_leave_func leave_func; - void *data; st_table *rec; + VALUE rec_hash; }; @@ -1887,19 +1887,19 @@ struct obj_traverse_callback_data { struct obj_traverse_data *data; }; -static int rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data); +static int obj_traverse_i(VALUE obj, struct obj_traverse_data *data); static int obj_hash_traverse_i(VALUE key, VALUE val, VALUE ptr) { struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr; - if (rb_obj_traverse_i(key, d->data)) { + if (obj_traverse_i(key, d->data)) { d->stop = true; return ST_STOP; } - if (rb_obj_traverse_i(val, d->data)) { + if (obj_traverse_i(val, d->data)) { d->stop = true; return ST_STOP; } @@ -1912,24 +1912,34 @@ obj_tdata_traverse_i(VALUE obj, void *ptr) { struct obj_traverse_callback_data *d = (struct obj_traverse_callback_data *)ptr; - if (rb_obj_traverse_i(obj, d->data)) { + if (obj_traverse_i(obj, d->data)) { d->stop = true; } } +static struct st_table * +obj_traverse_rec(struct obj_traverse_data *data) +{ + if (UNLIKELY(!data->rec)) { + data->rec_hash = rb_ident_hash_new(); + data->rec = rb_hash_st_table(data->rec_hash); + } + return data->rec; +} + static int -rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) +obj_traverse_i(VALUE obj, struct obj_traverse_data *data) { if (RB_SPECIAL_CONST_P(obj)) return 0; - switch (data->enter_func(obj, data->data)) { + switch (data->enter_func(obj)) { case 0: break; case 1: return 0; // skip children case 2: return 1; // stop search default: rb_bug("rb_obj_traverse_func should return 0 to 2"); } - if (st_insert(data->rec, obj, 1)) { + if (st_insert(obj_traverse_rec(data), obj, 1)) { // already traversed return 0; } @@ -1939,7 +1949,7 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) rb_ivar_generic_ivtbl_lookup(obj, &ivtbl); for (uint32_t i = 0; i < ivtbl->numiv; i++) { VALUE val = ivtbl->ivptr[i]; - if (val != Qundef && rb_obj_traverse_i(val, data)) return 1; + if (val != Qundef && obj_traverse_i(val, data)) return 1; } } @@ -1961,7 +1971,7 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) for (uint32_t i=0; inum, data)) return 1; - if (rb_obj_traverse_i(RRATIONAL(obj)->den, data)) return 1; + if (obj_traverse_i(RRATIONAL(obj)->num, data)) return 1; + if (obj_traverse_i(RRATIONAL(obj)->den, data)) return 1; break; case T_COMPLEX: - if (rb_obj_traverse_i(RCOMPLEX(obj)->real, data)) return 1; - if (rb_obj_traverse_i(RCOMPLEX(obj)->imag, data)) return 1; + if (obj_traverse_i(RCOMPLEX(obj)->real, data)) return 1; + if (obj_traverse_i(RCOMPLEX(obj)->imag, data)) return 1; break; case T_DATA: @@ -2028,7 +2038,7 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) rb_bug("unreachable"); } - switch (data->leave_func(obj, data->data)) { + switch (data->leave_func(obj)) { case 0: case 1: return 0; // terminate case 2: return 1; // stop search @@ -2041,21 +2051,15 @@ rb_obj_traverse_i(VALUE obj, struct obj_traverse_data *data) static int rb_obj_traverse(VALUE obj, rb_obj_traverse_enter_func enter_func, - rb_obj_traverse_leave_func leave_func, - void *passed_data) + rb_obj_traverse_leave_func leave_func) { - VALUE h = rb_ident_hash_new(); - struct obj_traverse_data data = { .enter_func = enter_func, .leave_func = leave_func, - .data = passed_data, - .rec = rb_hash_st_table(h), + .rec = NULL, }; - int r = rb_obj_traverse_i(obj, &data); - RB_GC_GUARD(h); - return r; + return obj_traverse_i(obj, &data); } static int @@ -2076,7 +2080,7 @@ frozen_shareable_p(VALUE obj) } static int -make_shareable_check_shareable(VALUE obj, void *data) +make_shareable_check_shareable(VALUE obj) { VM_ASSERT(!SPECIAL_CONST_P(obj)); @@ -2091,12 +2095,16 @@ make_shareable_check_shareable(VALUE obj, void *data) if (!OBJ_FROZEN(obj)) { rb_funcall(obj, idFreeze, 0); + + if (UNLIKELY(!OBJ_FROZEN(obj))) { + rb_raise(rb_eRactorError, "#freeze does not freeze object correctly"); + } } return 0; } static int -mark_shareable(VALUE obj, void *data) +mark_shareable(VALUE obj) { FL_SET_RAW(obj, RUBY_FL_SHAREABLE); return 0; @@ -2107,13 +2115,12 @@ rb_ractor_make_shareable(VALUE obj) { rb_obj_traverse(obj, make_shareable_check_shareable, - mark_shareable, - NULL); + mark_shareable); return obj; } static int -shareable_p_enter(VALUE obj, void *ptr) +shareable_p_enter(VALUE obj) { if (RB_OBJ_SHAREABLE_P(obj)) { return 1; @@ -2122,7 +2129,7 @@ shareable_p_enter(VALUE obj, void *ptr) RB_TYPE_P(obj, T_MODULE) || RB_TYPE_P(obj, T_ICLASS)) { // TODO: remove it - mark_shareable(obj, NULL); + mark_shareable(obj); return 1; } else if (RB_OBJ_FROZEN_RAW(obj) && @@ -2138,8 +2145,7 @@ rb_ractor_shareable_p_continue(VALUE obj) { if (rb_obj_traverse(obj, shareable_p_enter, - mark_shareable, - NULL)) { + mark_shareable)) { return false; } else { From 3a97d361576d1cc198047d502c5165aa37b7f86e Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Wed, 21 Oct 2020 23:57:44 +0900 Subject: [PATCH 36/41] refactoring frozen_shareable_p --- ractor.c | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/ractor.c b/ractor.c index 93a1fc59fd..2cf34cb392 100644 --- a/ractor.c +++ b/ractor.c @@ -2065,18 +2065,14 @@ rb_obj_traverse(VALUE obj, static int frozen_shareable_p(VALUE obj) { - switch (BUILTIN_TYPE(obj)) { - case T_DATA: - if (RTYPEDDATA_P(obj)) { - const rb_data_type_t *type = RTYPEDDATA_TYPE(obj); - if (type->flags & RUBY_TYPED_FROZEN_SHAREABLE) { - return true; - } - } - return false; - default: + if (!RB_TYPE_P(obj, T_DATA) || + (RTYPEDDATA_P(obj) && + RTYPEDDATA_TYPE(obj)->flags & RUBY_TYPED_FROZEN_SHAREABLE)) { return true; } + else { + return false; + } } static int From 96293784779c000cdb5c07dd80be0dc208f8eeb9 Mon Sep 17 00:00:00 2001 From: git Date: Thu, 22 Oct 2020 00:07:02 +0900 Subject: [PATCH 37/41] * 2020-10-22 [ci skip] --- version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.h b/version.h index f3a3916756..d4effab113 100644 --- a/version.h +++ b/version.h @@ -16,7 +16,7 @@ #define RUBY_RELEASE_YEAR 2020 #define RUBY_RELEASE_MONTH 10 -#define RUBY_RELEASE_DAY 21 +#define RUBY_RELEASE_DAY 22 #include "ruby/version.h" From 0c0d0752f1fefd9b085f191b62946a811763ef1b Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Thu, 22 Oct 2020 00:36:53 +0900 Subject: [PATCH 38/41] allow to access ivars of frozen shareable objects Accessing a shareable object is prohibitted because it can cause race condition, but if the shareable object is frozen, there is no problem to access ivars. --- bootstraptest/test_ractor.rb | 12 ++++++++++++ variable.c | 3 ++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index 6290b73c36..62b0b523ae 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -734,6 +734,18 @@ assert_equal 'can not access instance variables of shareable objects from non-ma end } +# But a sharable object is frozen, it is allowed to access ivars from non-main Ractor +assert_equal '11', %q{ + [Object.new, [], ].map{|obj| + obj.instance_variable_set('@a', 1) + Ractor.make_shareable obj = obj.freeze + + Ractor.new obj do |obj| + obj.instance_variable_get('@a') + end.take.to_s + }.join +} + # cvar in sharable-objects are not allowed to access from non-main Ractor assert_equal 'can not access class variables from non-main Ractors', %q{ class C diff --git a/variable.c b/variable.c index 795ee3fb0a..8ac40efe80 100644 --- a/variable.c +++ b/variable.c @@ -922,7 +922,8 @@ generic_ivtbl(VALUE obj, ID id, bool force_check_ractor) { ASSERT_vm_locking(); - if ((force_check_ractor || rb_is_instance_id(id)) && // not internal ID + if ((force_check_ractor || LIKELY(rb_is_instance_id(id)) /* not internal ID */ ) && + !RB_OBJ_FROZEN_RAW(obj) && UNLIKELY(!rb_ractor_main_p()) && UNLIKELY(rb_ractor_shareable_p(obj))) { rb_raise(rb_eRuntimeError, "can not access instance variables of shareable objects from non-main Ractors"); From 603fb940c0d334f399d77b56d7e62ee85edb91e0 Mon Sep 17 00:00:00 2001 From: Koichi Sasada Date: Thu, 22 Oct 2020 00:43:32 +0900 Subject: [PATCH 39/41] refactoring obj_traverse_i --- ractor.c | 63 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/ractor.c b/ractor.c index 2cf34cb392..272a4bc3b7 100644 --- a/ractor.c +++ b/ractor.c @@ -1870,8 +1870,15 @@ rb_ractor_stderr_set(VALUE err) // 2: stop search // 1: skip child // 0: continue -typedef int (*rb_obj_traverse_enter_func)(VALUE obj); -typedef int (*rb_obj_traverse_leave_func)(VALUE obj); + +enum obj_traverse_iterator_result { + traverse_cont, + traverse_skip, + traverse_stop, +}; + +typedef enum obj_traverse_iterator_result (*rb_obj_traverse_enter_func)(VALUE obj); +typedef enum obj_traverse_iterator_result (*rb_obj_traverse_leave_func)(VALUE obj); struct obj_traverse_data { rb_obj_traverse_enter_func enter_func; @@ -1933,18 +1940,17 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data) if (RB_SPECIAL_CONST_P(obj)) return 0; switch (data->enter_func(obj)) { - case 0: break; - case 1: return 0; // skip children - case 2: return 1; // stop search - default: rb_bug("rb_obj_traverse_func should return 0 to 2"); + case traverse_cont: break; + case traverse_skip: return 0; // skip children + case traverse_stop: return 1; // stop search } - if (st_insert(obj_traverse_rec(data), obj, 1)) { + if (UNLIKELY(st_insert(obj_traverse_rec(data), obj, 1))) { // already traversed return 0; } - if (FL_TEST(obj, FL_EXIVAR)) { + if (UNLIKELY(FL_TEST_RAW(obj, FL_EXIVAR))) { struct gen_ivtbl *ivtbl; rb_ivar_generic_ivtbl_lookup(obj, &ivtbl); for (uint32_t i = 0; i < ivtbl->numiv; i++) { @@ -2038,11 +2044,11 @@ obj_traverse_i(VALUE obj, struct obj_traverse_data *data) rb_bug("unreachable"); } - switch (data->leave_func(obj)) { - case 0: - case 1: return 0; // terminate - case 2: return 1; // stop search - default: rb_bug("rb_obj_traverse_func should return 0 to 2"); + if (data->leave_func(obj) == traverse_stop) { + return 1; + } + else { + return 0; } } @@ -2075,35 +2081,34 @@ frozen_shareable_p(VALUE obj) } } -static int +static enum obj_traverse_iterator_result make_shareable_check_shareable(VALUE obj) { VM_ASSERT(!SPECIAL_CONST_P(obj)); if (RB_OBJ_SHAREABLE_P(obj)) { - return 1; + return traverse_skip; } - else { - if (!frozen_shareable_p(obj)) { - rb_raise(rb_eRactorError, "can not make shareable object for %"PRIsVALUE, obj); - } + else if (!frozen_shareable_p(obj)) { + rb_raise(rb_eRactorError, "can not make shareable object for %"PRIsVALUE, obj); } - if (!OBJ_FROZEN(obj)) { + if (!RB_OBJ_FROZEN_RAW(obj)) { rb_funcall(obj, idFreeze, 0); - if (UNLIKELY(!OBJ_FROZEN(obj))) { + if (UNLIKELY(!RB_OBJ_FROZEN_RAW(obj))) { rb_raise(rb_eRactorError, "#freeze does not freeze object correctly"); } } - return 0; + + return traverse_cont; } -static int +static enum obj_traverse_iterator_result mark_shareable(VALUE obj) { FL_SET_RAW(obj, RUBY_FL_SHAREABLE); - return 0; + return traverse_cont; } VALUE @@ -2115,25 +2120,25 @@ rb_ractor_make_shareable(VALUE obj) return obj; } -static int +static enum obj_traverse_iterator_result shareable_p_enter(VALUE obj) { if (RB_OBJ_SHAREABLE_P(obj)) { - return 1; + return traverse_skip; } else if (RB_TYPE_P(obj, T_CLASS) || RB_TYPE_P(obj, T_MODULE) || RB_TYPE_P(obj, T_ICLASS)) { // TODO: remove it mark_shareable(obj); - return 1; + return traverse_skip; } else if (RB_OBJ_FROZEN_RAW(obj) && frozen_shareable_p(obj)) { - return 0; + return traverse_cont; } - return 2; // fail + return traverse_stop; // fail } MJIT_FUNC_EXPORTED bool From d23d5c3130a0944e7e591370cbf8599009318a7c Mon Sep 17 00:00:00 2001 From: Kenta Murata Date: Thu, 22 Oct 2020 17:59:52 +0900 Subject: [PATCH 40/41] rational.c: try converting by to_int in Rational() (#3684) [Bug #12485] --- rational.c | 34 +++++++++++++++++++++++++++++++--- test/ruby/test_rational.rb | 19 +++++++++++++++++++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/rational.c b/rational.c index 6ac42bff04..31768702a5 100644 --- a/rational.c +++ b/rational.c @@ -2573,6 +2573,8 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise) VALUE a1 = numv, a2 = denv; int state; + assert(a1 != Qundef); + if (NIL_P(a1) || NIL_P(a2)) { if (!raise) return Qnil; rb_raise(rb_eTypeError, "can't convert nil into Rational"); @@ -2588,21 +2590,47 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise) a2 = RCOMPLEX(a2)->real; } - if (RB_FLOAT_TYPE_P(a1)) { + if (RB_INTEGER_TYPE_P(a1)) { + // nothing to do + } + else if (RB_FLOAT_TYPE_P(a1)) { a1 = float_to_r(a1); } + else if (RB_TYPE_P(a1, T_RATIONAL)) { + // nothing to do + } else if (RB_TYPE_P(a1, T_STRING)) { a1 = string_to_r_strict(a1, raise); if (!raise && NIL_P(a1)) return Qnil; } + else if (!rb_respond_to(a1, idTo_r)) { + VALUE tmp = rb_protect(rb_check_to_int, a1, NULL); + rb_set_errinfo(Qnil); + if (!NIL_P(tmp)) { + a1 = tmp; + } + } - if (RB_FLOAT_TYPE_P(a2)) { + if (RB_INTEGER_TYPE_P(a2)) { + // nothing to do + } + else if (RB_FLOAT_TYPE_P(a2)) { a2 = float_to_r(a2); } + else if (RB_TYPE_P(a2, T_RATIONAL)) { + // nothing to do + } else if (RB_TYPE_P(a2, T_STRING)) { a2 = string_to_r_strict(a2, raise); if (!raise && NIL_P(a2)) return Qnil; } + else if (a2 != Qundef && !rb_respond_to(a2, idTo_r)) { + VALUE tmp = rb_protect(rb_check_to_int, a2, NULL); + rb_set_errinfo(Qnil); + if (!NIL_P(tmp)) { + a2 = tmp; + } + } if (RB_TYPE_P(a1, T_RATIONAL)) { if (a2 == Qundef || (k_exact_one_p(a2))) @@ -2610,7 +2638,7 @@ nurat_convert(VALUE klass, VALUE numv, VALUE denv, int raise) } if (a2 == Qundef) { - if (!k_integer_p(a1)) { + if (!RB_INTEGER_TYPE_P(a1)) { if (!raise) { VALUE result = rb_protect(to_rational, a1, NULL); rb_set_errinfo(Qnil); diff --git a/test/ruby/test_rational.rb b/test/ruby/test_rational.rb index 301890b620..5bdf5b717e 100644 --- a/test/ruby/test_rational.rb +++ b/test/ruby/test_rational.rb @@ -128,6 +128,13 @@ class Rational_Test < Test::Unit::TestCase assert_raise(TypeError){Rational(Object.new, Object.new)} assert_raise(TypeError){Rational(1, Object.new)} + bug12485 = '[ruby-core:75995] [Bug #12485]' + o = Object.new + def o.to_int; 1; end + assert_equal(1, Rational(o, 1), bug12485) + assert_equal(1, Rational(1, o), bug12485) + assert_equal(1, Rational(o, o), bug12485) + o = Object.new def o.to_r; 1/42r; end assert_equal(1/42r, Rational(o)) @@ -834,6 +841,18 @@ class Rational_Test < Test::Unit::TestCase assert_equal(nil, Rational(1, Object.new, exception: false)) } + bug12485 = '[ruby-core:75995] [Bug #12485]' + assert_nothing_raised(RuntimeError, bug12485) { + o = Object.new + def o.to_int; raise; end + assert_equal(nil, Rational(o, exception: false)) + } + assert_nothing_raised(RuntimeError, bug12485) { + o = Object.new + def o.to_int; raise; end + assert_equal(nil, Rational(1, o, exception: false)) + } + o = Object.new; def o.to_r; raise; end assert_nothing_raised(RuntimeError) { From abf678a4397c6c00a1bb686043e377d372e695a4 Mon Sep 17 00:00:00 2001 From: Aaron Patterson Date: Wed, 21 Oct 2020 13:16:15 -0700 Subject: [PATCH 41/41] Use a lock level for a less granular lock. We are seeing an error where code that is generated with MJIT contains references to objects that have been moved. I believe this is due to a race condition in the compaction function. `gc_compact` has two steps: 1. Run a full GC to pin objects 2. Compact / update references Step one is executed with `garbage_collect`. `garbage_collect` calls `gc_enter` / `gc_exit`, these functions acquire a JIT lock and release a JIT lock. So a lock is held for the duration of step 1. Step two is executed by `gc_compact_after_gc`. It also holds a JIT lock. I believe the problem is that the JIT is free to execute between step 1 and step 2. It copies call cache values, but doesn't pin them when it copies them. So the compactor thinks it's OK to move the call cache even though it is not safe. We need to hold a lock for the duration of `garbage_collect` *and* `gc_compact_after_gc`. This patch introduces a lock level which increments and decrements. The compaction function can increment and decrement the lock level and prevent MJIT from executing during both steps. --- gc.c | 2 ++ mjit.c | 13 +++++++++---- mjit_worker.c | 4 ++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/gc.c b/gc.c index 6c3fc50229..c97246a9cc 100644 --- a/gc.c +++ b/gc.c @@ -8834,10 +8834,12 @@ gc_compact(rb_objspace_t *objspace, int use_toward_empty, int use_double_pages, objspace->flags.during_compacting = TRUE; { + mjit_gc_start_hook(); /* pin objects referenced by maybe pointers */ garbage_collect(objspace, GPR_DEFAULT_REASON); /* compact */ gc_compact_after_gc(objspace, use_toward_empty, use_double_pages, use_verifier); + mjit_gc_exit_hook(); } objspace->flags.during_compacting = FALSE; } diff --git a/mjit.c b/mjit.c index b6abcf4f1d..ab74a066d9 100644 --- a/mjit.c +++ b/mjit.c @@ -96,7 +96,7 @@ mjit_gc_start_hook(void) rb_native_cond_wait(&mjit_client_wakeup, &mjit_engine_mutex); verbose(4, "Getting wakeup from a worker for GC"); } - in_gc = true; + in_gc++; CRITICAL_SECTION_FINISH(4, "mjit_gc_start_hook"); } @@ -108,9 +108,14 @@ mjit_gc_exit_hook(void) if (!mjit_enabled) return; CRITICAL_SECTION_START(4, "mjit_gc_exit_hook"); - in_gc = false; - verbose(4, "Sending wakeup signal to workers after GC"); - rb_native_cond_broadcast(&mjit_gc_wakeup); + in_gc--; + if (in_gc < 0) { // Don't allow underflow + in_gc = 0; + } + if (!in_gc) { + verbose(4, "Sending wakeup signal to workers after GC"); + rb_native_cond_broadcast(&mjit_gc_wakeup); + } CRITICAL_SECTION_FINISH(4, "mjit_gc_exit_hook"); } diff --git a/mjit_worker.c b/mjit_worker.c index 461b10f0ef..63f976a2b9 100644 --- a/mjit_worker.c +++ b/mjit_worker.c @@ -220,8 +220,8 @@ static rb_nativethread_cond_t mjit_client_wakeup; static rb_nativethread_cond_t mjit_worker_wakeup; // A thread conditional to wake up workers if at the end of GC. static rb_nativethread_cond_t mjit_gc_wakeup; -// True when GC is working. -static bool in_gc = false; +// Greater than 0 when GC is working. +static int in_gc = 0; // True when JIT is working. static bool in_jit = false; // True when JIT compaction is running.