summaryrefslogtreecommitdiff
path: root/include/ruby/ruby.h
diff options
context:
space:
mode:
authorshyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-01-15 02:35:16 +0000
committershyouhei <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2018-01-15 02:35:16 +0000
commitf089a52865bd82a327fe9ef460cecdb812dcb56c (patch)
treefd2ebe09327942662defac756ae752d0a9134e00 /include/ruby/ruby.h
parent630ab3b925cd8b6e3c94250bb7c970d80604dcdc (diff)
__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
Diffstat (limited to 'include/ruby/ruby.h')
-rw-r--r--include/ruby/ruby.h17
1 files changed, 8 insertions, 9 deletions
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) ? \