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;