Stack-allocating wrapped C++ objects


#1

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

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

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
end

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

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
#2

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.


#3

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