# New Ticket Created by Leopold Toetsch # Please include the string: [perl #17703] # in the subject line of all future correspondence about this issue. # <URL: http://rt.perl.org/rt2/Ticket/Display.html?id=17703 >
Description of patch by chunks: - remove outdated comment/ifdef - use Parrot_allocate_string in unmake_COW. The currently used method is not wrong, but hides, that Parrot_reallocate_string in alloc/copy internally. Also resets BUFFER_external_flag, which was set for COWed constants. - save some cycles in strlen - string_to_cstring returned (Peter) highly volatile pointers. Please apply, leo -- attachment 1 ------------------------------------------------------ url: http://rt.perl.org/rt2/attach/38995/31667/629f2d/string_c.patch
--- parrot/string.c Sun Sep 15 15:30:59 2002 +++ parrot-leo/string.c Tue Oct 1 08:29:04 2002 @@ -18,32 +18,31 @@ #define EXTRA_SIZE 4 /* String COW support */ + +/* make a copy of string's data: + * copy used string data from strstart to a newly + * allocated string + * the header stays the same + */ static void unmake_COW(struct Parrot_Interp *interpreter, STRING *s) { -#if 0 - if (s->flags & BUFFER_constant_FLAG) { - /* this happens when we call string_to_cstring on - * a constant string in order to print it - */ - internal_exception(INVALID_OPERATION, - "Cannot unmake COW on a constant header"); - } - else -#endif if (s->flags & (BUFFER_COW_FLAG|BUFFER_constant_FLAG)) { + void *p; + UINTVAL size; interpreter->GC_block_level++; interpreter->DOD_block_level++; /* Make the copy point to only the portion of the string that * we are actually using. */ - s->bufstart = s->strstart; - s->buflen = s->bufused; - + p = s->strstart; + size = s->bufused; /* Create new pool data for this header to use, * independant of the original COW data */ - Parrot_reallocate_string(interpreter, s, s->buflen); - s->flags &= ~(UINTVAL)(BUFFER_COW_FLAG | BUFFER_constant_FLAG); + Parrot_allocate_string(interpreter, s, s->buflen); + mem_sys_memcopy(s->bufstart, p, size); + s->flags &= ~(UINTVAL)(BUFFER_COW_FLAG | BUFFER_constant_FLAG | + BUFFER_external_FLAG); interpreter->GC_block_level--; interpreter->DOD_block_level--; } @@ -399,8 +398,7 @@ INTVAL string_compute_strlen(STRING *s) { - s->strlen = s->encoding->characters(s->bufstart, s->bufused) - - ((UINTVAL)s->strstart - (UINTVAL)s->bufstart); + s->strlen = s->encoding->characters(s->strstart, s->bufused); return s->strlen; } @@ -972,13 +970,6 @@ const char * string_to_cstring(struct Parrot_Interp * interpreter, STRING * s) { - char *cstring; - - /* We shouldn't modify a constant string, - * so instead create a new copy of it */ - if (s->flags & BUFFER_constant_FLAG) { - s = make_COW_reference(interpreter,s); - } unmake_COW(interpreter, s); @@ -986,11 +977,9 @@ string_grow(interpreter, s, 1); } - cstring = s->strstart; - - cstring[s->bufused] = 0; - - return cstring; + ((char *)s->strstart)[s->bufused] = 0; + /* don't return local vars, return the right thing */ + return (char*)s->strstart; }