summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-12-06 15:41:21 +0900
committerKoichi Sasada <ko1@atdot.net>2020-12-07 08:28:36 +0900
commit344ec26a99e09c2d2f756fa6384e75ffa48f415f (patch)
tree71aeb66c03bad047e36de3b7a5ab74962139f789
parent59ddb88da6bf483eeec7b85b8a85cf3719edf440 (diff)
tuning trial: newobj with current ec
Passing current ec can improve performance of newobj. This patch tries it for Array and String literals ([] and '').
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3842
-rw-r--r--array.c52
-rw-r--r--insns.def4
-rw-r--r--internal/array.h3
-rw-r--r--internal/string.h3
-rw-r--r--string.c31
5 files changed, 89 insertions, 4 deletions
diff --git a/array.c b/array.c
index d8e76b050b..207d5a337a 100644
--- a/array.c
+++ b/array.c
@@ -790,6 +790,58 @@ rb_ary_new_from_values(long n, const VALUE *elts)
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 3dd65f12c7..e39037c039 100644
--- a/insns.def
+++ b/insns.def
@@ -363,7 +363,7 @@ putstring
()
(VALUE val)
{
- val = rb_str_resurrect(str);
+ val = rb_ec_str_resurrect(ec, str);
}
/* put concatenate strings */
@@ -426,7 +426,7 @@ newarray
(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 a7bf6d3868..44c0efbbc1 100644
--- a/internal/array.h
+++ b/internal/array.h
@@ -48,6 +48,9 @@ VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
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 091035d92c..8907a1a6e6 100644
--- a/internal/string.h
+++ b/internal/string.h
@@ -69,6 +69,9 @@ VALUE rb_str_concat_literals(size_t num, const VALUE *strary);
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 2ce0fd2e05..864a0909b2 100644
--- a/string.c
+++ b/string.c
@@ -1543,7 +1543,14 @@ str_replace(VALUE str, VALUE str2)
}
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)
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)
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)
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