[前][次][番号順一覧][スレッド一覧]

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/

[前][次][番号順一覧][スレッド一覧]