On 3/21/19 5:03 AM, Jakub Jelinek wrote:
On Thu, Mar 21, 2019 at 09:28:06AM +0100, Richard Biener wrote:
Well, this is surely more costly in that it allocates both the hash_table
structure and the memory pointed by it from GC.

You could use

   char constexpr_fundef_table[sizeof(hash-table)];
   bool constexpr_fundef_table_initialized_p = false;

   if (!constexpr_fundef_table_initialized_p)
     new (constexpr_fundef_table) hash-table (...);

and hide this pattern behind a new RAII class?

Do we have a portable C++98 way to make sure the buffer has proper alignment
though?  Plus we'd need to pass around this auto_hash_set instead of
hash_set, so from the usage POV it would be like the following patches
where the functionality is embedded in hash_set instantiations itself with a
special new template parameter.

I guess another option would be to make the decision whether
the hash_{table,set,map} is constructed with allocation right away (and no
runtime checks for it) or if it is lazy another template argument (bool
Lazy = false before the Allocator template argument), if !Lazy, it would
work exactly as it is now, if Lazy it would not allocate it in the ctor
and where needed would add m_entries checks.

That's a possibility, but what about the above RAII trick?  Not sure
if there's a way to avoid the char[] use and instead use "unconstructed"
properly typed storage.

Attached (so far without changelog, selftest additions and only tested with
make -j32 -k check-c++-all RUNTESTFLAGS="dg.exp='pr89767.C *lambda* *desig*'"
) is
1) hash_{table,set} <whatever, true> implementation for lazy allocation

I would expect that a single test on an object that's already in cache in the context of hash table operations would be insignificant, but if you really want to offer that choice this seems like a clean enough way to implement it. Are you sure that we want the default to be immediate allocation?

2) the PR c++/89767 patch with optimization for zero and one entries
3) incremental PR c++/71446 fix to simplify that code using this new
    infrastructure

2 and 3 are explicitly specifying "false" for the Lazy parameter, which is the default.

We might do the duplicate checking in a wrapper around add_capture since it's only used by cp_parser_lambda_introducer. It's fine either way.

Jason

Reply via email to