diff options
-rw-r--r-- | array.c | 52 | ||||
-rw-r--r-- | insns.def | 4 | ||||
-rw-r--r-- | internal/array.h | 3 | ||||
-rw-r--r-- | internal/string.h | 3 | ||||
-rw-r--r-- | string.c | 31 |
5 files changed, 89 insertions, 4 deletions
@@ -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) { @@ -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)) @@ -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 |