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