www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 13854] New: Appending to an interior slice of a large array


          Issue ID: 13854
           Summary: Appending to an interior slice of a large array
                    results in unnecessary 16-byte offset
           Product: D
           Version: D2
          Hardware: x86
                OS: All
            Status: NEW
          Severity: normal
          Priority: P1
         Component: druntime
          Assignee: schveiguy yahoo.com
          Reporter: schveiguy yahoo.com

When appending to a small non-appendable slice of a large array (PAGESIZE or
bigger), the runtime may extend, but will reallocate if it cannot.

On the reallocation, it mistakenly assumes the new array is also PAGESIZE or
bigger, when figuring out the padding and offset.

It should do the padding based on the new size, not the old size. Note, the
allocated array length is properly stored, so at least it will not corrupt
data. Just the first 16 bytes of the block are wasted.

Example code:

import std.stdio;
import core.memory;

void main()
    ubyte[] x = new ubyte[2048]; // ensure page size at least
    assert(x.ptr - GC.addrOf(x.ptr) == 16); // 16 byte offset is required for
storing offset
    x.length = 1; // make x not appendable due to stomping
    x ~= 0;
    assert(x.length == 2);
    assert(x.ptr == GC.addrOf(x.ptr)); // 16 byte offset shouldn't be here!

In the current version, the final assert triggers, but should not in a correct
implementation (will add this as a unit test).

Dec 11 2014