On 2015-07-13 20:52, Andrei Alexandrescu wrote:

That design would have been possible, e.g. have deallocate return false,
owns return Ternary.unknown, expand return false, alignedAllocate return
null etc.

Perhaps it's a simplified view, but for all examples in the talk it seems it would work without changing the API. The branch which was executed for "does not support this operation" was the same for "this operation failed". Example:

static if (hasMember!("deallocate"))
    deallocate();

There was no "else", no action when "deallocate" was not supported. Or:

static if (hasMember!("reallocate"))
    return reallocate();
else
    return false;

Of course I haven't look through the whole source code.

I see the following issues with that design:

1. Many incorrect or grossly unfit allocators can be statically defined,
for example a FallbackAllocator putting in the front an allocator that
has a dummy implementation of owns. Unittesting could be expected to
reasonably get rid of most.

But there are many byzantine failure modes that are likely to escape
even thorough unittesting. Consider, for example, building a Segregator
out of several allocators, most of which support alignedAllocate, but
some that don't (i.e. return null). During testing, if only the
supported size ranges are tested, it all works. In production, if the
wrong size is asked for in alignedAllocate, the allocator will return
null as if the system ran out of memory.

2. Efficiency becomes increasingly tenuous. Simple cases of calls to
do-nothing functions can be reasonably expected to be handled by the
optimizer, but e.g. AllocatorList does significant work in owns,
deallocate, deallocateAll, etc. - all under the assumption that the
parent does implement the expected functionality.

Emery Berger told me this was a constant source of concern with
HeapLayers; he'd need to look at disassembly and tweak code in various
ways to obtain the desired inlining, which when absent would cause
dramatic slowdowns. Compiler technology has improved since that work,
but also Heap Building Blocks go quite a longer distance than HeapLayers.

With the DbI approach, the performance profile of a composite allocator
is immediate and obvious.

Yeah, my suggestion assumes the compiler can optimize away all these dummy functions.

--
/Jacob Carlborg

Reply via email to