ruby-changes:30764
From: charliesome <ko1@a...>
Date: Thu, 5 Sep 2013 13:49:25 +0900 (JST)
Subject: [ruby-changes:30764] charliesome:r42843 (trunk): * include/ruby/ruby.h: add RSTRING_FSTR flag
charliesome 2013-09-05 13:49:16 +0900 (Thu, 05 Sep 2013) New Revision: 42843 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=42843 Log: * 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 Modified files: trunk/ChangeLog trunk/include/ruby/ruby.h trunk/internal.h trunk/parse.y trunk/string.c trunk/test/ruby/test_string.rb Index: include/ruby/ruby.h =================================================================== --- include/ruby/ruby.h (revision 42842) +++ include/ruby/ruby.h (revision 42843) @@ -905,6 +905,7 @@ struct RString { https://github.com/ruby/ruby/blob/trunk/include/ruby/ruby.h#L905 } 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) \ Index: ChangeLog =================================================================== --- ChangeLog (revision 42842) +++ ChangeLog (revision 42843) @@ -1,3 +1,20 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1 +Thu Sep 5 13:49:00 2013 Charlie Somerville <charliesome@r...> + + * 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@c...> * configure.in (with_gmp): set with_gmp no if it is empty. Index: string.c =================================================================== --- string.c (revision 42842) +++ string.c (revision 42843) @@ -131,6 +131,26 @@ VALUE rb_cSymbol; https://github.com/ruby/ruby/blob/trunk/string.c#L131 #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 https://github.com/ruby/ruby/blob/trunk/string.c#L858 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) https://github.com/ruby/ruby/blob/trunk/string.c#L8695 #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); Index: parse.y =================================================================== --- parse.y (revision 42842) +++ parse.y (revision 42843) @@ -8561,7 +8561,7 @@ str_suffix_gen(struct parser_params *par https://github.com/ruby/ruby/blob/trunk/parse.y#L8561 #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 Index: internal.h =================================================================== --- internal.h (revision 42842) +++ internal.h (revision 42843) @@ -600,6 +600,7 @@ size_t rb_strftime(char *s, size_t maxsi https://github.com/ruby/ruby/blob/trunk/internal.h#L600 #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); Index: test/ruby/test_string.rb =================================================================== --- test/ruby/test_string.rb (revision 42842) +++ test/ruby/test_string.rb (revision 42843) @@ -2243,6 +2243,12 @@ class TestString < Test::Unit::TestCase https://github.com/ruby/ruby/blob/trunk/test/ruby/test_string.rb#L2243 }) 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 -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/