summaryrefslogtreecommitdiff
path: root/string.c
diff options
context:
space:
mode:
authorcharliesome <charliesome@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-09-05 04:49:16 +0000
committercharliesome <charliesome@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2013-09-05 04:49:16 +0000
commit6fd900007616801f4c8adcc0228fe06bd6f1f873 (patch)
tree56c09166a8ac25e195f9c14f493579a16be90904 /string.c
parent301cb9ca993347ee0f78719f7e01ddb8c16927f5 (diff)
* include/ruby/ruby.h: add RSTRING_FSTR flag
* internal.h: add rb_fstring() prototype * parse.y (str_suffix_gen): deduplicate frozen string literals * string.c (rb_fstring): deduplicate frozen string literals * string.c (rb_str_free): delete fstrings from frozen_strings table when they are GC'd * string.c (Init_String): initialize frozen_strings table * test/ruby/test_string.rb: test frozen strings are deduplicated git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@42843 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'string.c')
-rw-r--r--string.c25
1 files changed, 25 insertions, 0 deletions
diff --git a/string.c b/string.c
index 4bc26df81e..7ee4730930 100644
--- a/string.c
+++ b/string.c
@@ -131,6 +131,26 @@ VALUE rb_cSymbol;
#define STR_ENC_GET(str) rb_enc_from_index(ENCODING_GET(str))
+static st_table* frozen_strings;
+
+static const struct st_hash_type fstring_hash_type = {
+ rb_str_cmp,
+ rb_str_hash
+};
+
+VALUE
+rb_fstring(VALUE str)
+{
+ VALUE fstr;
+ if (!st_lookup(frozen_strings, (st_data_t)str, (st_data_t*)&fstr)) {
+ fstr = rb_str_dup(str);
+ OBJ_FREEZE(fstr);
+ RBASIC(fstr)->flags |= RSTRING_FSTR;
+ st_insert(frozen_strings, fstr, fstr);
+ }
+ return fstr;
+}
+
static inline int
single_byte_optimizable(VALUE str)
{
@@ -838,6 +858,9 @@ rb_free_tmp_buffer(volatile VALUE *store)
void
rb_str_free(VALUE str)
{
+ if (FL_TEST(str, RSTRING_FSTR)) {
+ st_delete(frozen_strings, (st_data_t*)&str, NULL);
+ }
if (!STR_EMBED_P(str) && !STR_SHARED_P(str)) {
xfree(RSTRING(str)->as.heap.ptr);
}
@@ -8672,6 +8695,8 @@ Init_String(void)
#undef rb_intern
#define rb_intern(str) rb_intern_const(str)
+ frozen_strings = st_init_table(&fstring_hash_type);
+
rb_cString = rb_define_class("String", rb_cObject);
rb_include_module(rb_cString, rb_mComparable);
rb_define_alloc_func(rb_cString, empty_str_alloc);