ruby-changes:61975
From: =E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3 <ko1@a...>
Date: Mon, 29 Jun 2020 11:06:22 +0900 (JST)
Subject: [ruby-changes:61975] 2e8d8d10f2 (master): rb_ary_behead: do not goto into a branch
https://git.ruby-lang.org/ruby.git/commit/?id=2e8d8d10f2 From 2e8d8d10f211b52f520109a8bfdd3bb3a6eab8c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=9C=E9=83=A8=E6=98=8C=E5=B9=B3?= <shyouhei@r...> Date: Wed, 10 Jun 2020 13:42:30 +0900 Subject: 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. diff --git a/array.c b/array.c index bbfbc2b..d6a2a7a 100644 --- a/array.c +++ b/array.c @@ -1524,36 +1524,50 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary) https://github.com/ruby/ruby/blob/trunk/array.c#L1524 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) { -- cgit v0.10.2 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/