Break up Alloc<T> in to templated and (mostly) non-templated parts? Without seeing the code its hard to know.
It is a tiny function that is basically equivalent to that macro, but using variadic templates:
template <typename T, typename... Args>
T* Alloc(Args&&... args) {
assert(gHeap.is_initialized_);
void* place = gHeap.Allocate(sizeof(T));
assert(place != nullptr);
// placement new
return new (place) T(std::forward<Args>(args)...);
}
https://github.com/oilshell/oil/blob/master/mycpp/gc_heap.h#...So there is nothing to really break up
Make it forced-inline and it should be more similar to the macro.
An example is I wrote a varadic template for a GC allocation interface:
However because I have so many fine-grained types, this seems to takes up 10% of the VM size of the program!https://www.oilshell.org/release/0.12.5/pub/metrics.wwz/oil-...
The total vmsize is 1217792 and the 2 Alloc<> entries are about 10% of that.
So my conclusion is that it would have been better to use a macro all along, which would look something like:
This will expand to something like: That is, it uses placement new to constructs the object inside a GC'd heap.-----
I don't believe the C++ idiom is any faster, and it makes the code larger (and potentially slower).
Am I missing something?
I think the issue is that the monomorphization happens for each T and not for each sizeof(T), and even doing it on sizeof(T) is not really necessary for fast code.
Oil has more fine-grained and ML-style strong types than any other shell implementation, via ASDL and C++. So I try to take advantage of additional type safety. But sometimes it's not worth it. I suspect the macro is better here. It will be somewhat annoying to change all the code, but probably worth it.