www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 19013] New: Allocation of array that has indirections makes


          Issue ID: 19013
           Summary: Allocation of array that has indirections makes
                    incorrect assumption about zeroing
           Product: D
           Version: D2
          Hardware: All
                OS: All
            Status: NEW
          Severity: minor
          Priority: P1
         Component: druntime
          Assignee: nobody puremagic.com
          Reporter: schveiguy yahoo.com

I'm not sure this is super-relevant, but when allocating a block for storing
array elements with indirections, the GC zeroes out what it thinks are the
bytes that are not going to be used in the allocation.

However, the array runtime is clever and allocates enough space to hold the
elements plus the array length. For small blocks, the way the array length
works, it's stored at the end of the block.

This means that for example, a 16-byte block, one byte is requested for length.
If you are allocating 8 bytes, this means you request 9 bytes. To the GC, this
means it needs to zero the last 7 bytes. If we assume the bit-pattern for the
garbage is 0xff, we have the following progression (in groups of 4 bytes

ff_ff_ff_ff ff_ff_ff_ff ff_ff_ff_ff ff_ff_ff_ff // block data originally
ff_ff_ff_ff ff_ff_ff_ff ff_00_00_00 00_00_00_00 // GC initializes "unused" data
00_00_00_00 00_00_00_00 ff_00_00_00 00_00_00_00 // runtime initializes array
00_00_00_00 00_00_00_00 ff_00_00_00 00_00_00_08 // runtime sets "used" length
to 8

So that weird ff pattern in the middle is an artifact of this procedure.

How much will this affect the GC? Probably not a lot. First, the number of
bytes that are "garbage" is going to be 1 or 2 bytes. This covers all block
sizes up to 2048 bytes. In the cases of 4096 bytes or larger, the array length
is a size_t, and is stored at the front, so there should be no garbage. Only 1
or 2 bytes could have an effect, but likely very small as it will be combined
with other 0 bytes around it. On little endian systems, they will likely be the
least significant bytes, so they probably will point at non-GC memory. But
there is still a chance of odd things happening here.

I wanted to file this bug to ensure that the behavior is documented.

Jun 21 2018