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

ruby-changes:53945

From: ko1 <ko1@a...>
Date: Mon, 3 Dec 2018 21:36:45 +0900 (JST)
Subject: [ruby-changes:53945] ko1:r66165 (trunk): make `RARRAY_PTR_USE` more conservertive.

ko1	2018-12-03 21:36:39 +0900 (Mon, 03 Dec 2018)

  New Revision: 66165

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=66165

  Log:
    make `RARRAY_PTR_USE` more conservertive.
    
    * include/ruby/ruby.h: de-transient at
      `RARRAY_PTR_USE` and `RARRAY_PTR_USE_START`.
      Introduce `RARRAY_PTR_USE_TRANSIENT` and
      `RARRAY_PTR_USE_START_TRANSIENT` if you don't want to
      de-transient an array. Generally, it is difficult
      so C-extension writers should not use them.
    
    * array.c: use `RARRAY_PTR_USE_TRANSIENT` if possible.
    
    * hash.c: ditto.
    
    * enum.c (enum_sort_by): remove `rb_ary_transient_heap_evacuate()`
      because `RARRAY_PTR_USE` do de-transient.

  Modified files:
    trunk/array.c
    trunk/enum.c
    trunk/hash.c
    trunk/include/ruby/ruby.h
    trunk/internal.h
