[Issue 13854] New: Appending to an interior slice of a large array results in unnecessary 16-byte offset

via Digitalmars-d-bugs digitalmars-d-bugs at puremagic.com
Thu Dec 11 11:37:44 PST 2014


https://issues.dlang.org/show_bug.cgi?id=13854

          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 at yahoo.com
          Reporter: schveiguy at 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).

--


More information about the Digitalmars-d-bugs mailing list