Bug 13854 – Appending to an interior slice of a large array results in unnecessary 16-byte offset
Status
RESOLVED
Resolution
FIXED
Severity
normal
Priority
P1
Component
druntime
Product
D
Version
D2
Platform
x86
OS
All
Creation time
2014-12-11T19:37:00Z
Last change time
2015-02-18T03:38:34Z
Assigned to
schveiguy
Creator
schveiguy
Comments
Comment #0 by schveiguy — 2014-12-11T19:37:44Z
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).