Index: internal.h
===================================================================
--- internal.h	(revision 66164)
+++ internal.h	(revision 66165)
@@ -1262,14 +1262,13 @@ VALUE rb_gvar_defined(struct rb_global_e https://github.com/ruby/ruby/blob/trunk/internal.h#L1262
 #ifdef ARRAY_DEBUG
 #define RARRAY_PTR_IN_USE_FLAG FL_USER14
 #define ARY_PTR_USING_P(ary) FL_TEST_RAW((ary), RARRAY_PTR_IN_USE_FLAG)
-
 #else
 
 /* disable debug function */
-#undef  RARRAY_PTR_USE_START
-#undef  RARRAY_PTR_USE_END
-#define RARRAY_PTR_USE_START(a) ((VALUE *)RARRAY_CONST_PTR_TRANSIENT(a))
-#define RARRAY_PTR_USE_END(a)
+#undef  RARRAY_PTR_USE_START_TRANSIENT
+#undef  RARRAY_PTR_USE_END_TRANSIENT
+#define RARRAY_PTR_USE_START_TRANSIENT(a) ((VALUE *)RARRAY_CONST_PTR_TRANSIENT(a))
+#define RARRAY_PTR_USE_END_TRANSIENT(a)
 #define ARY_PTR_USING_P(ary) 0
 
 #endif
Index: enum.c
===================================================================
--- enum.c	(revision 66164)
+++ enum.c	(revision 66165)
@@ -1172,7 +1172,6 @@ enum_sort_by(VALUE obj) https://github.com/ruby/ruby/blob/trunk/enum.c#L1172
 	rb_ary_concat(ary, buf);
     }
     if (RARRAY_LEN(ary) > 2) {
-        rb_ary_transient_heap_evacuate(ary, TRUE); /* should be malloc heap */
         RARRAY_PTR_USE(ary, ptr,
                        ruby_qsort(ptr, RARRAY_LEN(ary)/2, 2*sizeof(VALUE),
                                   sort_by_cmp, (void *)ary));
Index: hash.c
===================================================================
--- hash.c	(revision 66164)
+++ hash.c	(revision 66165)
@@ -3113,27 +3113,22 @@ keys_i(VALUE key, VALUE value, VALUE ary https://github.com/ruby/ruby/blob/trunk/hash.c#L3113
 MJIT_FUNC_EXPORTED VALUE
 rb_hash_keys(VALUE hash)
 {
-    VALUE keys;
     st_index_t size = RHASH_SIZE(hash);
+    VALUE keys =  rb_ary_new_capa(size);
 
-    keys = rb_ary_new_capa(size);
     if (size == 0) return keys;
 
     if (ST_DATA_COMPATIBLE_P(VALUE)) {
-        if (RHASH_ARRAY_P(hash)) {
-            rb_gc_writebarrier_remember(keys);
-            RARRAY_PTR_USE(keys, ptr, {
+        RARRAY_PTR_USE_TRANSIENT(keys, ptr, {
+            if (RHASH_ARRAY_P(hash)) {
                 size = linear_keys(hash, ptr, size);
-            });
-        }
-        else if (RHASH_TABLE_P(hash)) {
-            st_table *table = RHASH_ST_TABLE(hash);
-
-            rb_gc_writebarrier_remember(keys);
-            RARRAY_PTR_USE(keys, ptr, {
-                 size = st_keys(table, ptr, size);
-            });
-        }
+            }
+            else {
+                st_table *table = RHASH_ST_TABLE(hash);
+                size = st_keys(table, ptr, size);
+            }
+        });
+        rb_gc_writebarrier_remember(keys);
 	rb_ary_set_len(keys, size);
     }
     else {
@@ -3174,15 +3169,14 @@ rb_hash_values(VALUE hash) https://github.com/ruby/ruby/blob/trunk/hash.c#L3169
     if (ST_DATA_COMPATIBLE_P(VALUE)) {
         if (RHASH_ARRAY_P(hash)) {
             rb_gc_writebarrier_remember(values);
-            RARRAY_PTR_USE(values, ptr, {
+            RARRAY_PTR_USE_TRANSIENT(values, ptr, {
                 size = linear_values(hash, ptr, size);
             });
         }
         else if (RHASH_TABLE_P(hash)) {
             st_table *table = RHASH_ST_TABLE(hash);
-
             rb_gc_writebarrier_remember(values);
-            RARRAY_PTR_USE(values, ptr, {
+            RARRAY_PTR_USE_TRANSIENT(values, ptr, {
                 size = st_values(table, ptr, size);
             });
         }
Index: array.c
===================================================================
--- array.c	(revision 66164)
+++ array.c	(revision 66165)
@@ -223,7 +223,7 @@ rb_mem_clear(register VALUE *mem, regist https://github.com/ruby/ruby/blob/trunk/array.c#L223
 static void
 ary_mem_clear(VALUE ary, long beg, long size)
 {
-    RARRAY_PTR_USE(ary, ptr, {
+    RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
 	rb_mem_clear(ptr + beg, size);
     });
 }
@@ -239,7 +239,7 @@ memfill(register VALUE *mem, register lo https://github.com/ruby/ruby/blob/trunk/array.c#L239
 static void
 ary_memfill(VALUE ary, long beg, long size, VALUE val)
 {
-    RARRAY_PTR_USE(ary, ptr, {
+    RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
 	memfill(ptr + beg, size, val);
 	RB_OBJ_WRITTEN(ary, Qundef, val);
     });
@@ -252,13 +252,13 @@ ary_memcpy0(VALUE ary, long beg, long ar https://github.com/ruby/ruby/blob/trunk/array.c#L252
 
     if (argc > (int)(128/sizeof(VALUE)) /* is magic number (cache line size) */) {
         rb_gc_writebarrier_remember(buff_owner_ary);
-        RARRAY_PTR_USE(ary, ptr, {
+        RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
             MEMCPY(ptr+beg, argv, VALUE, argc);
         });
     }
     else {
         int i;
-        RARRAY_PTR_USE(ary, ptr, {
+        RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
             for (i=0; i<argc; i++) {
                 RB_OBJ_WRITE(buff_owner_ary, &ptr[i+beg], argv[i]);
             }
@@ -539,7 +539,7 @@ rb_ary_modify(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L539
 	    FL_UNSET_SHARED(ary);
             ARY_SET_PTR(ary, RARRAY_CONST_PTR_TRANSIENT(shared));
 	    ARY_SET_CAPA(ary, shared_len);
-	    RARRAY_PTR_USE(ary, ptr, {
+	    RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
 		MEMMOVE(ptr, ptr+shift, VALUE, len);
 	    });
 	    FL_SET_EMBED(shared);
@@ -1149,7 +1149,7 @@ rb_ary_push(VALUE ary, VALUE item) https://github.com/ruby/ruby/blob/trunk/array.c#L1149
 {
     long idx = RARRAY_LEN((ary_verify(ary), ary));
     VALUE target_ary = ary_ensure_room_for_push(ary, 1);
-    RARRAY_PTR_USE(ary, ptr, {
+    RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
 	RB_OBJ_WRITE(target_ary, &ptr[idx], item);
     });
     ARY_SET_LEN(ary, idx + 1);
@@ -1254,7 +1254,7 @@ rb_ary_shift(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L1254
     top = RARRAY_AREF(ary, 0);
     if (!ARY_SHARED_P(ary)) {
 	if (len < ARY_DEFAULT_SIZE) {
-	    RARRAY_PTR_USE(ary, ptr, {
+	    RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
 		MEMMOVE(ptr, ptr+1, VALUE, len-1);
 	    }); /* WB: no new reference */
             ARY_INCREASE_LEN(ary, -1);
@@ -1267,7 +1267,7 @@ rb_ary_shift(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L1267
 	ary_make_shared(ary);
     }
     else if (ARY_SHARED_OCCUPIED(ARY_SHARED(ary))) {
-	RARRAY_PTR_USE(ary, ptr, ptr[0] = Qnil);
+	RARRAY_PTR_USE_TRANSIENT(ary, ptr, ptr[0] = Qnil);
     }
     ARY_INCREASE_PTR(ary, 1);		/* shift ptr */
     ARY_INCREASE_LEN(ary, -1);
@@ -1333,8 +1333,8 @@ rb_ary_behead(VALUE ary, long n) https://github.com/ruby/ruby/blob/trunk/array.c#L1333
     }
     else {
 	if (RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
-	    RARRAY_PTR_USE(ary, ptr, {
-		MEMMOVE(ptr, ptr+n, VALUE, RARRAY_LEN(ary)-n);
+	    RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
+                MEMMOVE(ptr, ptr+n, VALUE, RARRAY_LEN(ary)-n);
 	    }); /* WB: no new reference */
 	}
 	else {
@@ -1403,7 +1403,7 @@ ary_ensure_room_for_unshift(VALUE ary, i https://github.com/ruby/ruby/blob/trunk/array.c#L1403
     }
     else {
 	/* sliding items */
-	RARRAY_PTR_USE(ary, ptr, {
+	RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
 	    MEMMOVE(ptr + argc, ptr, VALUE, len);
 	});
 
@@ -1856,9 +1856,9 @@ rb_ary_splice(VALUE ary, long beg, long https://github.com/ruby/ruby/blob/trunk/array.c#L1856
 	}
 
 	if (len != rlen) {
-	    RARRAY_PTR_USE(ary, ptr,
-			   MEMMOVE(ptr + beg + rlen, ptr + beg + len,
-				   VALUE, olen - (beg + len)));
+	    RARRAY_PTR_USE_TRANSIENT(ary, ptr,
+                                     MEMMOVE(ptr + beg + rlen, ptr + beg + len,
+                                             VALUE, olen - (beg + len)));
 	    ARY_SET_LEN(ary, alen);
 	}
 	if (rlen > 0) {
@@ -2490,9 +2490,9 @@ rb_ary_reverse(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L2490
 
     rb_ary_modify(ary);
     if (len > 1) {
-	RARRAY_PTR_USE(ary, p1, {
-	    p2 = p1 + len - 1;	/* points last item */
-	    ary_reverse(p1, p2);
+        RARRAY_PTR_USE_TRANSIENT(ary, p1, {
+            p2 = p1 + len - 1;	/* points last item */
+            ary_reverse(p1, p2);
 	}); /* WB: no new reference */
     }
     return ary;
@@ -2563,7 +2563,7 @@ rb_ary_rotate(VALUE ary, long cnt) https://github.com/ruby/ruby/blob/trunk/array.c#L2563
     if (cnt != 0) {
         long len = RARRAY_LEN(ary);
         if (len > 0 && (cnt = rotate_count(cnt, len)) > 0) {
-            RARRAY_PTR_USE(ary, ptr, ary_rotate_ptr(ptr, len, cnt));
+            RARRAY_PTR_USE_TRANSIENT(ary, ptr, ary_rotate_ptr(ptr, len, cnt));
             return ary;
         }
     }
@@ -2740,8 +2740,8 @@ rb_ary_sort_bang(VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L2740
 	data.cmp_opt.opt_methods = 0;
 	data.cmp_opt.opt_inited = 0;
 	RARRAY_PTR_USE(tmp, ptr, {
-	    ruby_qsort(ptr, len, sizeof(VALUE),
-		       rb_block_given_p()?sort_1:sort_2, &data);
+            ruby_qsort(ptr, len, sizeof(VALUE),
+                       rb_block_given_p()?sort_1:sort_2, &data);
 	}); /* WB: no new reference */
 	rb_ary_modify(ary);
         if (ARY_EMBED_P(tmp)) {
@@ -3208,7 +3208,7 @@ select_bang_ensure(VALUE a) https://github.com/ruby/ruby/blob/trunk/array.c#L3208
 	long tail = 0;
 	if (i1 < len) {
 	    tail = len - i1;
-	    RARRAY_PTR_USE(ary, ptr, {
+	    RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
 		    MEMMOVE(ptr + i2, ptr + i1, VALUE, tail);
 		});
 	}
@@ -3377,8 +3377,8 @@ rb_ary_delete_at(VALUE ary, long pos) https://github.com/ruby/ruby/blob/trunk/array.c#L3377
 
     rb_ary_modify(ary);
     del = RARRAY_AREF(ary, pos);
-    RARRAY_PTR_USE(ary, ptr, {
-	MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
+    RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
+        MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1);
     });
     ARY_INCREASE_LEN(ary, -1);
     ary_verify(ary);
@@ -5367,7 +5367,7 @@ rb_ary_sample(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/array.c#L5367
 	    sorted[j] = idx[i] = k;
 	}
 	result = rb_ary_new_capa(n);
-	RARRAY_PTR_USE(result, ptr_result, {
+        RARRAY_PTR_USE_TRANSIENT(result, ptr_result, {
 	    for (i=0; i<n; i++) {
 		ptr_result[i] = RARRAY_AREF(ary, idx[i]);
 	    }
@@ -5390,7 +5390,7 @@ rb_ary_sample(int argc, VALUE *argv, VAL https://github.com/ruby/ruby/blob/trunk/array.c#L5390
 	    len = RARRAY_LEN(ary);
 	    if (len <= max_idx) n = 0;
 	    else if (n > len) n = len;
-	    RARRAY_PTR_USE(ary, ptr_ary, {
+            RARRAY_PTR_USE_TRANSIENT(ary, ptr_ary, {
 		for (i=0; i<n; i++) {
 		    long j2 = j = ptr_result[i];
 		    long i2 = i;
Index: include/ruby/ruby.h
===================================================================
--- include/ruby/ruby.h	(revision 66164)
+++ include/ruby/ruby.h	(revision 66165)
@@ -1066,11 +1066,18 @@ struct RArray { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1066
 #define RARRAY_TRANSIENT_P(ary) 0
 #endif
 
-VALUE *rb_ary_ptr_use_start(VALUE ary);
-void rb_ary_ptr_use_end(VALUE ary);
+#define RARRAY_PTR_USE_START_TRANSIENT(a) rb_array_ptr_use_start(a, 1)
+#define RARRAY_PTR_USE_END_TRANSIENT(a) rb_array_ptr_use_end(a, 1)
 
-#define RARRAY_PTR_USE_START(a) rb_ary_ptr_use_start(a)
-#define RARRAY_PTR_USE_END(a) rb_ary_ptr_use_end(a)
+#define RARRAY_PTR_USE_TRANSIENT(ary, ptr_name, expr) do { \
+    const VALUE _ary = (ary); \
+    VALUE *ptr_name = (VALUE *)RARRAY_PTR_USE_START_TRANSIENT(_ary); \
+    expr; \
+    RARRAY_PTR_USE_END_TRANSIENT(_ary); \
+} while (0)
+
+#define RARRAY_PTR_USE_START(a) rb_array_ptr_use_start(a, 0)
+#define RARRAY_PTR_USE_END(a) rb_array_ptr_use_end(a, 0)
 
 #define RARRAY_PTR_USE(ary, ptr_name, expr) do { \
     const VALUE _ary = (ary); \
@@ -1083,9 +1090,9 @@ void rb_ary_ptr_use_end(VALUE ary); https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L1090
 #define RARRAY_ASET(a, i, v) do { \
     const VALUE _ary = (a); \
     const VALUE _v = (v); \
-    VALUE *ptr = (VALUE *)RARRAY_PTR_USE_START(_ary); \
+    VALUE *ptr = (VALUE *)RARRAY_PTR_USE_START_TRANSIENT(_ary); \
     RB_OBJ_WRITE(_ary, &ptr[i], _v); \
-    RARRAY_PTR_USE_END(_ary); \
+    RARRAY_PTR_USE_END_TRANSIENT(_ary); \
 } while (0)
 
 #define RARRAY_PTR(a) ((VALUE *)RARRAY_CONST_PTR(RB_OBJ_WB_UNPROTECT_FOR(ARRAY, a)))
@@ -2134,6 +2141,7 @@ rb_array_len(VALUE a) https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L2141
 # define FIX_CONST_VALUE_PTR(x) (x)
 #endif
 
+/* internal function. do not use this function */
 static inline const VALUE *
 rb_array_const_ptr_transient(VALUE a)
 {
@@ -2141,6 +2149,7 @@ rb_array_const_ptr_transient(VALUE a) https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L2149
 	RARRAY(a)->as.ary : RARRAY(a)->as.heap.ptr);
 }
 
+/* internal function. do not use this function */
 static inline const VALUE *
 rb_array_const_ptr(VALUE a)
 {
@@ -2154,6 +2163,32 @@ rb_array_const_ptr(VALUE a) https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L2163
     return rb_array_const_ptr_transient(a);
 }
 
+/* internal function. do not use this function */
+static inline VALUE *
+rb_array_ptr_use_start(VALUE a, int allow_transient)
+{
+    VALUE *rb_ary_ptr_use_start(VALUE ary);
+
+#if USE_TRANSIENT_HEAP
+    if (!allow_transient) {
+        if (RARRAY_TRANSIENT_P(a)) {
+            void rb_ary_detransient(VALUE a);
+            rb_ary_detransient(a);
+        }
+    }
+#endif
+
+    return rb_ary_ptr_use_start(a);
+}
+
+/* internal function. do not use this function */
+static inline void
+rb_array_ptr_use_end(VALUE a, int allow_transient)
+{
+    void rb_ary_ptr_use_end(VALUE a);
+    rb_ary_ptr_use_end(a);
+}
+
 #if defined(EXTLIB) && defined(USE_DLN_A_OUT)
 /* hook for external modules */
 static char *dln_libs_to_be_linked[] = { EXTLIB, 0 };

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

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