1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

__attibute__((__aligned__)) for RSTRING_PTR()

For instance array.c:rb_ary_product() uses RSTRING_PTR() as an
array of int. So to avoid misaligned memory access RSTRING_PTR()
must at least be sizeof(int)-aligned.  However the type of
RSTRING_PTR() is char*, which of course can expect alignment as
much as 1.  This is a problem.

The reality is, there is no misaligned memory access because the
memory region behind RSTRING_PTR() is allocated using malloc().
Memory regions returned from malloc() are always aligned
appropriately.  So let's tell the compiler about this information.
It seems GCC, clang, and MSVC have such feature.

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@61827 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
shyouhei 2018-01-15 02:35:16 +00:00
parent 630ab3b925
commit f089a52865
5 changed files with 39 additions and 11 deletions

View file

@ -8077,7 +8077,7 @@ struct ibf_dump {
rb_iseq_t * iseq_alloc(void);
struct ibf_load {
const char *buff;
const RUBY_ALIGNAS(sizeof(VALUE)) char *buff;
const struct ibf_header *header;
ID *id_list; /* [id0, ...] */
VALUE iseq_list; /* [iseq0, ...] */

View file

@ -1743,6 +1743,30 @@ EOH
])dnl
])dnl
AC_CACHE_CHECK([for alignas() syntax], rb_cv_have_alignas, [
rb_cv_have_alignas=no
RUBY_WERROR_FLAG([
for attr in \
"_Alignas(x)" \
"alignas(x)" \
"@<:@@<:@alignas(x)@:>@@:>@" \
"__declspec(aligned(x))" \
"__attribute__((__aligned__(x)))" \
;
do
# C11 _Alignas and GCC __attribute__((__aligned__)) behave
# slightly differently. What we want is GCC's. Check that
# here by something C11 does not allow (`struct ALIGNAS ...`)
AC_TRY_COMPILE(
[@%:@define ALIGNAS(x) $attr
struct ALIGNAS(128) conftest_tag { int foo; } foo; ], [],
[rb_cv_have_alignas="$attr"; break], [])
done
])])
AS_IF([test "$rb_cv_have_alignas" != no], [
AC_DEFINE_UNQUOTED([RUBY_ALIGNAS(x)], $rb_cv_have_alignas)
])
dnl RUBY_DECL_ATTRIBUTE(attrib, macroname, cachevar, condition, type, code)
AC_DEFUN([RUBY_DECL_ATTRIBUTE], [dnl
m4_ifval([$2], dnl
@ -1773,6 +1797,7 @@ ${rbcv_cond+[@%:@define ]attrib[](attrib_params)[ x]}
${rbcv_cond+[@%:@endif]})
$6
@%:@define mesg ("")
@%:@define n (32768)
attrib[](attrib_params)[;], [],
[rbcv="$mac"; break])
done
@ -1801,7 +1826,6 @@ AC_DEFUN([RUBY_TYPE_ATTRIBUTE], [dnl
@%:@define x struct conftest_attribute_check {int i;}
])
])
RUBY_FUNC_ATTRIBUTE(__const__, CONSTFUNC)
RUBY_FUNC_ATTRIBUTE(__pure__, PUREFUNC)
RUBY_FUNC_ATTRIBUTE(__noreturn__, NORETURN)

View file

@ -376,6 +376,10 @@ void rb_ia64_flushrs(void);
# endif
#endif
#ifndef RUBY_ALIGNAS
#define RUBY_ALIGNAS(x) y
#endif
RUBY_SYMBOL_EXPORT_END
#if defined(__cplusplus)

View file

@ -853,14 +853,10 @@ enum ruby_fl_type {
RUBY_FL_SINGLETON = RUBY_FL_USER0
};
struct RBasic {
struct RUBY_ALIGNAS(sizeof(VALUE)) RBasic {
VALUE flags;
const VALUE klass;
}
#ifdef __GNUC__
__attribute__((aligned(sizeof(VALUE))))
#endif
;
};
VALUE rb_obj_hide(VALUE obj);
VALUE rb_obj_reveal(VALUE obj, VALUE klass); /* do not use this API to change klass information */
@ -953,18 +949,21 @@ enum ruby_rstring_flags {
RSTRING_ENUM_END
};
typedef RUBY_ALIGNAS(sizeof(VALUE)) char ruby_aligned_char;
struct RString {
struct RBasic basic;
union {
struct {
long len;
char *ptr;
ruby_aligned_char *ptr;
union {
long capa;
VALUE shared;
} aux;
} heap;
char ary[RSTRING_EMBED_LEN_MAX + 1];
char RUBY_ALIGNAS(sizeof(VALUE)) ary[RSTRING_EMBED_LEN_MAX + 1];
} as;
};
#define RSTRING_EMBED_LEN(str) \
@ -976,7 +975,7 @@ struct RString {
RSTRING(str)->as.heap.len)
#define RSTRING_PTR(str) \
(!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \
RSTRING(str)->as.ary : \
(ruby_aligned_char *)RSTRING(str)->as.ary : \
RSTRING(str)->as.heap.ptr)
#define RSTRING_END(str) \
(!(RBASIC(str)->flags & RSTRING_NOEMBED) ? \

View file

@ -636,6 +636,7 @@ $(CONFIG_H): $(MKFILES) $(srcdir)/win32/Makefile.sub $(win_srcdir)/Makefile.sub
#define PACKED_STRUCT_UNALIGNED(x) x
!endif
#define RUBY_EXTERN extern __declspec(dllimport)
#define RUBY_ALIGNAS(n) __declspec(align(n))
#define HAVE_DECL_SYS_NERR 1
#define HAVE_LIMITS_H 1
#define HAVE_FCNTL_H 1