Title: [99733] trunk/Source/_javascript_Core
Revision
99733
Author
da...@apple.com
Date
2011-11-09 10:11:47 -0800 (Wed, 09 Nov 2011)

Log Message

Add code path in HashTable for emptyValueIsZero that does not require copying the empty value
https://bugs.webkit.org/show_bug.cgi?id=71875

Reviewed by Anders Carlsson.

This is a step along the path of making OwnPtr work as HashMap value types.

* wtf/Alignment.h: Moved the AlignedBufferChar and AlignedBuffer types from Vector.h here.
Also fixed include style. To include other WTF headers inside WTF, we use "" includes.
I did not change the code to fix style checker complaints.

* wtf/HashTable.h: Added includes as needed and fixed include style.
(WTF::doubleHash): Removed the uneeeded and inappropriate "static" in this function, which
gave it internal linkage for no good reason.
(WTF::HashTable::checkKey): Made this use AlignedBuffer for the deleted value check to avoid
construction/destruction problems instead of doing the trick where we construct and destroy
an empty value twice. It's cleaner and simpler and avoids copying the empty value.
(WTF::HashTable::initializeBucket): Specialized initializeBucket to use memset when the
empty value is zero rather than copying an empty value.

* wtf/Vector.h: Moved the AlignedBufferChar and AlignedBuffer types into Alignment.h.

Modified Paths

Diff

Modified: trunk/Source/_javascript_Core/ChangeLog (99732 => 99733)


--- trunk/Source/_javascript_Core/ChangeLog	2011-11-09 18:07:12 UTC (rev 99732)
+++ trunk/Source/_javascript_Core/ChangeLog	2011-11-09 18:11:47 UTC (rev 99733)
@@ -1,3 +1,27 @@
+2011-11-08  Darin Adler  <da...@apple.com>
+
+        Add code path in HashTable for emptyValueIsZero that does not require copying the empty value
+        https://bugs.webkit.org/show_bug.cgi?id=71875
+
+        Reviewed by Anders Carlsson.
+
+        This is a step along the path of making OwnPtr work as HashMap value types.
+
+        * wtf/Alignment.h: Moved the AlignedBufferChar and AlignedBuffer types from Vector.h here.
+        Also fixed include style. To include other WTF headers inside WTF, we use "" includes.
+        I did not change the code to fix style checker complaints.
+
+        * wtf/HashTable.h: Added includes as needed and fixed include style.
+        (WTF::doubleHash): Removed the uneeeded and inappropriate "static" in this function, which
+        gave it internal linkage for no good reason.
+        (WTF::HashTable::checkKey): Made this use AlignedBuffer for the deleted value check to avoid
+        construction/destruction problems instead of doing the trick where we construct and destroy
+        an empty value twice. It's cleaner and simpler and avoids copying the empty value.
+        (WTF::HashTable::initializeBucket): Specialized initializeBucket to use memset when the
+        empty value is zero rather than copying an empty value.
+
+        * wtf/Vector.h: Moved the AlignedBufferChar and AlignedBuffer types into Alignment.h.
+
 2011-11-09  Gabor Rapcsanyi  <rga...@webkit.org>
 
         Buildfix for 32bit debug mode.

Modified: trunk/Source/_javascript_Core/wtf/Alignment.h (99732 => 99733)


--- trunk/Source/_javascript_Core/wtf/Alignment.h	2011-11-09 18:07:12 UTC (rev 99732)
+++ trunk/Source/_javascript_Core/wtf/Alignment.h	2011-11-09 18:11:47 UTC (rev 99733)
@@ -21,8 +21,11 @@
 #ifndef WTF_Alignment_h
 #define WTF_Alignment_h
 
-#include <wtf/Platform.h>
+#include "Platform.h"
+#include <algorithm>
 
+namespace WTF {
+
 #if COMPILER(GCC) || COMPILER(MINGW) || COMPILER(RVCT) || COMPILER(WINSCW) || COMPILER(GCCE)
     #define WTF_ALIGN_OF(type) __alignof__(type)
     #define WTF_ALIGNED(variable_type, variable, n) variable_type variable __attribute__((__aligned__(n)))
@@ -33,4 +36,28 @@
     #error WTF_ALIGN macros need alignment control.
 #endif
 
+#if COMPILER(GCC) && !COMPILER(INTEL) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
+    typedef char __attribute__((__may_alias__)) AlignedBufferChar; 
+#else
+    typedef char AlignedBufferChar; 
+#endif
+
+    template<size_t size, size_t alignment> struct AlignedBuffer;
+    template<size_t size> struct AlignedBuffer<size, 1> { AlignedBufferChar buffer[size]; };
+    template<size_t size> struct AlignedBuffer<size, 2> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 2);  };
+    template<size_t size> struct AlignedBuffer<size, 4> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 4);  };
+    template<size_t size> struct AlignedBuffer<size, 8> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 8);  };
+    template<size_t size> struct AlignedBuffer<size, 16> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 16); };
+    template<size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); };
+    template<size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); };
+
+    template <size_t size, size_t alignment>
+    void swap(AlignedBuffer<size, alignment>& a, AlignedBuffer<size, alignment>& b)
+    {
+        for (size_t i = 0; i < size; ++i)
+            std::swap(a.buffer[i], b.buffer[i]);
+    }
+
+}
+
 #endif // WTF_Alignment_h

Modified: trunk/Source/_javascript_Core/wtf/HashTable.h (99732 => 99733)


