Index: src/OFMutableString_UTF8.h ================================================================== --- src/OFMutableString_UTF8.h +++ src/OFMutableString_UTF8.h @@ -13,12 +13,14 @@ * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this * file. */ #import "OFMutableString.h" +#import "OFString_UTF8.h" @interface OFMutableString_UTF8: OFMutableString { @public struct of_string_utf8_ivars *restrict s; + struct of_string_utf8_ivars s_store; } @end Index: src/OFString_UTF8.h ================================================================== --- src/OFString_UTF8.h +++ src/OFString_UTF8.h @@ -17,15 +17,23 @@ #import "OFString.h" @interface OFString_UTF8: OFString { @public + /* + * A pointer to the actual data. + * + * Since constant strings don't have s_store, they have to malloc it on + * the first access. Strings created at runtime just set the pointer to + * &s_store. + */ struct of_string_utf8_ivars { char *cString; size_t cStringLength; BOOL UTF8; size_t length; BOOL hashed; uint32_t hash; } *restrict s; + struct of_string_utf8_ivars s_store; } @end Index: src/OFString_UTF8.m ================================================================== --- src/OFString_UTF8.m +++ src/OFString_UTF8.m @@ -62,12 +62,11 @@ - init { self = [super init]; @try { - s = [self allocMemoryWithSize: sizeof(*s)]; - memset(s, 0, sizeof(*s)); + s = &s_store; s->cString = [self allocMemoryWithSize: 1]; s->cString[0] = '\0'; } @catch (id e) { [self release]; @@ -91,12 +90,11 @@ cStringLength >= 3 && !memcmp(cString, "\xEF\xBB\xBF", 3)) { cString += 3; cStringLength -= 3; } - s = [self allocMemoryWithSize: sizeof(*s)]; - memset(s, 0, sizeof(*s)); + s = &s_store; s->cString = [self allocMemoryWithSize: cStringLength + 1]; s->cStringLength = cStringLength; if (encoding == OF_STRING_ENCODING_UTF_8 || @@ -212,12 +210,11 @@ - initWithString: (OFString*)string { self = [super init]; @try { - s = [self allocMemoryWithSize: sizeof(*s)]; - memset(s, 0, sizeof(*s)); + s = &s_store; s->cStringLength = [string UTF8StringLength]; if ([string isKindOfClass: [OFString_UTF8 class]] || [string isKindOfClass: [OFMutableString_UTF8 class]]) @@ -255,12 +252,11 @@ string++; length--; } else if (byteOrder != OF_ENDIANESS_NATIVE) swap = YES; - s = [self allocMemoryWithSize: sizeof(*s)]; - memset(s, 0, sizeof(*s)); + s = &s_store; s->cStringLength = length; s->cString = [self allocMemoryWithSize: (length * 4) + 1]; s->length = length; @@ -338,12 +334,11 @@ string++; length--; } else if (byteOrder != OF_ENDIANESS_NATIVE) swap = YES; - s = [self allocMemoryWithSize: sizeof(*s)]; - memset(s, 0, sizeof(*s)); + s = &s_store; s->cStringLength = length; s->cString = [self allocMemoryWithSize: (length * 4) + 1]; s->length = length; @@ -441,12 +436,11 @@ if (format == nil) @throw [OFInvalidArgumentException exceptionWithClass: isa selector: _cmd]; - s = [self allocMemoryWithSize: sizeof(*s)]; - memset(s, 0, sizeof(*s)); + s = &s_store; if ((cStringLength = of_vasprintf(&tmp, [format UTF8String], arguments)) == -1) @throw [OFInvalidFormatException exceptionWithClass: isa]; @@ -486,12 +480,11 @@ @try { OFString *component; size_t i, cStringLength; va_list argumentsCopy; - s = [self allocMemoryWithSize: sizeof(*s)]; - memset(s, 0, sizeof(*s)); + s = &s_store; s->cStringLength = [firstComponent UTF8StringLength]; if ([firstComponent isKindOfClass: [OFString_UTF8 class]] || [firstComponent isKindOfClass: