Stack-allocating wrapped C++ objects


In CxxWrap.jl, each C++ type has an associated type of the form:

type WrappedCxxType
  ptr::Ptr{Void} # Pointer to the C++ object

The reason for this is that the C++ object may be created using a constructor called from Julia, so it needs a finalizer associated with it. Unfortunately, this also means the wrapper is heap-allocated, even when it is returned for an already existing object and no finalizer is needed. So for performance reasons, I really want to make this an immutable, but then I see no way to delete an allocated object when needed (apart from manually calling a function). The performance problem comes up running a sparse matrix assembly loop for example, where the Julia loop is twice as slow as the C++ loop because of these allocations.

To alleviate this, I was thinking of the following construct:

# Used as the constructor return type
type AllocatedWrappedCxxType
  ptr::Ptr{Void} # Pointer to the C++ object

# Used as existing pointer and reference return type
immutable WrappedCxxTypeRef
  ptr::Ptr{Void} # Pointer to the C++ object

In addition to that, there would be a convert function to convert between both types and function signatures would take the union of these types as arguments. I’m hesitating to implement this, because it feels a bit complicated and I want to make sure I’m not missing a more obvious solution.

Also, what’s the progress on this:

Seems like it would be the perfect solution here.

Converting between type and immutable with the same layout

You can certainly do this. It’ll just segfault if you don’t manage memory correctly since it won’t do that automatically anymore.

The stack allocation PR won’t handle this case.


This is somewhat off-topic, but I don’t think you can reasonably rely on the finalizer to delete the object. In my experience these objects tend to live in memory for a lot longer than you expect because the Julia GC doesn’t know how large they are.

Therefore I think you should prefer manually managing the memory or avoiding using Ptr{Void} as a field type. In my case I was able to do the latter, but I think I pay for it by doing extra copies when moving data between Julia and C++.

See for reference