--- trunk/Source/_javascript_Core/wtf/HashTable.h	2011-11-09 18:07:12 UTC (rev 99732)
+++ trunk/Source/_javascript_Core/wtf/HashTable.h	2011-11-09 18:11:47 UTC (rev 99733)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2005, 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
  * Copyright (C) 2008 David Levin <le...@chromium.org>
  *
  * This library is free software; you can redistribute it and/or
@@ -22,11 +22,13 @@
 #ifndef WTF_HashTable_h
 #define WTF_HashTable_h
 
+#include "Alignment.h"
+#include "Assertions.h"
 #include "FastMalloc.h"
 #include "HashTraits.h"
+#include "StdLibExtras.h"
+#include "Threading.h"
 #include "ValueCheck.h"
-#include <wtf/Assertions.h>
-#include <wtf/Threading.h>
 
 namespace WTF {
 
@@ -384,7 +386,7 @@
         void rehash(int newTableSize);
         void reinsert(ValueType&);
 
-        static void initializeBucket(ValueType& bucket) { new (&bucket) ValueType(Traits::emptyValue()); }
+        static void initializeBucket(ValueType& bucket);
         static void deleteBucket(ValueType& bucket) { bucket.~ValueType(); Traits::constructDeletedValue(bucket); }
 
         FullLookupType makeLookupResult(ValueType* position, bool found, unsigned hash)
@@ -437,7 +439,7 @@
     {
     }
 
-    static inline unsigned doubleHash(unsigned key)
+    inline unsigned doubleHash(unsigned key)
     {
         key = ~key + (key >> 23);
         key ^= (key << 12);
@@ -464,11 +466,10 @@
         if (!HashFunctions::safeToCompareToEmptyOrDeleted)
             return;
         ASSERT(!HashTranslator::equal(KeyTraits::emptyValue(), key));
-        ValueType deletedValue = Traits::emptyValue();
-        deletedValue.~ValueType();
+        AlignedBuffer<sizeof(ValueType), WTF_ALIGN_OF(ValueType)> deletedValueBuffer;
+        ValueType& deletedValue = *reinterpret_cast_ptr<ValueType*>(deletedValueBuffer.buffer);
         Traits::constructDeletedValue(deletedValue);
         ASSERT(!HashTranslator::equal(Extractor::extract(deletedValue), key));
-        new (&deletedValue) ValueType(Traits::emptyValue());
     }
 
 #endif
@@ -624,7 +625,32 @@
         }
     }
 
+    template<bool emptyValueIsZero> struct HashTableBucketInitializer;
+
+    template<> struct HashTableBucketInitializer<false> {
+        template<typename Traits, typename Value> static void initialize(Value& bucket)
+        {
+            new (&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(&bucket, 0, sizeof(bucket));
+        }
+    };
+    
     template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
+    inline void HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::initializeBucket(ValueType& bucket)
+    {
+        HashTableBucketInitializer<Traits::emptyValueIsZero>::template initialize<Traits>(bucket);
+    }
+
+    template<typename Key, typename Value, typename Extractor, typename HashFunctions, typename Traits, typename KeyTraits>
     template<typename T, typename Extra, typename HashTranslator>
     inline pair<typename HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::iterator, bool> HashTable<Key, Value, Extractor, HashFunctions, Traits, KeyTraits>::add(const T& key, const Extra& extra)
     {

Modified: trunk/Source/_javascript_Core/wtf/Vector.h (99732 => 99733)


--- trunk/Source/_javascript_Core/wtf/Vector.h	2011-11-09 18:07:12 UTC (rev 99732)
+++ trunk/Source/_javascript_Core/wtf/Vector.h	2011-11-09 18:11:47 UTC (rev 99733)
@@ -21,6 +21,7 @@
 #ifndef WTF_Vector_h
 #define WTF_Vector_h
 
+#include "Alignment.h"
 #include "FastAllocBase.h"
 #include "Noncopyable.h"
 #include "NotFound.h"
@@ -29,7 +30,6 @@
 #include "VectorTraits.h"
 #include <limits>
 #include <utility>
-#include <wtf/Alignment.h>
 
 #if PLATFORM(QT)
 #include <QDataStream>
@@ -40,28 +40,6 @@
     using std::min;
     using std::max;
 
-    #if COMPILER(GCC) && !COMPILER(INTEL) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 303)
-        typedef char __attribute__((__may_alias__)) AlignedBufferChar; 
-    #else
-        typedef char AlignedBufferChar; 
-    #endif
-
-    template <size_t size, size_t alignment> struct AlignedBuffer;
-    template <size_t size> struct AlignedBuffer<size, 1> { AlignedBufferChar buffer[size]; };
-    template <size_t size> struct AlignedBuffer<size, 2> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 2);  };
-    template <size_t size> struct AlignedBuffer<size, 4> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 4);  };
-    template <size_t size> struct AlignedBuffer<size, 8> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 8);  };
-    template <size_t size> struct AlignedBuffer<size, 16> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 16); };
-    template <size_t size> struct AlignedBuffer<size, 32> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 32); };
-    template <size_t size> struct AlignedBuffer<size, 64> { WTF_ALIGNED(AlignedBufferChar, buffer[size], 64); };
-
-    template <size_t size, size_t alignment>
-    void swap(AlignedBuffer<size, alignment>& a, AlignedBuffer<size, alignment>& b)
-    {
-        for (size_t i = 0; i < size; ++i)
-            std::swap(a.buffer[i], b.buffer[i]);
-    }
-
     template <bool needsDestruction, typename T>
     struct VectorDestructor;
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to