summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--compile.c2
-rw-r--r--configure.ac26
-rw-r--r--include/ruby/defines.h4
-rw-r--r--include/ruby/ruby.h17
-rw-r--r--win32/Makefile.sub1
5 files changed, 39 insertions, 11 deletions
diff --git a/compile.c b/compile.c
index f4ae64bacc..98004b65a0 100644
--- a/compile.c
+++ b/compile.c
@@ -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, ...] */
diff --git a/configure.ac b/configure.ac
index 81efb0bbc1..f7707b761d 100644
--- a/configure.ac
+++ b/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)
diff --git a/include/ruby/defines.h b/include/ruby/defines.h
index 2c72a7cb8a..da2ba24109 100644
--- a/include/ruby/defines.h
+++ b/include/ruby/defines.h
@@ -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)
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index 6d84a6b06e..fe0ecf4622 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -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) ? \
diff --git a/win32/Makefile.sub b/win32/Makefile.sub
index 944573f1bb..a3ac277dd2 100644
--- a/win32/Makefile.sub
+++ b/win32/Makefile.sub
@@ -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