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:
parent
630ab3b925
commit
f089a52865
5 changed files with 39 additions and 11 deletions
|
@ -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, ...] */
|
||||
|
|
26
configure.ac
26
configure.ac
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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) ? \
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue