[Mono-dev] Getting rid of String.InternalSetLength
lupus at ximian.com
Fri Dec 4 10:28:02 EST 2009
On 12/03/09 Mark Probst wrote:
> SGen, our new garbage collector, doesn't explicitly store an object's
> size but determines it via the object's vtable and, in the case of
> arrays and strings, via the length field. String.InternalSetLength
> changes that length field, which means that, from SGen's view, the
> string's size changes. That's a problem because depending on an
> object's size it is either stored in a regular heap section or, if it
> is larger than a certain threshold, in the large object section (LOS).
> SGen depends on being able to distinguish between the two, so it must
> not happen that an object changes size, i.e. we have to get rid of
> String.InternalSetLength, which is used by StringBuilder.
> The attached patch fixes this problem, but of course it has to do more
> copying. Does anybody object to this? Any alternatives?
Good catch for this issue.
I think we should keep the optimization. To fix it it should be enough
to add a check for the problematic case: if setting the new length would
change the storage space, the copy codepath is taken instead.
Let's have this in String.cs:
static readonly int LOS_length = GetLOSLength (); // icall optimized by the jit to a constant.
and then you can have:
> --- System.Text/StringBuilder.cs (revision 147553)
> +++ System.Text/StringBuilder.cs (working copy)
> @@ -207,8 +207,7 @@
> if (null != _cached_str)
> return _cached_str;
> - // If we only have a half-full buffer we return a new string.
> - if (_length < (_str.Length >> 1))
> + if (_length < (_str.Length >> 1) || (_str.Length >= string.LOS_length && _length < string.LOS_length))
> // use String.SubstringUnchecked instead of String.Substring
> // as the former is guaranteed to create a new string object
lupus at debian.org debian/rules
lupus at ximian.com Monkeys do it better
More information about the Mono-devel-list