[Issue 14126] GITHEAD - GC seemingly corrupting memory
via Digitalmars-d-bugs
digitalmars-d-bugs at puremagic.com
Fri Feb 6 07:18:58 PST 2015
https://issues.dlang.org/show_bug.cgi?id=14126
Steven Schveighoffer <schveiguy at yahoo.com> changed:
What |Removed |Added
----------------------------------------------------------------------------
CC| |schveiguy at yahoo.com
Assignee|nobody at puremagic.com |schveiguy at yahoo.com
--- Comment #14 from Steven Schveighoffer <schveiguy at yahoo.com> ---
(In reply to Ketmar Dark from comment #11)
> seems that the bug is due to the code in `lifetime.d:finalize_array2()`.
>
> for big blocks (those which are bigger or equal to PAGESIZE), it does this:
> `p += LARGEPAD;`, and LARGEPAD is:
>
> LARGEPREFIX = 16, // 16 bytes padding at the front of the array
> LARGEPAD = LARGEPREFIX + 1,
>
> seems that LARGEPAD must be used only in overall block size calculations,
> but not as real padding (real padding is LARGEPREFIX in this case).
>
> yet i'm not an expert in D memory management, so i can't say if i'm really
> right here. fixing `lifetime.d:finalize_array2()` to use `LARGEPREFIX`
> instead seems to fix the bug. and hey, why anoyone would use 17-byte PREFIX
> padding anyway?
This is exactly the problem. The + 1 is used to determine overall size of array
allocation. The +1 is the sentinel byte added to the end of the block to
prevent cross-block referencing.
For example, imagine you had a block of 16 bytes:
ubyte[] x = new ubyte[16];
If you put this into an exact block of 16 bytes, then did this:
x = x[$..$];
Now x.ptr is technically referring to the NEXT block in memory. That's why the
sentinel is used. For smaller blocks, the sentinel is really the array 'used'
size, but for larger blocks that can be extended, we put the 'used' size at the
beginning. The resulting data must be 16-byte aligned, so we skip ahead 16
bytes (LARGEPREFIX), and we add 1 byte to the end to prevent cross-block
issues.
I will generate a PR.
--
More information about the Digitalmars-d-bugs
mailing list