Does foreach on array literal allocate?
Walter Bright
newshound1 at digitalmars.com
Thu Dec 4 17:37:05 PST 2008
Bill Baxter wrote:
> Does anyone know off the top of their head if code like this allocates
> or not with current DMD 1.x compilers?
>
> foreach(x; [1, 2, 3, 4])
> {
> // do something non-allocating with x
> }
Here's how to find out. Compile:
void test()
{
foreach(x; [1, 2, 3, 4])
{
// do something non-allocating with x
}
}
Obj2asm the output:
_D5test44testFZv comdat
assume CS:_D5test44testFZv
L0: enter 8,0
push EBX
push 4
push 3
push 2
push 1
push 4
push offset FLAT:_D12TypeInfo_G4i6__initZ
call near ptr __d_arrayliteralT
mov -8[EBP],EAX
lea EAX,010h[EAX]
mov -4[EBP],EAX
add ESP,018h
L25: mov ECX,-8[EBP]
cmp ECX,-4[EBP]
jae L38
mov EDX,-8[EBP]
mov EBX,[EDX]
add dword ptr -8[EBP],4
jmp short L25
L38: pop EBX
leave
ret
_D5test44testFZv ends
Look up _d_arrayliteralT in the runtime library:
extern (C) void* _d_arrayliteralT(TypeInfo ti, size_t length, ...)
{
auto sizeelem = ti.next.tsize(); // array element size
void* result;
debug(PRINTF) printf("_d_arrayliteralT(sizeelem = %d, length =
%d)\n", sizeelem, length);
if (length == 0 || sizeelem == 0)
result = null;
else
{
result = gc_malloc(length * sizeelem, !(ti.next.flags() & 1) ?
BlkAttr.NO_SCAN : 0);
va_list q;
va_start!(size_t)(q, length);
size_t stacksize = (sizeelem + int.sizeof - 1) & ~(int.sizeof - 1);
if (stacksize == sizeelem)
{
memcpy(result, q, length * sizeelem);
}
else
{
for (size_t i = 0; i < length; i++)
{
memcpy(result + i * sizeelem, q, sizeelem);
q += stacksize;
}
}
va_end(q);
}
return result;
}
and note the call to gc_malloc().
More information about the Digitalmars-d
mailing list