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

ruby-changes:47240

From: normal <ko1@a...>
Date: Tue, 18 Jul 2017 13:30:13 +0900 (JST)
Subject: [ruby-changes:47240] normal:r59355 (trunk): newhash insn reuses existing keys

normal	2017-07-18 13:30:08 +0900 (Tue, 18 Jul 2017)

  New Revision: 59355

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=59355

  Log:
    newhash insn reuses existing keys
    
    This gives the newhash VM instruction the same string reuse
    capabilities as rb_hash_aset.
    
    * st.c (str_key): new wrapper function to call rb_fstring_existing
      (rb_hash_bulk_insert): use str_key
    * test/ruby/test_optimization.rb (test_hash_reuse_fstring):
      ensure key reuse for newhash instructions

  Modified files:
    trunk/st.c
    trunk/test/ruby/test_optimization.rb
Index: test/ruby/test_optimization.rb
===================================================================
--- test/ruby/test_optimization.rb	(revision 59354)
+++ test/ruby/test_optimization.rb	(revision 59355)
@@ -196,6 +196,9 @@ class TestRubyOptimization < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_optimization.rb#L196
       assert_predicate h.keys[0], :frozen?
       assert_same exp, h.keys[0]
 
+      h = { key => 1 }
+      assert_same exp, h.keys[0], 'newhash insn should reuse strings, too'
+
       h1 = {}
       h2 = {}
       key.taint
@@ -206,6 +209,10 @@ class TestRubyOptimization < Test::Unit: https://github.com/ruby/ruby/blob/trunk/test/ruby/test_optimization.rb#L209
       assert_same k1, k2
       assert_predicate k1, :tainted?
 
+      h = { key => 1 }
+      assert_not_predicate key, :frozen?
+      assert_same k1, h.keys[0], 'newhash insn should reuse tainted strings'
+
       assert_equal GC::INTERNAL_CONSTANTS[:RVALUE_SIZE],
                    ObjectSpace.memsize_of(k1),
                    'tainted string should share with untainted fstring'
Index: st.c
===================================================================
--- st.c	(revision 59354)
+++ st.c	(revision 59355)
@@ -2092,6 +2092,23 @@ st_rehash(st_table *tab) https://github.com/ruby/ruby/blob/trunk/st.c#L2092
 }
 
 #ifdef RUBY
+
+static VALUE
+str_key(VALUE key)
+{
+    VALUE k;
+
+    if (RB_OBJ_FROZEN(key)) {
+	return key;
+    }
+    if ((k = rb_fstring_existing(key)) != Qnil) {
+	return k;
+    }
+    else {
+	return rb_str_new_frozen(key);
+    }
+}
+
 /* Mimics ruby's { foo => bar } syntax. This function is placed here
    because it touches table internals and write barriers at once. */
 void
@@ -2114,8 +2131,7 @@ rb_hash_bulk_insert(long argc, const VAL https://github.com/ruby/ruby/blob/trunk/st.c#L2131
     for (i = 0; i < argc; /* */) {
         VALUE key = argv[i++];
         VALUE val = argv[i++];
-        st_data_t k = (rb_obj_class(key) == rb_cString) ?
-            rb_str_new_frozen(key) : key;
+        st_data_t k = (rb_obj_class(key) == rb_cString) ? str_key(key) : key;
         st_table_entry e;
         e.hash = do_hash(k, tab);
         e.key = k;

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

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