summaryrefslogtreecommitdiffhomepage
path: root/include
diff options
context:
space:
mode:
authorKOBAYASHI Shuji <[email protected]>2019-08-20 18:49:55 +0900
committerKOBAYASHI Shuji <[email protected]>2019-08-20 18:49:55 +0900
commit8157672a29e50756b9709022e8f66da73cd92c2b (patch)
tree3fbec1e5e92d6c1a5fc3f28d9f649f2a17ea2fdc /include
parentb836fd05dd084ac9e61c918cf1757b425c4d271b (diff)
downloadmruby-8157672a29e50756b9709022e8f66da73cd92c2b.tar.gz
mruby-8157672a29e50756b9709022e8f66da73cd92c2b.zip
Use `RBasic` padding for embedded string on 64-bit CPU
On 64-bit CPU, there is padding in `RBasic`, so reorder the fields and use it as buffer of embedded string. This change allows 4 more bytes to be embedded on 64-bit CPU. However, an incompatibility will occur if `RString::as::ary` is accessed directly because `RString` structure has changed.
Diffstat (limited to 'include')
-rw-r--r--include/mruby/object.h6
-rw-r--r--include/mruby/string.h11
2 files changed, 11 insertions, 6 deletions
diff --git a/include/mruby/object.h b/include/mruby/object.h
index 48dcc4977..1cb4ca6e8 100644
--- a/include/mruby/object.h
+++ b/include/mruby/object.h
@@ -8,11 +8,11 @@
#define MRUBY_OBJECT_H
#define MRB_OBJECT_HEADER \
+ struct RClass *c; \
+ struct RBasic *gcnext; \
enum mrb_vtype tt:8; \
uint32_t color:3; \
- uint32_t flags:21; \
- struct RClass *c; \
- struct RBasic *gcnext
+ uint32_t flags:21
#define MRB_FLAG_TEST(obj, flag) ((obj)->flags & (flag))
diff --git a/include/mruby/string.h b/include/mruby/string.h
index ab29be421..84a6c4665 100644
--- a/include/mruby/string.h
+++ b/include/mruby/string.h
@@ -16,7 +16,8 @@ MRB_BEGIN_DECL
extern const char mrb_digitmap[];
-#define RSTRING_EMBED_LEN_MAX ((mrb_int)(sizeof(void*) * 3 - 1))
+#define RSTRING_EMBED_LEN_MAX \
+ ((mrb_int)(sizeof(void*) * 3 + sizeof(void*) - 32 / CHAR_BIT - 1))
struct RString {
MRB_OBJECT_HEADER;
@@ -30,9 +31,12 @@ struct RString {
} aux;
char *ptr;
} heap;
- char ary[RSTRING_EMBED_LEN_MAX + 1];
} as;
};
+struct RStringEmbed {
+ MRB_OBJECT_HEADER;
+ char ary[];
+};
#define RSTR_SET_TYPE_FLAG(s, type) (RSTR_UNSET_TYPE_FLAG(s), (s)->flags |= MRB_STR_##type)
#define RSTR_UNSET_TYPE_FLAG(s) ((s)->flags &= ~(MRB_STR_TYPE_MASK|MRB_STR_EMBED_LEN_MASK))
@@ -53,11 +57,12 @@ struct RString {
(s)->as.heap.len = (mrb_int)(n);\
}\
} while (0)
+#define RSTR_EMBED_PTR(s) (((struct RStringEmbed*)(s))->ary)
#define RSTR_EMBED_LEN(s)\
(mrb_int)(((s)->flags & MRB_STR_EMBED_LEN_MASK) >> MRB_STR_EMBED_LEN_SHIFT)
#define RSTR_EMBEDDABLE_P(len) ((len) <= RSTRING_EMBED_LEN_MAX)
-#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? (s)->as.ary : (s)->as.heap.ptr)
+#define RSTR_PTR(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_PTR(s) : (s)->as.heap.ptr)
#define RSTR_LEN(s) ((RSTR_EMBED_P(s)) ? RSTR_EMBED_LEN(s) : (s)->as.heap.len)
#define RSTR_CAPA(s) (RSTR_EMBED_P(s) ? RSTRING_EMBED_LEN_MAX : (s)->as.heap.aux.capa)