[#15359] Timeout::Error — Jeremy Thurgood <jerith@...>

Good day,

41 messages 2008/02/05
[#15366] Re: Timeout::Error — Eric Hodel <drbrain@...7.net> 2008/02/06

On Feb 5, 2008, at 06:20 AM, Jeremy Thurgood wrote:

[#15370] Re: Timeout::Error — Jeremy Thurgood <jerith@...> 2008/02/06

Eric Hodel wrote:

[#15373] Re: Timeout::Error — Nobuyoshi Nakada <nobu@...> 2008/02/06

Hi,

[#15374] Re: Timeout::Error — Jeremy Thurgood <jerith@...> 2008/02/06

Nobuyoshi Nakada wrote:

[#15412] Re: Timeout::Error — Nobuyoshi Nakada <nobu@...> 2008/02/07

Hi,

[#15413] Re: Timeout::Error — Jeremy Thurgood <jerith@...> 2008/02/07

Nobuyoshi Nakada wrote:

[#15414] Re: Timeout::Error — Nobuyoshi Nakada <nobu@...> 2008/02/07

Hi,

[#15360] reopen: can't change access mode from "w+" to "w"? — Sam Ruby <rubys@...>

I ran 'rake test' on test/spec [1], using

16 messages 2008/02/05
[#15369] Re: reopen: can't change access mode from "w+" to "w"? — Nobuyoshi Nakada <nobu@...> 2008/02/06

Hi,

[#15389] STDIN encoding differs from default source file encoding — Dave Thomas <dave@...>

This seems strange:

21 messages 2008/02/06
[#15392] Re: STDIN encoding differs from default source file encoding — Yukihiro Matsumoto <matz@...> 2008/02/06

Hi,

[#15481] very bad character performance on ruby1.9 — "Eric Mahurin" <eric.mahurin@...>

I'd like to bring up the issue of how characters are represented in

16 messages 2008/02/10

[#15528] Test::Unit maintainer — Kouhei Sutou <kou@...>

Hi Nathaniel, Ryan,

22 messages 2008/02/13

[#15551] Proc#curry — ts <decoux@...>

21 messages 2008/02/14
[#15557] Re: [1.9] Proc#curry — David Flanagan <david@...> 2008/02/15

ts wrote:

[#15558] Re: [1.9] Proc#curry — Yukihiro Matsumoto <matz@...> 2008/02/15

Hi,

[#15560] Re: Proc#curry — Trans <transfire@...> 2008/02/15

[#15585] Ruby M17N meeting summary — Martin Duerst <duerst@...>

This is a rough translation of the Japanese meeting summary

19 messages 2008/02/18

[#15596] possible bug in regexp lexing — Ryan Davis <ryand-ruby@...>

current:

17 messages 2008/02/19

[#15678] Re: [ANN] MacRuby — "Rick DeNatale" <rick.denatale@...>

On 2/27/08, Laurent Sansonetti <laurent.sansonetti@gmail.com> wrote:

18 messages 2008/02/28
[#15679] Re: [ANN] MacRuby — "Laurent Sansonetti" <laurent.sansonetti@...> 2008/02/28

On Thu, Feb 28, 2008 at 6:33 AM, Rick DeNatale <rick.denatale@gmail.com> wrote:

[#15680] Re: [ANN] MacRuby — Yukihiro Matsumoto <matz@...> 2008/02/28

Hi,

[#15683] Re: [ANN] MacRuby — "Laurent Sansonetti" <laurent.sansonetti@...> 2008/02/28

On Thu, Feb 28, 2008 at 1:51 PM, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

Re: string[0..-1] no longer uses copy on write

From: Nobuyoshi Nakada <nobu@...>
Date: 2008-02-07 06:10:41 UTC
List: ruby-core #15407
Hi,

At Thu, 7 Feb 2008 11:17:08 +0900,
Daniel DeLorme wrote in [ruby-core:15400]:
> As the subject states, in 1.8 string[0..-1] used copy on write but in 
> 1.9 it does not, i.e.

> Should that be considered a bug?

It works as expected, so may not be called a bug.

> On a related topic, why is copy on write not used for String#dup ?

I also have wondered about it.

This patch allows associated strings to be shared too.


Index: string.c
===================================================================
--- string.c	(revision 15392)
+++ string.c	(working copy)
@@ -346,8 +346,6 @@ rb_tainted_str_new2(const char *ptr)
 
 static VALUE
-str_new_shared(VALUE klass, VALUE str)
+str_replace_shared(VALUE str2, VALUE str)
 {
-    VALUE str2 = str_alloc(klass);
-
     if (RSTRING_LEN(str) <= RSTRING_EMBED_LEN_MAX) {
 	STR_SET_EMBED(str2);
@@ -367,4 +365,10 @@ str_new_shared(VALUE klass, VALUE str)
 
 static VALUE
+str_new_shared(VALUE klass, VALUE str)
+{
+    return str_replace_shared(str_alloc(klass), str);
+}
+
+static VALUE
 str_new3(VALUE klass, VALUE str)
 {
@@ -413,22 +417,30 @@ rb_str_new4(VALUE orig)
     if (OBJ_FROZEN(orig)) return orig;
     klass = rb_obj_class(orig);
-    if (STR_SHARED_P(orig) && (str = RSTRING(orig)->as.heap.aux.shared)
-	&& klass == RBASIC(str)->klass) {
+    if (STR_SHARED_P(orig) && (str = RSTRING(orig)->as.heap.aux.shared)) {
 	long ofs;
 	ofs = RSTRING_LEN(str) - RSTRING_LEN(orig);
-	if ((ofs > 0) || (!OBJ_TAINTED(str) && OBJ_TAINTED(orig))) {
+	if ((ofs > 0) || (klass != RBASIC(str)->klass) ||
+	    (!OBJ_TAINTED(str) && OBJ_TAINTED(orig))) {
 	    str = str_new3(klass, str);
 	    RSTRING(str)->as.heap.ptr += ofs;
 	    RSTRING(str)->as.heap.len -= ofs;
 	}
+	OBJ_INFECT(str, orig);
     }
-    else if (STR_ASSOC_P(orig) || STR_EMBED_P(orig)) {
+    else if (STR_EMBED_P(orig)) {
 	str = str_new(klass, RSTRING_PTR(orig), RSTRING_LEN(orig));
 	rb_enc_copy(str, orig);
+	OBJ_INFECT(str, orig);
+    }
+    else if (STR_ASSOC_P(orig)) {
+	VALUE assoc = RSTRING(orig)->as.heap.aux.shared;
+	FL_UNSET(orig, STR_ASSOC);
+	str = str_new4(klass, orig);
+	FL_SET(str, STR_ASSOC);
+	RSTRING(str)->as.heap.aux.shared = assoc;
     }
     else {
 	str = str_new4(klass, orig);
     }
-    OBJ_INFECT(str, orig);
     OBJ_FREEZE(str);
     return str;
@@ -553,7 +565,5 @@ VALUE
 rb_str_dup(VALUE str)
 {
-    VALUE dup = str_alloc(rb_obj_class(str));
-    rb_str_replace(dup, str);
-    return dup;
+    return rb_str_new3(str);
 }
 
@@ -778,12 +788,21 @@ void
 rb_str_associate(VALUE str, VALUE add)
 {
+    /* sanity check */
+    if (OBJ_FROZEN(str)) rb_error_frozen("string");
     if (STR_ASSOC_P(str)) {
-	/* sanity check */
-	if (OBJ_FROZEN(str)) rb_error_frozen("string");
 	/* already associated */
 	rb_ary_concat(RSTRING(str)->as.heap.aux.shared, add);
     }
     else {
-	if (STR_SHARED_P(str) || STR_EMBED_P(str)) {
+	if (STR_SHARED_P(str)) {
+	    VALUE assoc = RSTRING(str)->as.heap.aux.shared;
+	    str_make_independent(str);
+	    if (STR_ASSOC_P(assoc)) {
+		assoc = RSTRING(assoc)->as.heap.aux.shared;
+		rb_ary_concat(assoc, add);
+		add = assoc;
+	    }
+	}
+	else if (STR_EMBED_P(str)) {
 	    str_make_independent(str);
 	}
@@ -800,8 +819,7 @@ VALUE
 rb_str_associated(VALUE str)
 {
+    if (STR_SHARED_P(str)) str = RSTRING(str)->as.heap.aux.shared;
     if (STR_ASSOC_P(str)) {
-	VALUE ary = RSTRING(str)->as.heap.aux.shared;
-	if (OBJ_FROZEN(str)) OBJ_FREEZE(ary);
-	return ary;
+	return RSTRING(str)->as.heap.aux.shared;
     }
     return Qfalse;
@@ -966,7 +984,15 @@ rb_str_substr(VALUE str, long beg, long 
     }
   sub:
-    str2 = rb_str_new5(str, p, len);
-    rb_enc_copy(str2, str);
-    OBJ_INFECT(str2, str);
+    if (len > RSTRING_EMBED_LEN_MAX && beg + len == RSTRING_LEN(str)) {
+	str2 = rb_str_new4(str);
+	str2 = str_new3(rb_obj_class(str2), str2);
+	RSTRING(str2)->as.heap.ptr += RSTRING(str2)->as.heap.len - len;
+	RSTRING(str2)->as.heap.len = len;
+    }
+    else {
+	str2 = rb_str_new5(str, p, len);
+	rb_enc_copy(str2, str);
+	OBJ_INFECT(str2, str);
+    }
 
     return str2;
@@ -1180,5 +1206,5 @@ rb_enc_cr_str_buf_cat(VALUE str, const c
         str_cr != ENC_CODERANGE_7BIT &&
         ptr_cr != ENC_CODERANGE_7BIT) {
-incompatible:
+      incompatible:
         rb_raise(rb_eArgError, "append incompatible encoding strings: %s and %s",
             rb_enc_name(rb_enc_from_index(str_encindex)),
@@ -3006,4 +3032,7 @@ rb_str_replace(VALUE str, VALUE str2)
     StringValue(str2);
     len = RSTRING_LEN(str2);
+    if (STR_ASSOC_P(str2)) {
+	str2 = rb_str_new4(str2);
+    }
     if (STR_SHARED_P(str2)) {
 	if (str_independent(str) && !STR_EMBED_P(str)) {
@@ -3017,16 +3046,7 @@ rb_str_replace(VALUE str, VALUE str2)
 	RSTRING(str)->as.heap.aux.shared = RSTRING(str2)->as.heap.aux.shared;
     }
-    else if (STR_ASSOC_P(str2)) {
-	rb_str_modify(str);
-	STR_SET_NOEMBED(str);
-	RSTRING(str)->as.heap.ptr = ALLOC_N(char,len+1);
-	memcpy(RSTRING_PTR(str), RSTRING_PTR(str2), len+1);
-	FL_SET(str, STR_ASSOC);
-	RSTRING(str)->as.heap.aux.shared = RSTRING(str2)->as.heap.aux.shared;
-    }
     else {
 	rb_str_modify(str);
-	rb_str_resize(str, len);
-	memcpy(RSTRING_PTR(str), RSTRING_PTR(str2), len+1);
+	str_replace_shared(str, str2);
     }
 


-- 
Nobu Nakada

In This Thread