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

ruby-changes:33335

From: charliesome <ko1@a...>
Date: Wed, 26 Mar 2014 08:46:14 +0900 (JST)
Subject: [ruby-changes:33335] charliesome:r45414 (trunk): Stop allocating backref strings within gsub's search loop

charliesome	2014-03-26 08:46:05 +0900 (Wed, 26 Mar 2014)

  New Revision: 45414

  http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=45414

  Log:
    Stop allocating backref strings within gsub's search loop
    
    * internal.h: add prototype for rb_reg_search0
    
    * re.c: rename rb_reg_search to rb_reg_search0, add set_backref_str
      argument to allow callers to indicate that they don't require the
      backref string to be allocated
    
    * string.c: don't allocate backref str if replacement string is provided
    
    Closes GH-578. [Bug #9676] [ruby-core:61682]

  Modified files:
    trunk/ChangeLog
    trunk/internal.h
    trunk/re.c
    trunk/string.c
Index: ChangeLog
===================================================================
--- ChangeLog	(revision 45413)
+++ ChangeLog	(revision 45414)
@@ -1,3 +1,15 @@ https://github.com/ruby/ruby/blob/trunk/ChangeLog#L1
+Wed Mar 26 08:45:00 2014  Sam Rawlins  <sam.rawlins@g...>
+
+	* internal.h: add prototype for rb_reg_search0
+
+	* re.c: rename rb_reg_search to rb_reg_search0, add set_backref_str
+	  argument to allow callers to indicate that they don't require the
+	  backref string to be allocated.
+
+	* string.c: don't allocate backref str if replacement string is provided
+
+	[GH-578] [Bug #9676] [ruby-core:61682]
+
 Wed Mar 26 08:29:43 2014  mo khan  <mo@m...>
 
 	* lib/rubygem.rb: fix spelling of Jim Weirich.  [Fixes GH-577]
Index: re.c
===================================================================
--- re.c	(revision 45413)
+++ re.c	(revision 45414)
@@ -1375,7 +1375,7 @@ rb_reg_adjust_startpos(VALUE re, VALUE s https://github.com/ruby/ruby/blob/trunk/re.c#L1375
 
 /* returns byte offset */
 long
-rb_reg_search(VALUE re, VALUE str, long pos, int reverse)
+rb_reg_search0(VALUE re, VALUE str, long pos, int reverse, int set_backref_str)
 {
     long result;
     VALUE match;
@@ -1450,17 +1450,26 @@ rb_reg_search(VALUE re, VALUE str, long https://github.com/ruby/ruby/blob/trunk/re.c#L1450
 	    FL_UNSET(match, FL_TAINT);
     }
 
-    RMATCH(match)->str = rb_str_new4(str);
+    if (set_backref_str) {
+	RMATCH(match)->str = rb_str_new4(str);
+	OBJ_INFECT(match, str);
+    }
+
     RMATCH(match)->regexp = re;
     RMATCH(match)->rmatch->char_offset_updated = 0;
     rb_backref_set(match);
 
     OBJ_INFECT(match, re);
-    OBJ_INFECT(match, str);
 
     return result;
 }
 
+long
+rb_reg_search(VALUE re, VALUE str, long pos, int reverse)
+{
+	return rb_reg_search0(re, str, pos, reverse, 1);
+}
+
 VALUE
 rb_reg_nth_defined(int nth, VALUE match)
 {
Index: string.c
===================================================================
--- string.c	(revision 45413)
+++ string.c	(revision 45414)
@@ -4021,6 +4021,7 @@ str_gsub(int argc, VALUE *argv, VALUE st https://github.com/ruby/ruby/blob/trunk/string.c#L4021
     int iter = 0;
     char *sp, *cp;
     int tainted = 0;
+    int str_replace;
     rb_encoding *str_enc;
 
     switch (argc) {
@@ -4041,7 +4042,8 @@ str_gsub(int argc, VALUE *argv, VALUE st https://github.com/ruby/ruby/blob/trunk/string.c#L4042
     }
 
     pat = get_pat(argv[0], 1);
-    beg = rb_reg_search(pat, str, 0, 0);
+    str_replace = !iter && NIL_P(hash);
+    beg = rb_reg_search0(pat, str, 0, 0, !str_replace);
     if (beg < 0) {
 	if (bang) return Qnil;	/* no match, no substitution */
 	return rb_str_dup(str);
@@ -4064,7 +4066,7 @@ str_gsub(int argc, VALUE *argv, VALUE st https://github.com/ruby/ruby/blob/trunk/string.c#L4066
 	regs = RMATCH_REGS(match);
 	beg0 = BEG(0);
 	end0 = END(0);
-	if (iter || !NIL_P(hash)) {
+	if (!str_replace) {
             if (iter) {
                 val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match)));
             }
@@ -4104,7 +4106,7 @@ str_gsub(int argc, VALUE *argv, VALUE st https://github.com/ruby/ruby/blob/trunk/string.c#L4106
 	}
 	cp = RSTRING_PTR(str) + offset;
 	if (offset > RSTRING_LEN(str)) break;
-	beg = rb_reg_search(pat, str, offset, 0);
+	beg = rb_reg_search0(pat, str, offset, 0, !str_replace);
     } while (beg >= 0);
     if (RSTRING_LEN(str) > offset) {
         rb_enc_str_buf_cat(dest, cp, RSTRING_LEN(str) - offset, str_enc);
Index: internal.h
===================================================================
--- internal.h	(revision 45413)
+++ internal.h	(revision 45414)
@@ -978,6 +978,9 @@ VALUE rb_gcd_normal(VALUE self, VALUE ot https://github.com/ruby/ruby/blob/trunk/internal.h#L978
 VALUE rb_gcd_gmp(VALUE x, VALUE y);
 #endif
 
+/* re.c */
+long rb_reg_search0(VALUE, VALUE, long, int, int);
+
 /* util.c */
 extern const signed char ruby_digit36_to_number_table[];
 

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

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