This is a follow-up to r239666: "Fix PR12999 - unordered_set::insert calls operator new when no insert occurs". That fix didn't apply to `unordered_map` because unordered_map::value_type gets packed inside: -- union __value_type { pair<key_type, mapped_type> __nc; // Only C++11 or higher. pair<const key_type, mapped_type> __cc; // Always. // Constructors... }; -- and the underlying __hash_table only knows about __value_type.
I added __hash_table::__insert_unique_dispatch(), which accepts an extra argument of either true_type or false_type. Since __hash_table doesn't know anything about __value_type vs. value_type, unordered_map needs to check whether the type passed to `insert()` is recognized -- i.e., either value_type or __nc_value_type -- and can avoid the allocation. Doing a type check in __hash_table seems like a layering violation. Besides this, I augmented __unordered_map_hasher and __unordered_map_equal to understand both value_type and __nc_value_type, and broke an ambiguity in callers of __hash_table::__construct_node() by renaming the versions that take a hash to __construct_node_hash(). The main work is still done by __hash_table::__insert_unique_value() from r239666. This is one of my first patches for libc++, and I'm not sure of a few things: - Did I successfully match the coding style? (I'm kind of lost without clang-format TBH.) - Should I separate the change to __construct_node_hash() into a separate prep commit? (I would if this were LLVM, but I'm not sure if the common practice is different for libc++.) - Most of the overloads I added to __unordered_map_hasher and __unordered_map_equal aren't actually used by __hash_table::__insert_unique_value(). Should I omit the unused ones? (Again, for LLVM I would have omitted them.) After this I'll fix the same performance issue in std::map (and I assume std::set?).
0001-unordered_map-Avoid-unnecessary-mallocs-when-no-inse.patch
Description: Binary data
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits