summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-10-09 07:53:54 +0000
committernobu <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2014-10-09 07:53:54 +0000
commit795b8b474c52b97fc81bba7888aa70e18e8fd79d (patch)
treea7fe09dfc2e37f500881e7fabc971ae5db6aa91e
parent9629e7efc143ec5dc409eade499a65f4a348b9ce (diff)
internal.h: optimize rb_ary_new_from_args
* internal.h (rb_ary_new_from_args): optimization by expanding arguments in caller to get rid of va_list if possible. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@47858 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--array.c2
-rw-r--r--internal.h14
2 files changed, 14 insertions, 2 deletions
diff --git a/array.c b/array.c
index 71e9b46edf..5fd2702af6 100644
--- a/array.c
+++ b/array.c
@@ -499,7 +499,7 @@ rb_ary_new(void)
}
VALUE
-rb_ary_new_from_args(long n, ...)
+(rb_ary_new_from_args)(long n, ...)
{
va_list ar;
VALUE ary;
diff --git a/internal.h b/internal.h
index a4d56b9984..a9fd533cd2 100644
--- a/internal.h
+++ b/internal.h
@@ -63,7 +63,8 @@ extern "C" {
#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
-#define STATIC_ASSERT(name, expr) typedef int static_assert_##name##_check[1 - 2*!(expr)]
+#define STATIC_ASSERT_TYPE(name) static_assert_##name##_check
+#define STATIC_ASSERT(name, expr) typedef int STATIC_ASSERT_TYPE(name)[1 - 2*!(expr)]
#define GCC_VERSION_SINCE(major, minor, patchlevel) \
(defined(__GNUC__) && !defined(__INTEL_COMPILER) && \
@@ -509,6 +510,17 @@ VALUE rb_ary_last(int, const VALUE *, VALUE);
void rb_ary_set_len(VALUE, long);
void rb_ary_delete_same(VALUE, VALUE);
VALUE rb_ary_tmp_new_fill(long capa);
+#ifdef __GNUC__
+#define rb_ary_new_from_args(n, ...) \
+ __extension__ ({ \
+ const VALUE args_to_new_ary[] = {__VA_ARGS__}; \
+ if (__builtin_constant_p(n)) { \
+ STATIC_ASSERT(rb_ary_new_from_args, numberof(args_to_new_ary) == (n)); \
+ (void)sizeof(STATIC_ASSERT_TYPE(rb_ary_new_from_args)); /* suppress warnings by gcc 4.8 or later */ \
+ } \
+ rb_ary_new_from_values(numberof(args_to_new_ary), args_to_new_ary); \
+ })
+#endif
/* bignum.c */
VALUE rb_big_fdiv(VALUE x, VALUE y);