On 07/03/2015 10:55 AM, Richard Sandiford wrote: > Trevor Saunders <tbsau...@tbsaunde.org> writes: >> On Thu, Jul 02, 2015 at 09:09:31PM +0100, Richard Sandiford wrote: >>> Martin Liška <mli...@suse.cz> writes: >>>> diff --git a/gcc/asan.c b/gcc/asan.c >>>> index e89817e..dabd6f1 100644 >>>> --- a/gcc/asan.c >>>> +++ b/gcc/asan.c >>>> @@ -362,20 +362,20 @@ struct asan_mem_ref >>>> /* Pool allocation new operator. */ >>>> inline void *operator new (size_t) >>>> { >>>> - return pool.allocate (); >>>> + return ::new (pool.allocate ()) asan_mem_ref (); >>>> } >>>> >>>> /* Delete operator utilizing pool allocation. */ >>>> inline void operator delete (void *ptr) >>>> { >>>> - pool.remove ((asan_mem_ref *) ptr); >>>> + pool.remove (ptr); >>>> } >>>> >>>> /* Memory allocation pool. */ >>>> - static pool_allocator<asan_mem_ref> pool; >>>> + static pool_allocator pool; >>>> }; >>> >>> I'm probably going over old ground/wounds, sorry, but what's the benefit >>> of having this sort of pattern? Why not simply have object_allocators >>> and make callers use pool.allocate () and pool.remove (x) (with pool.remove >>> calling the destructor) instead of new and delete? It feels wrong to me >>> to tie the data type to a particular allocation object like this. >> >> Well the big question is what does allocate() do about construction? if >> it seems wierd for it to not call the ctor, but I'm not sure we can do a >> good job of forwarding args to allocate() with C++98. > > If you need non-default constructors then: > > new (pool) type (aaa, bbb)...; > > doesn't seem too bad. I agree object_allocator's allocate () should call > the constructor.
Hello. I do not insist on having a new/delete operator for aforementioned class. However, I don't know a different approach that will do an object construction in the allocate method w/o utilizing placement new? > >> However it seems kind of wierd the operator new here is calling the >> placement new on the object it allocates. > > Yeah. > >>> And using the pool allocator functions directly has the nice property >>> that you can tell when a delete/remove isn't necessary because the pool >>> itself is being cleared. >> >> Well, all these cases involve a pool with static storage lifetime right? >> so actually if you don't delete things in these pool they are >> effectively leaked. > > They might have a static storage lifetime now, but it doesn't seem like > a good idea to hard-bake that into the interface (by saying that for > these types you should use new and delete, but for other pool-allocated > types you should use object_allocators). Maybe I just have bad memories > from doing the SWITCHABLE_TARGET stuff, but there I was changing a lot > of state that was "obviously" static in the old days, but that needed > to become non-static to support vaguely-efficient switching between > different subtargets. The same kind of thing is likely to happen again. > I assume things like the jit would prefer not to have new global state > with load-time construction. Agree with that it's a global state. But even before my transformation the code utilized static variables that are similar problem from e.g. JIT perspective. Best approach would be to encapsulate these static allocators to a class (a pass?). It's quite a lot of work. Thanks, Martin > > Thanks, > Richard >