mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* 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
This commit is contained in:
parent
301cb9ca99
commit
6fd9000076
6 changed files with 51 additions and 1 deletions
17
ChangeLog
17
ChangeLog
|
|
@ -1,3 +1,20 @@
|
|||
Thu Sep 5 13:49:00 2013 Charlie Somerville <charliesome@ruby-lang.org>
|
||||
|
||||
* 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
|
||||
|
||||
Thu Sep 5 12:48:00 2013 Kenta Murata <mrkn@cookpad.com>
|
||||
|
||||
* configure.in (with_gmp): set with_gmp no if it is empty.
|
||||
|
|
|
|||
|
|
@ -905,6 +905,7 @@ struct RString {
|
|||
} as;
|
||||
};
|
||||
#define RSTRING_NOEMBED FL_USER1
|
||||
#define RSTRING_FSTR FL_USER17
|
||||
#define RSTRING_EMBED_LEN_MASK (FL_USER2|FL_USER3|FL_USER4|FL_USER5|FL_USER6)
|
||||
#define RSTRING_EMBED_LEN_SHIFT (FL_USHIFT+2)
|
||||
#define RSTRING_EMBED_LEN(str) \
|
||||
|
|
|
|||
|
|
@ -600,6 +600,7 @@ size_t rb_strftime(char *s, size_t maxsize, const char *format, rb_encoding *enc
|
|||
#endif
|
||||
|
||||
/* string.c */
|
||||
VALUE rb_fstring(VALUE);
|
||||
int rb_str_buf_cat_escaped_char(VALUE result, unsigned int c, int unicode_p);
|
||||
int rb_str_symname_p(VALUE);
|
||||
VALUE rb_str_quote_unprintable(VALUE);
|
||||
|
|
|
|||
2
parse.y
2
parse.y
|
|
@ -8561,7 +8561,7 @@ str_suffix_gen(struct parser_params *parser, NODE *node, long opt)
|
|||
#endif
|
||||
#if STR_OPTION_FROZEN
|
||||
if (opt & STR_OPTION_FROZEN) {
|
||||
OBJ_FREEZE(node->nd_lit);
|
||||
node->nd_lit = rb_fstring(node->nd_lit);
|
||||
nd_set_type(node, NODE_LIT);
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
25
string.c
25
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);
|
||||
|
|
|
|||
|
|
@ -2243,6 +2243,12 @@ class TestString < Test::Unit::TestCase
|
|||
})
|
||||
end
|
||||
end
|
||||
|
||||
def test_frozen_strings_are_deduplicated
|
||||
a = "hello"f
|
||||
b = "hello"f
|
||||
assert_equal a.object_id, b.object_id
|
||||
end
|
||||
end
|
||||
|
||||
class TestString2 < TestString
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue