[libcxx] Patch/RFC: Avoid using ::operator new in the default allocator

Howard Hinnant howard.hinnant at gmail.com
Sat Oct 5 18:19:18 PDT 2013


On Oct 5, 2013, at 8:59 PM, Chandler Carruth <chandlerc at google.com> wrote:

> 
> On Sat, Oct 5, 2013 at 8:15 PM, Howard Hinnant <howard.hinnant at gmail.com> wrote:
> On Sep 25, 2013, at 3:46 PM, Chandler Carruth <chandlerc at google.com> wrote:
> 
> > This only applies to calls made as part of a new expression -- an explicit call cannot be transformed, it is allowed to have observed side effects according to as-if.
> 
> It seems illogical to me to allow one transformation but not the other because of backwards compatibility concerns.  And this seems to indicate that the committee *does* have backwards compatibility concerns.
> 
> The discussion in the committee around this basically centered around the following logic:
> 
> There was strong consensus that we wanted to allow these transformations to most allocations. There was also strong consensus that it would be useful to provide an escape hatch. Further, it seemed like the implementation providing storage for a new expression by emitting optimized calls to the allocation function would be relatively unsurprising, where as the implementation merging *explicit* calls to operator new would be significantly more surprising.
> 
> Essentially, this wasn't a backwards compatibility decision, but one of providing a relatively unsurprising mechanism to explicitly get an exact call to an allocation function.
>  
> I see a few ways forward, none of them easy, nor actionable by us alone.
> 
> 1.  Get the LWG to change the places where they specify calls to ::operator new.  This will entail a backwards compatibility hit.  Not sure if it is acceptably small or not.
> 
> 2.  Get the CWG to further relax where these types of optimizations can be done.  This will entail a backwards compatibility hit.  Not sure if it is acceptably small or not.
> 
> 3.  There's a new polymorphic allocator on the horizon.  Make the spec for that sufficiently relaxed for these optimizations, and get it standardized.
> 
> Perhaps I'm missing another possibility?
> 
> I don't think we need to do anything in the committee.
> 
> I propose that we add a __builtin_allocate and __builtin_array_allocate (or better names, i hate naming things) which call the global operator new exactly as a new-expression would. That is, they *are* candidates for merging, etc. Then we define the libc++ routine __allocate in terms of the builtin. The result will be that calling libc++'s __allocate funtion does call operator new, but when and how many calls are produced is unspecified.
> 
> Essentially, the [allocator.members]p6 I believe already gives us enough freedom to do the same set of optimizations as provided by the committee's new wording for new-expressions. (It actually gives more freedom as far as I can tell.) All we need is a way to express that to the optimizer.
> 
> Does this make sense to you Howard? I may be missing some aspect of incompatibility, so let me know.

I must admit to not completely understanding how your path forward is any different from the status-quo.  And in that sense, I have absolutely no objection to it.  I do maintain that unless there is a committee change, we need to beware of:

#include <vector>

int
main()
{
   std::vector<int> v;
   v.push_back(1);
   return v[0];
}

#include <stdio.h>
#include <stdlib.h>

void* operator new[](size_t sz)
{
   printf("I don't like new-array!\n");
   abort();
   return nullptr;
}

And I do agree that these are very attractive optimization opportunities that we should aggressively pursue.

Howard





More information about the cfe-commits mailing list