librelist archives

« back to archive

Allocation strategy classes

Allocation strategy classes

From:
Jason Roelofs
Date:
2010-01-06 @ 14:59
Paul,

* Default_Allocation_Strategy::alloc() is never used, I assume it was there
before Constructor was built. Is there any use for this call anymore and can
I get rid of it?
* Is anyone using the Xmalloc strategy class? Would that be ok to remove it
and replace it with documentation on how to build your own allocation
strategies?

Jason

Re: [rice] Allocation strategy classes

From:
Paul Brannan
Date:
2010-01-06 @ 18:53
On Wed, Jan 06, 2010 at 09:59:42AM -0500, Jason Roelofs wrote:
> Paul,
> 
> * Default_Allocation_Strategy::alloc() is never used, I assume it was there
> before Constructor was built. Is there any use for this call anymore and can I
> get rid of it?

I would have assumed the same thing, but actually it's the other way
around.  First there was Ruby_Delete_Strategy:


http://excruby.cvs.sourceforge.net/viewvc/excruby/excruby/excruby/ruby_reference.ipp?revision=1.5&view=markup

then Constructor:


http://excruby.cvs.sourceforge.net/viewvc/excruby/excruby/excruby/builtin/Constructor.hpp?revision=1.1.1.1&view=markup

then later when excruby became Rice, Ruby_Delete_Strategy was
generalized to the allocation strategy so the new/delete would be in the
same file (instead of split between two different files).

IMO this is a bug; the Constructor should call
Default_Allocation_Strategy::allocate() instead of calling new directly.

> * Is anyone using the Xmalloc strategy class? Would that be ok to remove it and
> replace it with documentation on how to build your own allocation strategies?

Nobody here is using it at the moment.  It's purpose for existence,
though, is so the ruby garbage collector knows about the memory that is
allocated by the extension and can thus do its job better (the
Data_Make_Struct macro uses xmalloc for this reason).  It started as an
experiment, but I had always in the back of my mind considered making
the xmalloc strategy the default strategy.

I don't know whether or not it actually solves a real-world problem.

What's the motivation for this change?  I'm all for it if it simplifies
a feature that we want.

Paul

Re: [rice] Allocation strategy classes

From:
Jason Roelofs
Date:
2010-01-06 @ 19:07
On Wed, Jan 6, 2010 at 1:53 PM, Paul Brannan <pbrannan@atdesk.com> wrote:

> On Wed, Jan 06, 2010 at 09:59:42AM -0500, Jason Roelofs wrote:
> > Paul,
> >
> > * Default_Allocation_Strategy::alloc() is never used, I assume it was
> there
> > before Constructor was built. Is there any use for this call anymore and
> can I
> > get rid of it?
>
> I would have assumed the same thing, but actually it's the other way
> around.  First there was Ruby_Delete_Strategy:
>
>
> 
http://excruby.cvs.sourceforge.net/viewvc/excruby/excruby/excruby/ruby_reference.ipp?revision=1.5&view=markup
>
> then Constructor:
>
>
> 
http://excruby.cvs.sourceforge.net/viewvc/excruby/excruby/excruby/builtin/Constructor.hpp?revision=1.1.1.1&view=markup
>
> then later when excruby became Rice, Ruby_Delete_Strategy was
> generalized to the allocation strategy so the new/delete would be in the
> same file (instead of split between two different files).
>
> IMO this is a bug; the Constructor should call
> Default_Allocation_Strategy::allocate() instead of calling new directly.
>
> > * Is anyone using the Xmalloc strategy class? Would that be ok to remove
> it and
> > replace it with documentation on how to build your own allocation
> strategies?
>
> Nobody here is using it at the moment.  It's purpose for existence,
> though, is so the ruby garbage collector knows about the memory that is
> allocated by the extension and can thus do its job better (the
> Data_Make_Struct macro uses xmalloc for this reason).  It started as an
> experiment, but I had always in the back of my mind considered making
> the xmalloc strategy the default strategy.
>
> I don't know whether or not it actually solves a real-world problem.
>
> What's the motivation for this change?  I'm all for it if it simplifies
> a feature that we want.
>
> Paul
>
>
Interesting, makes sense then. The motivation behind the question is simply
one of cleaning up extraneous source, which I was pointed to when trying to
help someone with using Default_Allocation_Strategy and what needed to go in
::alloc(). I did a quick search, saw that nothing used the method and to
help with any potential future confusion I'd like to either make use of it,
or get rid of it (just alloc in this case, free is definitely used).

