Thread overview
Garbage Collector profiling and the dynamic array reserve() function
Oct 17, 2017
Tony
Oct 18, 2017
Tony
Oct 22, 2017
bauss
October 17, 2017
Found this unanswered question on StackOverflow.

This program:

import std.stdio;

void add(ref int[] data)
{
    data ~= 1;
    data ~= 2;
}

void main()
{
    int[] a;
    writeln("capacity:",a.capacity);
    auto cap = a.reserve(1000); // allocated may be more than requested
    assert(cap >= 1000);
    assert(cap == a.capacity);
    writeln("capacity:",a.capacity);
    a.add();
    writeln(a);

}

compiled with "dmd -profile=gc"

has this output in profilegc.log

bytes allocated, allocations, type, function, file:line
              4	              1	int[] profiling.add profiling.d:8
              4	              1	int[] profiling.add profiling.d:7

The question is: why doesn't using reserve() cause an allocation to be shown?
October 17, 2017
On 10/17/17 2:14 AM, Tony wrote:
> Found this unanswered question on StackOverflow.
> 
> This program:
> 
> import std.stdio;
> 
> void add(ref int[] data)
> {
>      data ~= 1;
>      data ~= 2;
> }
> 
> void main()
> {
>      int[] a;
>      writeln("capacity:",a.capacity);
>      auto cap = a.reserve(1000); // allocated may be more than requested
>      assert(cap >= 1000);
>      assert(cap == a.capacity);
>      writeln("capacity:",a.capacity);
>      a.add();
>      writeln(a);
> 
> }
> 
> compiled with "dmd -profile=gc"
> 
> has this output in profilegc.log
> 
> bytes allocated, allocations, type, function, file:line
>                4                  1    int[] profiling.add profiling.d:8
>                4                  1    int[] profiling.add profiling.d:7
> 
> The question is: why doesn't using reserve() cause an allocation to be shown?

I don't know what "allocations" represents, but reserve actually calls gc_malloc, and the others do not (the space is available to expand into the block). There should be only one allocation IMO.

-Steve
October 18, 2017
On Tuesday, 17 October 2017 at 13:27:24 UTC, Steven Schveighoffer wrote:

>
> I don't know what "allocations" represents, but reserve actually calls gc_malloc, and the others do not (the space is available to expand into the block). There should be only one allocation IMO.
>
> -Steve

So there should be a bug report written for this?

October 18, 2017
On 10/18/17 1:40 AM, Tony wrote:
> On Tuesday, 17 October 2017 at 13:27:24 UTC, Steven Schveighoffer wrote:
> 
>>
>> I don't know what "allocations" represents, but reserve actually calls gc_malloc, and the others do not (the space is available to expand into the block). There should be only one allocation IMO.
>>
> 
> So there should be a bug report written for this?
> 

It all depends on what "allocations" means. I'd wait to find out from someone who is familiar with the GC profiling.

-Steve
October 22, 2017
On Wednesday, 18 October 2017 at 15:39:43 UTC, Steven Schveighoffer wrote:
> On 10/18/17 1:40 AM, Tony wrote:
>> On Tuesday, 17 October 2017 at 13:27:24 UTC, Steven Schveighoffer wrote:
>> 
>>>
>>> I don't know what "allocations" represents, but reserve actually calls gc_malloc, and the others do not (the space is available to expand into the block). There should be only one allocation IMO.
>>>
>> 
>> So there should be a bug report written for this?
>> 
>
> It all depends on what "allocations" means. I'd wait to find out from someone who is familiar with the GC profiling.
>
> -Steve

I don't have a lot of clues on how the GC profiling work, but looking at reserve() it calls mem.xmalloc() for allocations which in fact calls GC.malloc().

Looking at the profiling for GC though:
https://github.com/dlang/dmd/blob/69567a32c5bffae5513b41e7691c91b50766b552/src/ddmd/e2ir.d#L5952

It doesn't look like there's anything for array reserve calls, unless:
 [ RTLSYM_ALLOCMEMORY, RTLSYM_TRACEALLOCMEMORY ]
are triggered from the allocations done in reserve(), but I have no idea about that.