Changes to the Tango runtime / GC
Robert Fraser
fraserofthenight at gmail.com
Sat Oct 13 11:59:13 PDT 2007
Sean Kelly Wrote:
> All the recent talk about the GC inspired me to make some changes that
> I'd been planning for Tango. I wanted to post about them here to make
> sure everyone was aware of them because they are silent changes that
> could affect the reliability of a program in certain rare circumstances.
> Previously, the Tango runtime worked just like the Phobos runtime in
> that the hasPointers flag was set or cleared on array operations based
> on the type of the variable referencing the underlying memory. For example:
>
> byte[] b = cast(byte[]) new void[5]; // hasPointers is set
> byte[] c = b[1 .. $];
>
> b.length = 10; // hasPointers is retained because no realloc occurs
> b.length = 20; // hasPointers is lost/cleared because of a realloc
>
> c.length = 1; // hasPointers is lost/cleared--slices always realloc
> c.length = 20; // hasPointers is lost/cleared for same reason as above
>
> The opposite was also true:
>
> void[] v = new byte[5]; // hasPointers is not set
> void[] w = v[1 .. $];
>
> v.length = 10; // hasPointers is still 0 because no realloc occurs
> v.length = 20; // hasPointers is set because of a realloc
>
> w.length = 1; // hasPointers is set because slices always realloc
> w.length = 20; // hasPointers is set for same reason as above
>
> The new behavior of Tango is to preserve block attributes for any
> allocated block whose size is simply changing as the result of an array
> operation. *** This is true of both slices and normal arrays. *** For
> example:
>
> byte[] b = cast(byte[]) new void[5]; // hasPointers is set
> byte[] c = b[1 .. $];
>
> b.length = 10; // hasPointers is retained because no realloc occurs
> b.length = 20; // hasPointers is retained because of new logic
>
> c.length = 1; // hasPointers is retained because of new logic
> c.length = 20; // hasPointers is retained because of new logic
>
> The same behavior is true of void references to byte arrays. Here is a
> quick run-down of more complex cases:
>
> byte[] b = cast(byte[]) new void[5];
>
> b ~= 0; // hasPointers is preserved on realloc
> b ~= [0,1,2]; // hasPointers is preserved on realloc
> b = [0,1] ~ [2]; // hasPointers is not retained - A
>
> b = null;
> b.length = 10; // hasPointers is lost because reference was cleared
>
> In situation A above, hasPointers is not retained because the operation
> is an assignment rather than a resize.
>
> I believe these changes will result in more predictable behavior than
> before. However, they can cause a change in program behavior in rare cases:
>
> void[] getBlock()
> {
> return new byte[32];
> }
>
> With the old behavior, manipulating the block returned by getBlock in a
> way that caused a reallocation to occur would result in hasPointers
> being set on that block. With the new behavior, hasPointers would not
> be set because the runtime would be preserving the bits set on the
> original block, which was allocated as a byte[]. Thus it's possible in
> certain degenerate cases that the bits set on a memory block could
> silently propagate and "poison" an application in instances where they
> were discarded before.
>
>
> Sean
So, wait, under this new regime, there will be *more* chances of random data causing memory leaks?
More information about the Digitalmars-d
mailing list