News for hackers. Stuff that matters.
Re:CppCon 2022 by chubot on Saturday September 17, 2022 @11:37AM (#32878367)
Why should I code in C++ idioms if it has significant downsides?

An example is I wrote a varadic template for a GC allocation interface:

    T1* obj1 = Alloc<T1>(arg1)
    T2* obj2 = Alloc<T2>(arg2, arg3)
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:

    T1* obj1 = ALLOC(T1, arg1)
    T2* obj2 = ALLOC(T2, arg2, arg3)
This will expand to something like:

    T1* obj1 = new (gHeap.Allocate(sizeof(T1)) (arg1)
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.

Re:CppCon 2022 by krona on Saturday September 17, 2022 @11:56AM (#32878533)
Break up Alloc<T> in to templated and (mostly) non-templated parts? Without seeing the code its hard to know.
Re:CppCon 2022 by chubot on Saturday September 17, 2022 @12:24PM (#32878752)
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

Re:CppCon 2022 by cma on Saturday September 17, 2022 @01:12PM (#32879171)
Make it forced-inline and it should be more similar to the macro.
Re:CppCon 2022 by jcelerier on Saturday September 17, 2022 @06:25PM (#32882210)
It also needs to be marked as hidden or internal visibility (or be made static) otherwise an instantiation will likely still be present in the binary