<p dir="ltr">On 4 Jun 2014 08:02, "Marshall Clow" <<a href="mailto:mclow.lists@gmail.com">mclow.lists@gmail.com</a>> wrote:<br>
><br>
><br>
> On Jun 3, 2014, at 3:14 PM, Richard Smith <<a href="mailto:richard@metafoo.co.uk">richard@metafoo.co.uk</a>> wrote:<br>
><br>
> > Hi!<br>
> ><br>
> > This patch causes libc++ to use Clang's new __builtin_operator_new and __builtin_operator_delete builtins when possible. These builtins allow optimizations that the standard builtins do not: in particular, if we can remove all uses of an allocation, this permits removing the allocation itself too.<br>

> ><br>
> > In particular, this allows code using std::vector and its kin to be optimized away to nothing. Previously it would get optimized to the point where only the allocation and deallocation remained.<br>
> ><br>
> > This change has been applied to most calls to ::operator new and ::operator delete in libc++; I believe such optimizations are permitted by the specification of all affected library components.<br>
> ><br>
> > The exceptions are:<br>
> >  * get_temporary_buffer wants to call nothrow new, and we don't support that with the builtins (that would require teaching Clang about std::nothrow_t)<br>
> >  * __refstring is not affected; this doesn't seem particularly worthwhile since the only purpose for it is ABI interoperability with GCC<br>
> ><br>
> > One other caveat: the patch adds an include of <new> to <valarray>. <new> is extremely light, so I doubt this is a problem, but I thought it was worth calling out.<br>
><br>
> The code here looks quite straightforward.<br>
> I don’t see any problems - but I do have questions.<br>
><br>
> How does __builtin_operator_new/__builtin_operator_delete work if a user provides their own<br>
> global operator new/delete ?<br>
><br>
> For example, given code like this:<br>
><br>
> $ cat junk1.cpp<br>
><br>
> int main () {<br>
>         // something that eventually calls __builtin_operator_new<br>
> }<br>
><br>
> $ cat junk2.cpp<br>
> #include <new><br>
><br>
> char buffer[10240];<br>
> size_t offset = 0;<br>
><br>
> void * operator new(size_t sz) throw(std::bad_alloc) {<br>
>         void *p = &buffer[offset];<br>
>         offset += sz;<br>
>         return p;<br>
> }<br>
> void operator delete(void *) {}<br>
><br>
> does the user’s operator new get called?</p>
<p dir="ltr">Yes, if the allocation isn't optimised out. (The builtins behave just like the allocation / deallocation in a new-expression or delete-expression.)</p>