summaryrefslogtreecommitdiff
path: root/array.c
diff options
context:
space:
mode:
author卜部昌平 <shyouhei@ruby-lang.org>2020-06-10 13:42:30 +0900
committer卜部昌平 <shyouhei@ruby-lang.org>2020-06-29 11:05:41 +0900
commit2e8d8d10f211b52f520109a8bfdd3bb3a6eab8c0 (patch)
treea7a599505dfdf3611007f295468703238b64d92d /array.c
parent09b936d89cb66e38db46dbe782aa5f22f94656bc (diff)
rb_ary_behead: do not goto into a branch
I'm not necessarily against every goto in general, but jumping into a branch is definitely a bad idea. Better refactor.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/3247
Diffstat (limited to 'array.c')
-rw-r--r--array.c56
1 files changed, 35 insertions, 21 deletions
diff --git a/array.c b/array.c
index bbfbc2baec..d6a2a7abed 100644
--- a/array.c
+++ b/array.c
@@ -1524,36 +1524,50 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary)
return result;
}
-MJIT_FUNC_EXPORTED VALUE
-rb_ary_behead(VALUE ary, long n)
+static VALUE
+behead_shared(VALUE ary, long n)
{
- if (n<=0) return ary;
-
+ assert(ARY_SHARED_P(ary));
rb_ary_modify_check(ary);
- if (ARY_SHARED_P(ary)) {
- if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
- setup_occupied_shared:
- ary_mem_clear(ary, 0, n);
- }
- ARY_INCREASE_PTR(ary, n);
- }
- else {
- if (RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) {
- RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
- MEMMOVE(ptr, ptr+n, VALUE, RARRAY_LEN(ary)-n);
- }); /* WB: no new reference */
- }
- else {
- ary_make_shared(ary);
- goto setup_occupied_shared;
- }
+ if (ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))) {
+ ary_mem_clear(ary, 0, n);
}
+ ARY_INCREASE_PTR(ary, n);
ARY_INCREASE_LEN(ary, -n);
+ ary_verify(ary);
+ return ary;
+}
+static VALUE
+behead_transient(VALUE ary, long n)
+{
+ rb_ary_modify_check(ary);
+ RARRAY_PTR_USE_TRANSIENT(ary, ptr, {
+ MEMMOVE(ptr, ptr+n, VALUE, RARRAY_LEN(ary)-n);
+ }); /* WB: no new reference */
+ ARY_INCREASE_LEN(ary, -n);
ary_verify(ary);
return ary;
}
+MJIT_FUNC_EXPORTED VALUE
+rb_ary_behead(VALUE ary, long n)
+{
+ if (n <= 0) {
+ return ary;
+ }
+ else if (ARY_SHARED_P(ary)) {
+ return behead_shared(ary, n);
+ }
+ else if (RARRAY_LEN(ary) >= ARY_DEFAULT_SIZE) {
+ ary_make_shared(ary);
+ return behead_shared(ary, n);
+ }
+ else {
+ return behead_transient(ary, n);
+ }
+}
+
static VALUE
ary_ensure_room_for_unshift(VALUE ary, int argc)
{