summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorPeter Zhu <peter@peterzhu.ca>2021-08-26 10:06:32 -0400
committerPeter Zhu <peter@peterzhu.ca>2021-10-25 13:26:23 -0400
commita5b6598192c30187b19b892af3110a46f6a70d76 (patch)
tree4620f69a10659deb6f278b36c10ec7915194573e /include
parent6374be5a8188ff5ed2c70b9f1d76672c87a0eda7 (diff)
[Feature #18239] Implement VWA for strings
This commit adds support for embedded strings with variable capacity and uses Variable Width Allocation to allocate strings.
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/4933
Diffstat (limited to 'include')
-rw-r--r--include/ruby/internal/config.h4
-rw-r--r--include/ruby/internal/core/rstring.h20
2 files changed, 24 insertions, 0 deletions
diff --git a/include/ruby/internal/config.h b/include/ruby/internal/config.h
index b6134c6165..51f863fc29 100644
--- a/include/ruby/internal/config.h
+++ b/include/ruby/internal/config.h
@@ -146,4 +146,8 @@
# undef RBIMPL_TEST3
#endif /* HAVE_VA_ARGS_MACRO */
+#ifndef USE_RVARGC
+# define USE_RVARGC 0
+#endif
+
#endif /* RBIMPL_CONFIG_H */
diff --git a/include/ruby/internal/core/rstring.h b/include/ruby/internal/core/rstring.h
index f7d0539a0c..b7cf142156 100644
--- a/include/ruby/internal/core/rstring.h
+++ b/include/ruby/internal/core/rstring.h
@@ -42,9 +42,11 @@
/** @cond INTERNAL_MACRO */
#define RSTRING_NOEMBED RSTRING_NOEMBED
+#if !USE_RVARGC
#define RSTRING_EMBED_LEN_MASK RSTRING_EMBED_LEN_MASK
#define RSTRING_EMBED_LEN_SHIFT RSTRING_EMBED_LEN_SHIFT
#define RSTRING_EMBED_LEN_MAX RSTRING_EMBED_LEN_MAX
+#endif
#define RSTRING_FSTR RSTRING_FSTR
#define RSTRING_EMBED_LEN RSTRING_EMBED_LEN
#define RSTRING_LEN RSTRING_LEN
@@ -160,6 +162,7 @@ enum ruby_rstring_flags {
*/
RSTRING_NOEMBED = RUBY_FL_USER1,
+#if !USE_RVARGC
/**
* When a string employs embedded strategy (see ::RSTRING_NOEMBED), these
* bits are used to store the number of bytes actually filled into
@@ -172,6 +175,7 @@ enum ruby_rstring_flags {
*/
RSTRING_EMBED_LEN_MASK = RUBY_FL_USER2 | RUBY_FL_USER3 | RUBY_FL_USER4 |
RUBY_FL_USER5 | RUBY_FL_USER6,
+#endif
/* Actually, string encodings are also encoded into the flags, using
* remaining bits.*/
@@ -198,6 +202,7 @@ enum ruby_rstring_flags {
RSTRING_FSTR = RUBY_FL_USER17
};
+#if !USE_RVARGC
/**
* This is an enum because GDB wants it (rather than a macro). People need not
* bother.
@@ -209,6 +214,7 @@ enum ruby_rstring_consts {
/** Max possible number of characters that can be embedded. */
RSTRING_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(char) - 1
};
+#endif
/**
* Ruby's String. A string in ruby conceptually has these information:
@@ -278,7 +284,17 @@ struct RString {
* here. Could be sufficiently large. In this case the length is
* encoded into the flags.
*/
+#if USE_RVARGC
+ short len;
+ /* This is a length 1 array because:
+ * 1. GCC has a bug that does not optimize C flexible array members
+ * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
+ * 2. Zero length arrays are not supported by all compilers
+ */
+ char ary[1];
+#else
char ary[RSTRING_EMBED_LEN_MAX + 1];
+#endif
} embed;
} as;
};
@@ -407,9 +423,13 @@ RSTRING_EMBED_LEN(VALUE str)
RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
RBIMPL_ASSERT_OR_ASSUME(! RB_FL_ANY_RAW(str, RSTRING_NOEMBED));
+#if USE_RVARGC
+ short f = RSTRING(str)->as.embed.len;
+#else
VALUE f = RBASIC(str)->flags;
f &= RSTRING_EMBED_LEN_MASK;
f >>= RSTRING_EMBED_LEN_SHIFT;
+#endif
return RBIMPL_CAST((long)f);
}