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

ruby-changes:16832

From: nobu <ko1@a...>
Date: Sun, 1 Aug 2010 23:04:54 +0900 (JST)
Subject: [ruby-changes:16832] Ruby:r28827 (trunk): * string.c (rb_str_modify_expand, rb_str_resize): get rid of

nobu	2010-08-01 23:04:39 +0900 (Sun, 01 Aug 2010)

  New Revision: 28827

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

  Log:
    * string.c (rb_str_modify_expand, rb_str_resize): get rid of
      repeating malloc and realloc.

  Modified files:
    trunk/ChangeLog
    trunk/string.c

Index: ChangeLog
===================================================================
--- ChangeLog	(revision 28826)
+++ ChangeLog	(revision 28827)
@@ -1,3 +1,8 @@
+Sun Aug  1 23:04:35 2010  Nobuyoshi Nakada  <nobu@r...>
+
+	* string.c (rb_str_modify_expand, rb_str_resize): get rid of
+	  repeating malloc and realloc.
+
 Sun Aug  1 22:16:30 2010  Kenta Murata  <mrkn@m...>
 
 	* ext/bigdecimal/bigdecimal.c (BigDecimal_hash): use rb_memhash and
Index: string.c
===================================================================
--- string.c	(revision 28826)
+++ string.c	(revision 28827)
@@ -1264,12 +1264,12 @@
 }
 
 static void
-str_make_independent(VALUE str)
+str_make_independent_expand(VALUE str, long expand)
 {
     char *ptr;
     long len = RSTRING_LEN(str);
 
-    ptr = ALLOC_N(char, len+1);
+    ptr = ALLOC_N(char, len+expand+1);
     if (RSTRING_PTR(str)) {
 	memcpy(ptr, RSTRING_PTR(str), len);
     }
@@ -1281,6 +1281,8 @@
     STR_UNSET_NOCAPA(str);
 }
 
+#define str_make_independent(str) str_make_independent_expand(str, 0L)
+
 void
 rb_str_modify(VALUE str)
 {
@@ -1289,6 +1291,21 @@
     ENC_CODERANGE_CLEAR(str);
 }
 
+void
+rb_str_modify_expand(VALUE str, long expand)
+{
+    if (expand < 0) {
+	rb_raise(rb_eArgError, "negative expanding string size");
+    }
+    if (!str_independent(str) ||
+	(expand > 0 &&
+	 (!STR_EMBED_P(str) ||
+	  RSTRING_LEN(str) + expand > RSTRING_EMBED_LEN_MAX))) {
+	str_make_independent_expand(str, expand);
+    }
+    ENC_CODERANGE_CLEAR(str);
+}
+
 /* As rb_str_modify(), but don't clear coderange */
 static void
 str_modify_keep_cr(VALUE str)
@@ -1684,24 +1701,23 @@
 rb_str_resize(VALUE str, long len)
 {
     long slen;
+    int independent;
 
     if (len < 0) {
 	rb_raise(rb_eArgError, "negative string size (or size too big)");
     }
 
-    rb_str_modify(str);
+    independent = str_independent(str);
+    ENC_CODERANGE_CLEAR(str);
     slen = RSTRING_LEN(str);
     if (len != slen) {
 	if (STR_EMBED_P(str)) {
-	    char *ptr;
 	    if (len <= RSTRING_EMBED_LEN_MAX) {
 		STR_SET_EMBED_LEN(str, len);
 		RSTRING(str)->as.ary[len] = '\0';
 		return str;
 	    }
-	    ptr = ALLOC_N(char,len+1);
-	    MEMCPY(ptr, RSTRING(str)->as.ary, char, slen);
-	    RSTRING(str)->as.heap.ptr = ptr;
+	    str_make_independent_expand(str, len - slen);
 	    STR_SET_NOEMBED(str);
 	}
 	else if (len <= RSTRING_EMBED_LEN_MAX) {
@@ -1710,9 +1726,12 @@
 	    if (slen > 0) MEMCPY(RSTRING(str)->as.ary, ptr, char, len);
 	    RSTRING(str)->as.ary[len] = '\0';
 	    STR_SET_EMBED_LEN(str, len);
-	    xfree(ptr);
+	    if (independent) xfree(ptr);
 	    return str;
 	}
+	else if (!independent) {
+	    str_make_independent_expand(str, len - slen);
+	}
 	else if (slen < len || slen - len > 1024) {
 	    REALLOC_N(RSTRING(str)->as.heap.ptr, char, len+1);
 	}
@@ -1794,12 +1813,12 @@
 	rb_raise(rb_eArgError, "negative string size (or size too big)");
     }
     if (STR_ASSOC_P(str)) {
-	rb_str_modify(str);
-	if (STR_EMBED_P(str)) str_make_independent(str);
-	REALLOC_N(RSTRING(str)->as.heap.ptr, char, RSTRING(str)->as.heap.len+len+1);
-	memcpy(RSTRING(str)->as.heap.ptr + RSTRING(str)->as.heap.len, ptr, len);
-	RSTRING(str)->as.heap.len += len;
-	RSTRING(str)->as.heap.ptr[RSTRING(str)->as.heap.len] = '\0'; /* sentinel */
+	char *p;
+	rb_str_modify_expand(str, len);
+	p = RSTRING(str)->as.heap.ptr;
+	memcpy(p + RSTRING(str)->as.heap.len, ptr, len);
+	len = RSTRING(str)->as.heap.len += len;
+	p[len] = '\0'; /* sentinel */
 	return str;
     }
 
@@ -1951,17 +1970,17 @@
 {
     rb_encoding *enc;
     int cr, cr2;
+    long len2;
 
     StringValue(str2);
-    if (RSTRING_LEN(str2) > 0 && STR_ASSOC_P(str)) {
-        long len = RSTRING_LEN(str)+RSTRING_LEN(str2);
+    if ((len2 = RSTRING_LEN(str2)) > 0 && STR_ASSOC_P(str)) {
+        long len = RSTRING_LEN(str) + len2;
         enc = rb_enc_check(str, str2);
         cr = ENC_CODERANGE(str);
         if ((cr2 = ENC_CODERANGE(str2)) > cr) cr = cr2;
-        rb_str_modify(str);
-        REALLOC_N(RSTRING(str)->as.heap.ptr, char, len+1);
+        rb_str_modify_expand(str, len2);
         memcpy(RSTRING(str)->as.heap.ptr + RSTRING(str)->as.heap.len,
-               RSTRING_PTR(str2), RSTRING_LEN(str2)+1);
+               RSTRING_PTR(str2), len2+1);
         RSTRING(str)->as.heap.len = len;
         rb_enc_associate(str, enc);
         ENC_CODERANGE_SET(str, cr);

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

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