Of course, there is a big problem with Constructor() calling alloc(), and
that's that it would need to pass in all parameters given to the Constructor
down to the alloc() method, which effectively makes the class unusable for
the functionality it's meant to expose. Given that, I don't know of a way
you can alloc a C++ object, *then* call the constructor. If that is in fact
possible, then we can update Rice to use ::alloc again.

Also, concerning the Xmalloc strategy, I see of no way to actually use that
class right now, you'd have to reimplement the Default<> strategy for a
given type to use the xmalloc code.

So the short of it is I just wanted to either clean up or fix up some
currently unused code.

Jason

Re: [rice] Allocation strategy classes

From:
Paul Brannan
Date:
2010-01-06 @ 21:33
On Wed, Jan 06, 2010 at 02:07:23PM -0500, Jason Roelofs wrote:
> Of course, there is a big problem with Constructor() calling alloc(), and
> that's that it would need to pass in all parameters given to the Constructor
> down to the alloc() method, which effectively makes the class unusable for the
> functionality it's meant to expose. Given that, I don't know of a way you can
> alloc a C++ object, *then* call the constructor. If that is in fact possible,
> then we can update Rice to use ::alloc again.

They can be separated, but it's a little tricky if you want to support
overloading operator new:

  typedef void * (*OpNew)(size_t);

  template<OpNew> struct Test { };

  template<typename T>
  void *
  mynew_(Test<T::operator new> *)
  {
    void * p = T::operator new(sizeof(T));
    return new (p) T;
  }

  template<typename T>
  void *
  mynew_(...)
  {
    void * p = operator new(sizeof(T));
    return new (p) T;
  }

  template<typename T>
  void *
  mynew()
  {
    return mynew_<T>(0);
  }

then:

  void * ptr = 0;
  try
  {
    ptr = mynew<T>();
  }
  catch(...)
  {
    delete ptr;
  }
  T * obj = new(ptr) T;

> Also, concerning the Xmalloc strategy, I see of no way to actually use that
> class right now, you'd have to reimplement the Default<> strategy for a given
> type to use the xmalloc code.

I think it's not difficult:

1. Modify the allocation strategy to only allocate
2. Modify the Constructor class to allocate with the allocation
   strategy, then call placement new

Re: [rice] Allocation strategy classes

From:
Jason Roelofs
Date:
2010-01-08 @ 16:33
On Wed, Jan 6, 2010 at 4:33 PM, Paul Brannan <pbrannan@atdesk.com> wrote:

> On Wed, Jan 06, 2010 at 02:07:23PM -0500, Jason Roelofs wrote:
> > Of course, there is a big problem with Constructor() calling alloc(), and
> > that's that it would need to pass in all parameters given to the
> Constructor
> > down to the alloc() method, which effectively makes the class unusable
> for the
> > functionality it's meant to expose. Given that, I don't know of a way you
> can
> > alloc a C++ object, *then* call the constructor. If that is in fact
> possible,
> > then we can update Rice to use ::alloc again.
>
> They can be separated, but it's a little tricky if you want to support
> overloading operator new:
>
>  typedef void * (*OpNew)(size_t);
>
>  template<OpNew> struct Test { };
>
>  template<typename T>
>  void *
>  mynew_(Test<T::operator new> *)
>  {
>    void * p = T::operator new(sizeof(T));
>    return new (p) T;
>  }
>
>  template<typename T>
>  void *
>  mynew_(...)
>  {
>    void * p = operator new(sizeof(T));
>    return new (p) T;
>  }
>
>  template<typename T>
>  void *
>  mynew()
>  {
>    return mynew_<T>(0);
>  }
>
> then:
>
>  void * ptr = 0;
>  try
>  {
>    ptr = mynew<T>();
>  }
>  catch(...)
>  {
>    delete ptr;
>  }
>  T * obj = new(ptr) T;
>
> > Also, concerning the Xmalloc strategy, I see of no way to actually use
> that
> > class right now, you'd have to reimplement the Default<> strategy for a
> given
> > type to use the xmalloc code.
>
> I think it's not difficult:
>
> 1. Modify the allocation strategy to only allocate
> 2. Modify the Constructor class to allocate with the allocation
>   strategy, then call placement new
>
>
So given that huge mess of code (IMO), what's the benefit of letting people
use something other than new and delete? For all the cases I've run into,
all I've ever needed was to tell Rice NOT to destroy with delete due to
either private destructor (say, singleton class of some sort) or as the way
to tell Rice to never delete as the C++ will manage the object itself (this
case, of course, needs to be handled explicitly, aka call / return policies,
maybe something else, policies on Constructor?).

Jason