ruby-changes:63982
From: Koichi <ko1@a...>
Date: Mon, 7 Dec 2020 08:29:06 +0900 (JST)
Subject: [ruby-changes:63982] 344ec26a99 (master): tuning trial: newobj with current ec
https://git.ruby-lang.org/ruby.git/commit/?id=344ec26a99 From 344ec26a99e09c2d2f756fa6384e75ffa48f415f Mon Sep 17 00:00:00 2001 From: Koichi Sasada <ko1@a...> Date: Sun, 6 Dec 2020 15:41:21 +0900 Subject: tuning trial: newobj with current ec Passing current ec can improve performance of newobj. This patch tries it for Array and String literals ([] and ''). diff --git a/array.c b/array.c index d8e76b0..207d5a3 100644 --- a/array.c +++ b/array.c @@ -790,6 +790,58 @@ rb_ary_new_from_values(long n, const VALUE *elts) https://github.com/ruby/ruby/blob/trunk/array.c#L790 return rb_ary_tmp_new_from_values(rb_cArray, n, elts); } +static VALUE +ec_ary_alloc(rb_execution_context_t *ec, VALUE klass) +{ + RB_EC_NEWOBJ_OF(ec, ary, struct RArray, klass, T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0)); + /* Created array is: + * FL_SET_EMBED((VALUE)ary); + * ARY_SET_EMBED_LEN((VALUE)ary, 0); + */ + return (VALUE)ary; +} + +static VALUE +ec_ary_new(rb_execution_context_t *ec, VALUE klass, long capa) +{ + VALUE ary,*ptr; + + if (capa < 0) { + rb_raise(rb_eArgError, "negative array size (or size too big)"); + } + if (capa > ARY_MAX_SIZE) { + rb_raise(rb_eArgError, "array size too big"); + } + + RUBY_DTRACE_CREATE_HOOK(ARRAY, capa); + + ary = ec_ary_alloc(ec, klass); + + if (capa > RARRAY_EMBED_LEN_MAX) { + ptr = ary_heap_alloc(ary, capa); + FL_UNSET_EMBED(ary); + ARY_SET_PTR(ary, ptr); + ARY_SET_CAPA(ary, capa); + ARY_SET_HEAP_LEN(ary, 0); + } + + return ary; +} + +VALUE +rb_ec_ary_new_from_values(rb_execution_context_t *ec, long n, const VALUE *elts) +{ + VALUE ary; + + ary = ec_ary_new(ec, rb_cArray, n); + if (n > 0 && elts) { + ary_memcpy(ary, 0, n, elts); + ARY_SET_LEN(ary, n); + } + + return ary; +} + VALUE rb_ary_tmp_new(long capa) { diff --git a/insns.def b/insns.def index 3dd65f1..e39037c 100644 --- a/insns.def +++ b/insns.def @@ -363,7 +363,7 @@ putstring https://github.com/ruby/ruby/blob/trunk/insns.def#L363 () (VALUE val) { - val = rb_str_resurrect(str); + val = rb_ec_str_resurrect(ec, str); } /* put concatenate strings */ @@ -426,7 +426,7 @@ newarray https://github.com/ruby/ruby/blob/trunk/insns.def#L426 (VALUE val) // attr rb_snum_t sp_inc = 1 - (rb_snum_t)num; { - val = rb_ary_new4(num, STACK_ADDR_FROM_TOP(num)); + val = rb_ec_ary_new_from_values(ec, num, STACK_ADDR_FROM_TOP(num)); } /* put new array initialized with num values on the stack. There diff --git a/internal/array.h b/internal/array.h index a7bf6d3..44c0efb 100644 --- a/internal/array.h +++ b/internal/array.h @@ -48,6 +48,9 @@ VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *); https://github.com/ruby/ruby/blob/trunk/internal/array.h#L48 VALUE rb_check_to_array(VALUE ary); VALUE rb_ary_behead(VALUE, long); VALUE rb_ary_aref1(VALUE ary, VALUE i); + +struct rb_execution_context_struct; +VALUE rb_ec_ary_new_from_values(struct rb_execution_context_struct *ec, long n, const VALUE *elts); MJIT_SYMBOL_EXPORT_END static inline VALUE diff --git a/internal/string.h b/internal/string.h index 091035d..8907a1a 100644 --- a/internal/string.h +++ b/internal/string.h @@ -69,6 +69,9 @@ VALUE rb_str_concat_literals(size_t num, const VALUE *strary); https://github.com/ruby/ruby/blob/trunk/internal/string.h#L69 VALUE rb_str_eql(VALUE str1, VALUE str2); VALUE rb_id_quote_unprintable(ID); VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, int kw_splat, VALUE passed_proc); + +struct rb_execution_context_struct; +VALUE rb_ec_str_resurrect(struct rb_execution_context_struct *ec, VALUE str); MJIT_SYMBOL_EXPORT_END #define rb_fstring_lit(str) rb_fstring_new((str), rb_strlen_lit(str)) diff --git a/string.c b/string.c index 2ce0fd2..864a090 100644 --- a/string.c +++ b/string.c @@ -1543,7 +1543,14 @@ str_replace(VALUE str, VALUE str2) https://github.com/ruby/ruby/blob/trunk/string.c#L1543 } static inline VALUE -str_duplicate(VALUE klass, VALUE str) +ec_str_alloc(struct rb_execution_context_struct *ec, VALUE klass) +{ + RB_EC_NEWOBJ_OF(ec, str, struct RString, klass, T_STRING | (RGENGC_WB_PROTECTED_STRING ? FL_WB_PROTECTED : 0)); + return (VALUE)str; +} + +static inline VALUE +str_duplicate_setup(VALUE klass, VALUE str, VALUE dup) { enum {embed_size = RSTRING_EMBED_LEN_MAX + 1}; const VALUE flag_mask = @@ -1552,7 +1559,6 @@ str_duplicate(VALUE klass, VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L1559 FL_FREEZE ; VALUE flags = FL_TEST_RAW(str, flag_mask); - VALUE dup = str_alloc(klass); int encidx = 0; MEMCPY(RSTRING(dup)->as.ary, RSTRING(str)->as.ary, char, embed_size); @@ -1582,6 +1588,20 @@ str_duplicate(VALUE klass, VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L1588 return dup; } +static inline VALUE +ec_str_duplicate(struct rb_execution_context_struct *ec, VALUE klass, VALUE str) +{ + VALUE dup = ec_str_alloc(ec, klass); + return str_duplicate_setup(klass, str, dup); +} + +static inline VALUE +str_duplicate(VALUE klass, VALUE str) +{ + VALUE dup = str_alloc(klass); + return str_duplicate_setup(klass, str, dup); +} + VALUE rb_str_dup(VALUE str) { @@ -1595,6 +1615,13 @@ rb_str_resurrect(VALUE str) https://github.com/ruby/ruby/blob/trunk/string.c#L1615 return str_duplicate(rb_cString, str); } +VALUE +rb_ec_str_resurrect(struct rb_execution_context_struct *ec, VALUE str) +{ + RUBY_DTRACE_CREATE_HOOK(STRING, RSTRING_LEN(str)); + return ec_str_duplicate(ec, rb_cString, str); +} + /* * call-seq: * String.new(string = '') -> new_string -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/