[前][次][番号順一覧][スレッド一覧]

ruby-changes:63001

From: Koichi <ko1@a...>
Date: Fri, 18 Sep 2020 14:18:13 +0900 (JST)
Subject: [ruby-changes:63001] 3b159374a2 (master): sync ruby_global_symbols

https://git.ruby-lang.org/ruby.git/commit/?id=3b159374a2

From 3b159374a2daa101b419ebf6f4a7fe01bbe9dc55 Mon Sep 17 00:00:00 2001
From: Koichi Sasada <ko1@a...>
Date: Wed, 16 Sep 2020 09:15:10 +0900
Subject: sync ruby_global_symbols

ruby_global_symbols can be accessed with multiple ractors so that
the accesses should be synchronized.

diff --git a/common.mk b/common.mk
index c3fb948..f5ea771 100644
--- a/common.mk
+++ b/common.mk
@@ -13761,6 +13761,7 @@ symbol.$(OBJEXT): {$(VPATH)}internal/variable.h https://github.com/ruby/ruby/blob/trunk/common.mk#L13761
 symbol.$(OBJEXT): {$(VPATH)}internal/warning_push.h
 symbol.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
 symbol.$(OBJEXT): {$(VPATH)}missing.h
+symbol.$(OBJEXT): {$(VPATH)}node.h
 symbol.$(OBJEXT): {$(VPATH)}onigmo.h
 symbol.$(OBJEXT): {$(VPATH)}oniguruma.h
 symbol.$(OBJEXT): {$(VPATH)}probes.dmyh
@@ -13770,6 +13771,8 @@ symbol.$(OBJEXT): {$(VPATH)}st.h https://github.com/ruby/ruby/blob/trunk/common.mk#L13771
 symbol.$(OBJEXT): {$(VPATH)}subst.h
 symbol.$(OBJEXT): {$(VPATH)}symbol.c
 symbol.$(OBJEXT): {$(VPATH)}symbol.h
+symbol.$(OBJEXT): {$(VPATH)}vm_debug.h
+symbol.$(OBJEXT): {$(VPATH)}vm_sync.h
 thread.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
 thread.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
 thread.$(OBJEXT): $(CCAN_DIR)/list/list.h
diff --git a/symbol.c b/symbol.c
index 07cf28c..1a46985 100644
--- a/symbol.c
+++ b/symbol.c
@@ -21,6 +21,7 @@ https://github.com/ruby/ruby/blob/trunk/symbol.c#L21
 #include "ruby/encoding.h"
 #include "ruby/st.h"
 #include "symbol.h"
+#include "vm_sync.h"
 
 #ifndef USE_SYMBOL_GC
 # define USE_SYMBOL_GC 1
@@ -73,7 +74,6 @@ enum id_entry_type { https://github.com/ruby/ruby/blob/trunk/symbol.c#L74
 };
 
 rb_symbols_t ruby_global_symbols = {tNEXT_ID-1};
