[Webkit-unassigned] [Bug 184012] Unable to use HashMap<WebCore::SecurityOriginData, Ref<WebSWServerToContextConnection>> type in StorageProcess.h
bugzilla-daemon at webkit.org
bugzilla-daemon at webkit.org
Mon Mar 26 10:41:33 PDT 2018
https://bugs.webkit.org/show_bug.cgi?id=184012
--- Comment #4 from Chris Dumez <cdumez at apple.com> ---
(In reply to Chris Dumez from comment #3)
> (In reply to Chris Dumez from comment #2)
> > Using HashMap<RefPtr<WebCore::SecurityOrigin>,
> > Ref<WebSWServerToContextConnection>> works. I believe the different is that
> > emptyValueIsZero for both the Key and the Value.
> >
> > emptyValueIsZero is false when the key is a SecurityOriginData. So
> > KeyValuePairHashTraits::emptyValueIsZero goes from true to false and it
> > causes failures.
>
> As a result, it ends up using a different template specialization for
> HashTableBucketInitializer:
> template<bool emptyValueIsZero> struct HashTableBucketInitializer;
>
> template<> struct HashTableBucketInitializer<false> {
> template<typename Traits, typename Value> static void
> initialize(Value& bucket)
> {
> new (NotNull, std::addressof(bucket))
> Value(Traits::emptyValue());
> }
> };
>
> template<> struct HashTableBucketInitializer<true> {
> template<typename Traits, typename Value> static void
> initialize(Value& bucket)
> {
> // This initializes the bucket without copying the empty value.
> // That makes it possible to use this with types that don't
> support copying.
> // The memset to 0 looks like a slow operation but is optimized
> by the compilers.
> memset(std::addressof(bucket), 0, sizeof(bucket));
> }
> };
So instead of doing a memset zero, we now rely on Traits::emptyValue(), which for Ref<T> is static Ref<P> emptyValue() { return HashTableEmptyValue; }
This is implemented as:
Ref(HashTableEmptyValueType) : m_ptr(hashTableEmptyValue()) { }
hashTableDeletedValue() returns nullptr.
So when we construct a KeyValuePair:
template<typename K, typename V>
KeyValuePair(K&& key, V&& value)
: key(std::forward<K>(key))
, value(std::forward<V>(value))
{
}
And V is HashTraits<Ref<T>>::emptyValue(), then it calls the Ref<T>(Ref<t>&&) move constructor, which ends up calling leakRef() on the Ref. This is implemented as:
T& leakRef() WARN_UNUSED_RETURN
{
ASSERT(m_ptr);
/ ...
}
We hit this assertion since m_ptr is nullptr when the Ref<> is an empty HashTable value :/
Advice on how to best address this would be appreciated:
1. Dropping this assertion would be unfortunate since it is useful to catch bugs
2. Using another value than nullptr as empty HashTable value maybe?
--
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20180326/053251b9/attachment-0001.html>
More information about the webkit-unassigned
mailing list