ruby-changes:3905
From: ko1@a...
Date: Thu, 7 Feb 2008 16:34:19 +0900 (JST)
Subject: [ruby-changes:3905] nobu - Ruby:r15395 (trunk): * string.c (str_replace_shared): replaces string with sharing.
nobu 2008-02-07 16:33:50 +0900 (Thu, 07 Feb 2008)
New Revision: 15395
Modified files:
trunk/ChangeLog
trunk/string.c
Log:
* string.c (str_replace_shared): replaces string with sharing.
* string.c (rb_str_new4, rb_str_associate, rb_str_associated): allows
associated strings shared.
* string.c (rb_str_dup, rb_str_substr, rb_str_replace): shares memory.
[ruby-core:15400]
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/string.c?r1=15395&r2=15394&diff_format=u
http://svn.ruby-lang.org/cgi-bin/viewvc.cgi/trunk/ChangeLog?r1=15395&r2=15394&diff_format=u
Index: ChangeLog
===================================================================
--- ChangeLog (revision 15394)
+++ ChangeLog (revision 15395)
@@ -1,3 +1,13 @@
+Thu Feb 7 16:33:48 2008 Nobuyoshi Nakada <nobu@r...>
+
+ * string.c (str_replace_shared): replaces string with sharing.
+
+ * string.c (rb_str_new4, rb_str_associate, rb_str_associated): allows
+ associated strings shared.
+
+ * string.c (rb_str_dup, rb_str_substr, rb_str_replace): shares memory.
+ [ruby-core:15400]
+
Thu Feb 7 15:42:42 2008 Nobuyoshi Nakada <nobu@r...>
* string.c (rb_str_end_with): compares with the suffix.
Index: string.c
===================================================================
--- string.c (revision 15394)
+++ string.c (revision 15395)
@@ -345,10 +345,8 @@
}
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);
memcpy(RSTRING_PTR(str2), RSTRING_PTR(str), RSTRING_LEN(str)+1);
@@ -366,6 +364,12 @@
}
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)
{
VALUE str2 = str_new_shared(klass, str);
@@ -412,24 +416,32 @@
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;
}
@@ -552,9 +564,7 @@
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);
}
@@ -777,16 +787,25 @@
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);
+ }
else if (RSTRING(str)->as.heap.aux.capa != RSTRING_LEN(str)) {
RESIZE_CAPA(str, RSTRING_LEN(str));
}
@@ -799,10 +818,9 @@
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;
}
@@ -965,9 +983,17 @@
len = str_offset(p, e, len, enc, singlebyte);
}
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;
}
@@ -1179,7 +1205,7 @@
if (str_encindex != ptr_encindex &&
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)),
rb_enc_name(rb_enc_from_index(ptr_encindex)));
@@ -3005,6 +3031,9 @@
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)) {
free(RSTRING_PTR(str));
@@ -3016,18 +3045,9 @@
FL_UNSET(str, STR_ASSOC);
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);
}
OBJ_INFECT(str, str2);
--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/