-#define global_symbols ruby_global_symbols
 
 static const struct st_hash_type symhash = {
     rb_str_hash_cmp,
@@ -83,26 +83,32 @@ static const struct st_hash_type symhash = { https://github.com/ruby/ruby/blob/trunk/symbol.c#L83
 void
 Init_sym(void)
 {
+    rb_symbols_t *symbols = &ruby_global_symbols;
+
     VALUE dsym_fstrs = rb_ident_hash_new();
-    global_symbols.dsymbol_fstr_hash = dsym_fstrs;
+    symbols->dsymbol_fstr_hash = dsym_fstrs;
     rb_gc_register_mark_object(dsym_fstrs);
     rb_obj_hide(dsym_fstrs);
 
-    global_symbols.str_sym = st_init_table_with_size(&symhash, 1000);
-    global_symbols.ids = rb_ary_tmp_new(0);
-    rb_gc_register_mark_object(global_symbols.ids);
+    symbols->str_sym = st_init_table_with_size(&symhash, 1000);
+    symbols->ids = rb_ary_tmp_new(0);
+    rb_gc_register_mark_object(symbols->ids);
 
     Init_op_tbl();
     Init_id();
 }
 
-WARN_UNUSED_RESULT(static VALUE dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding *const enc, const ID type));
-WARN_UNUSED_RESULT(static VALUE dsymbol_check(const VALUE sym));
+WARN_UNUSED_RESULT(static VALUE dsymbol_alloc(rb_symbols_t *symbols, const VALUE klass, const VALUE str, rb_encoding *const enc, const ID type));
+WARN_UNUSED_RESULT(static VALUE dsymbol_check(rb_symbols_t *symbols, const VALUE sym));
 WARN_UNUSED_RESULT(static ID lookup_str_id(VALUE str));
+WARN_UNUSED_RESULT(static VALUE lookup_str_sym_with_lock(rb_symbols_t *symbols, const VALUE str));
 WARN_UNUSED_RESULT(static VALUE lookup_str_sym(const VALUE str));
 WARN_UNUSED_RESULT(static VALUE lookup_id_str(ID id));
 WARN_UNUSED_RESULT(static ID intern_str(VALUE str, int mutable));
 
+#define GLOBAL_SYMBOLS_ENTER(symbols) rb_symbols_t *symbols = &ruby_global_symbols; RB_VM_LOCK_ENTER()
+#define GLOBAL_SYMBOLS_LEAVE()        RB_VM_LOCK_LEAVE()
+
 ID
 rb_id_attrset(ID id)
 {
@@ -414,10 +420,12 @@ rb_str_symname_type(VALUE name, unsigned int allowed_attrset) https://github.com/ruby/ruby/blob/trunk/symbol.c#L420
 }
 
 static void
-set_id_entry(rb_id_serial_t num, VALUE str, VALUE sym)
+set_id_entry(rb_symbols_t *symbols, rb_id_serial_t num, VALUE str, VALUE sym)
 {
+    ASSERT_vm_locking();
     size_t idx = num / ID_ENTRY_UNIT;
-    VALUE ary, ids = global_symbols.ids;
+
+    VALUE ary, ids = symbols->ids;
     if (idx >= (size_t)RARRAY_LEN(ids) || NIL_P(ary = rb_ary_entry(ids, (long)idx))) {
 	ary = rb_ary_tmp_new(ID_ENTRY_UNIT * ID_ENTRY_SIZE);
 	rb_ary_store(ids, (long)idx, ary);
@@ -430,31 +438,42 @@ set_id_entry(rb_id_serial_t num, VALUE str, VALUE sym) https://github.com/ruby/ruby/blob/trunk/symbol.c#L438
 static VALUE
 get_id_serial_entry(rb_id_serial_t num, ID id, const enum id_entry_type t)
 {
-    if (num && num <= global_symbols.last_id) {
-	size_t idx = num / ID_ENTRY_UNIT;
-	VALUE ids = global_symbols.ids;
-	VALUE ary;
-	if (idx < (size_t)RARRAY_LEN(ids) && !NIL_P(ary = rb_ary_entry(ids, (long)idx))) {
-            long pos = (long)(num % ID_ENTRY_UNIT) * ID_ENTRY_SIZE;
-            VALUE result = rb_ary_entry(ary, pos + t);
-            if (NIL_P(result)) return 0;
-#if CHECK_ID_SERIAL
-            if (id) {
-                VALUE sym = result;
-                if (t != ID_ENTRY_SYM)
-                    sym = rb_ary_entry(ary, pos + ID_ENTRY_SYM);
-                if (STATIC_SYM_P(sym)) {
-                    if (STATIC_SYM2ID(sym) != id) return 0;
+    VALUE result = 0;
+
+    GLOBAL_SYMBOLS_ENTER(symbols);
+    {
+        if (num && num <= symbols->last_id) {
+            size_t idx = num / ID_ENTRY_UNIT;
+            VALUE ids = symbols->ids;
+            VALUE ary;
+            if (idx < (size_t)RARRAY_LEN(ids) && !NIL_P(ary = rb_ary_entry(ids, (long)idx))) {
+                long pos = (long)(num % ID_ENTRY_UNIT) * ID_ENTRY_SIZE;
+                result = rb_ary_entry(ary, pos + t);
+
+                if (NIL_P(result)) {
+                    result = 0;
                 }
                 else {
-                    if (RSYMBOL(sym)->id != id) return 0;
+#if CHECK_ID_SERIAL
+                    if (id) {
+                        VALUE sym = result;
+                        if (t != ID_ENTRY_SYM)
+                          sym = rb_ary_entry(ary, pos + ID_ENTRY_SYM);
+                        if (STATIC_SYM_P(sym)) {
+                            if (STATIC_SYM2ID(sym) != id) result = 0;
+                        }
+                        else {
+                            if (RSYMBOL(sym)->id != id) result = 0;
+                        }
+                    }
+#endif
                 }
             }
-#endif
-            return result;
-	}
+        }
     }
-    return 0;
+    GLOBAL_SYMBOLS_LEAVE();
+
+    return result;
 }
 
 static VALUE
@@ -492,22 +511,26 @@ register_sym_update_callback(st_data_t *key, st_data_t *value, st_data_t arg, in https://github.com/ruby/ruby/blob/trunk/symbol.c#L511
 #endif
 
 static void
-register_sym(VALUE str, VALUE sym)
+register_sym(rb_symbols_t *symbols, VALUE str, VALUE sym)
 {
+    ASSERT_vm_locking();
+
 #if SYMBOL_DEBUG
-    st_update(global_symbols.str_sym, (st_data_t)str,
-	      register_sym_update_callback, (st_data_t)sym);
+    st_update(symbols->str_sym, (st_data_t)str,
+              register_sym_update_callback, (st_data_t)sym);
 #else
-    st_add_direct(global_symbols.str_sym, (st_data_t)str, (st_data_t)sym);
+    st_add_direct(symbols->str_sym, (st_data_t)str, (st_data_t)sym);
 #endif
 }
 
 static void
-unregister_sym(VALUE str, VALUE sym)
+unregister_sym(rb_symbols_t *symbols, VALUE str, VALUE sym)
 {
+    ASSERT_vm_locking();
+
     st_data_t str_data = (st_data_t)str;
-    if (!st_delete(global_symbols.str_sym, &str_data, NULL)) {
-	rb_bug("%p can't remove str from str_id (%s)", (void *)sym, RSTRING_PTR(str));
+    if (!st_delete(symbols->str_sym, &str_data, NULL)) {
+        rb_bug("%p can't remove str from str_id (%s)", (void *)sym, RSTRING_PTR(str));
     }
 }
 
@@ -529,8 +552,12 @@ register_static_symid_str(ID id, VALUE str) https://github.com/ruby/ruby/blob/trunk/symbol.c#L552
 
     RUBY_DTRACE_CREATE_HOOK(SYMBOL, RSTRING_PTR(str));
 
-    register_sym(str, sym);
-    set_id_entry(num, str, sym);
+    GLOBAL_SYMBOLS_ENTER(symbols)
+    {
+        register_sym(symbols, str, sym);
+        set_id_entry(symbols, num, str, sym);
+    }
+    GLOBAL_SYMBOLS_LEAVE();
 
     return id;
 }
@@ -578,8 +605,10 @@ must_be_dynamic_symbol(VALUE x) https://github.com/ruby/ruby/blob/trunk/symbol.c#L605
 #endif
 
 static VALUE
-dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding * const enc, const ID type)
+dsymbol_alloc(rb_symbols_t *symbols, const VALUE klass, const VALUE str, rb_encoding * const enc, const ID type)
 {
+    ASSERT_vm_locking();
+
     const VALUE dsym = rb_newobj_of(klass, T_SYMBOL | FL_WB_PROTECTED);
     long hashval;
 
@@ -591,25 +620,24 @@ dsymbol_alloc(const VALUE klass, const VALUE str, rb_encoding * const enc, const https://github.com/ruby/ruby/blob/trunk/symbol.c#L620
     /* we want hashval to be in Fixnum range [ruby-core:15713] r15672 */
     hashval = (long)rb_str_hash(str);
     RSYMBOL(dsym)->hashval = RSHIFT((long)hashval, 1);
-
-    register_sym(str, dsym);
-    rb_hash_aset(global_symbols.dsymbol_fstr_hash, str, Qtrue);
-
+    register_sym(symbols, str, dsym);
+    rb_hash_aset(symbols->dsymbol_fstr_hash, str, Qtrue);
     RUBY_DTRACE_CREATE_HOOK(SYMBOL, RSTRING_PTR(RSYMBOL(dsym)->fstr));
 
     return dsym;
 }
 
 static inline VALUE
-dsymbol_check(const VALUE sym)
+dsymbol_check(rb_symbols_t *symbols, const VALUE sym)
 {
+    ASSERT_vm_locking();
+
     if (UNLIKELY(rb_objspace_garbage_object_p(sym))) {
 	const VALUE fstr = RSYMBOL(sym)->fstr;
 	const ID type = RSYMBOL(sym)->id & ID_SCOPE_MASK;
 	RSYMBOL(sym)->fstr = 0;
-
-	unregister_sym(fstr, sym);
-	return dsymbol_alloc(rb_cSymbol, fstr, rb_enc_get(fstr), type);
+        unregister_sym(symbols, fstr, sym);
+        return dsymbol_alloc(symbols, rb_cSymbol, fstr, rb_enc_get(fstr), type);
     }
     else {
 	return sym;
@@ -620,7 +648,15 @@ static ID https://github.com/ruby/ruby/blob/trunk/symbol.c#L648
 lookup_str_id(VALUE str)
 {
     st_data_t sym_data;
-    if (st_lookup(global_symbols.str_sym, (st_data_t)str, &sym_data)) {
+    int found;
+
+    GLOBAL_SYMBOLS_ENTER(symbols);
+    {
+        found = st (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]