Reviewed by Darin.
authormjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Sep 2007 05:01:03 +0000 (05:01 +0000)
committermjs <mjs@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 5 Sep 2007 05:01:03 +0000 (05:01 +0000)
        - Added Vector::appendRange(), which appends to a vector based on a given start and end iterator
        - Added keys() and values() functions to HashMap iterators, which give keys-only and values-only iterators

        Together, these allow easy copying of a set, or the keys or values of a map, into a Vector. Examples:

        HashMap<int, int> map;
        HashSet<int> set;
        Vector<int> vec;
        // ...
        vec.appendRange(set.begin(), set.end());
        vec.appendRange(map.begin().keys(), map.end().keys());
        vec.appendRange(map.begin().values(), map.end().values());

        This also allows for a slightly nicer syntax when iterating a map. Instead of saying
        (*it)->first, you can say *it.values(). Similarly for keys. Example:

        HashMap<int, int>::const_iterator end = map.end();
        for (HashMap<int, int>::const_iterator it = map.begin(); it != end; ++it)
        printf(" [%d => %d]", *it.keys(), *it.values());

        * JavaScriptCore.xcodeproj/project.pbxproj:
        * wtf/HashIterators.h: Added.
        (WTF::):
        (WTF::HashTableConstKeysIterator::HashTableConstKeysIterator):
        (WTF::HashTableConstKeysIterator::get):
        (WTF::HashTableConstKeysIterator::operator*):
        (WTF::HashTableConstKeysIterator::operator->):
        (WTF::HashTableConstKeysIterator::operator++):
        (WTF::HashTableConstValuesIterator::HashTableConstValuesIterator):
        (WTF::HashTableConstValuesIterator::get):
        (WTF::HashTableConstValuesIterator::operator*):
        (WTF::HashTableConstValuesIterator::operator->):
        (WTF::HashTableConstValuesIterator::operator++):
        (WTF::HashTableKeysIterator::HashTableKeysIterator):
        (WTF::HashTableKeysIterator::get):
        (WTF::HashTableKeysIterator::operator*):
        (WTF::HashTableKeysIterator::operator->):
        (WTF::HashTableKeysIterator::operator++):
        (WTF::HashTableKeysIterator::operator HashTableConstKeysIterator<HashTableType, KeyType, MappedType>):
        (WTF::HashTableValuesIterator::HashTableValuesIterator):
        (WTF::HashTableValuesIterator::get):
        (WTF::HashTableValuesIterator::operator*):
        (WTF::HashTableValuesIterator::operator->):
        (WTF::HashTableValuesIterator::operator++):
        (WTF::HashTableValuesIterator::operator HashTableConstValuesIterator<HashTableType, KeyType, MappedType>):
        (WTF::operator==):
        (WTF::operator!=):
        * wtf/HashTable.h:
        * wtf/Vector.h:
        (WTF::::appendRange):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@25365 268f45cc-cd09-0410-ab3c-d52691b4dbfc

JavaScriptCore/ChangeLog
JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
JavaScriptCore/kjs/collector.cpp
JavaScriptCore/wtf/FastMalloc.cpp
JavaScriptCore/wtf/FastMallocInternal.h [deleted file]
JavaScriptCore/wtf/HashIterators.h [new file with mode: 0644]
JavaScriptCore/wtf/HashMap.h
JavaScriptCore/wtf/HashSet.h
JavaScriptCore/wtf/HashTable.h
JavaScriptCore/wtf/Vector.h

index ddca815..af17f61 100644 (file)
@@ -1,3 +1,79 @@
+2007-09-04  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin.
+        
+        - Added Vector::appendRange(), which appends to a vector based on a given start and end iterator
+        - Added keys() and values() functions to HashMap iterators, which give keys-only and values-only iterators
+        
+        Together, these allow easy copying of a set, or the keys or values of a map, into a Vector. Examples:
+        
+        HashMap<int, int> map;
+        HashSet<int> set;
+        Vector<int> vec;
+        // ...
+        vec.appendRange(set.begin(), set.end());
+        vec.appendRange(map.begin().keys(), map.end().keys());
+        vec.appendRange(map.begin().values(), map.end().values());
+
+        This also allows for a slightly nicer syntax when iterating a map. Instead of saying 
+        (*it)->first, you can say *it.values(). Similarly for keys. Example:
+        
+        HashMap<int, int>::const_iterator end = map.end();
+        for (HashMap<int, int>::const_iterator it = map.begin(); it != end; ++it)
+        printf(" [%d => %d]", *it.keys(), *it.values());
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * wtf/HashIterators.h: Added.
+        (WTF::):
+        (WTF::HashTableConstKeysIterator::HashTableConstKeysIterator):
+        (WTF::HashTableConstKeysIterator::get):
+        (WTF::HashTableConstKeysIterator::operator*):
+        (WTF::HashTableConstKeysIterator::operator->):
+        (WTF::HashTableConstKeysIterator::operator++):
+        (WTF::HashTableConstValuesIterator::HashTableConstValuesIterator):
+        (WTF::HashTableConstValuesIterator::get):
+        (WTF::HashTableConstValuesIterator::operator*):
+        (WTF::HashTableConstValuesIterator::operator->):
+        (WTF::HashTableConstValuesIterator::operator++):
+        (WTF::HashTableKeysIterator::HashTableKeysIterator):
+        (WTF::HashTableKeysIterator::get):
+        (WTF::HashTableKeysIterator::operator*):
+        (WTF::HashTableKeysIterator::operator->):
+        (WTF::HashTableKeysIterator::operator++):
+        (WTF::HashTableKeysIterator::operator HashTableConstKeysIterator<HashTableType, KeyType, MappedType>):
+        (WTF::HashTableValuesIterator::HashTableValuesIterator):
+        (WTF::HashTableValuesIterator::get):
+        (WTF::HashTableValuesIterator::operator*):
+        (WTF::HashTableValuesIterator::operator->):
+        (WTF::HashTableValuesIterator::operator++):
+        (WTF::HashTableValuesIterator::operator HashTableConstValuesIterator<HashTableType, KeyType, MappedType>):
+        (WTF::operator==):
+        (WTF::operator!=):
+        * wtf/HashTable.h:
+        * wtf/Vector.h:
+        (WTF::::appendRange):
+
+2007-09-04  Maciej Stachowiak  <mjs@apple.com>
+
+        Reviewed by Darin.
+        
+        - Remove single-threaded optimization for FastMalloc. 
+        
+        It does not appear to help anywhere but Mac OS X on PPC, due to
+        pthread_getspecific being slow there. On Intel, removing the
+        optimization results in a 1% PLT speedup, a 2% JS iBench speedup,
+        and no measurable effect on HTML iBench (maybe a slight speedup).
+
+        * JavaScriptCore.xcodeproj/project.pbxproj:
+        * kjs/collector.cpp:
+        (KJS::Collector::registerThread):
+        * wtf/FastMalloc.cpp:
+        (WTF::TCMalloc_ThreadCache::GetCache):
+        (WTF::TCMalloc_ThreadCache::GetCacheIfPresent):
+        (WTF::TCMalloc_ThreadCache::CreateCacheIfNecessary):
+        (WTF::do_malloc):
+        * wtf/FastMallocInternal.h: Removed.
+
 2007-09-03  Mark Rowe  <mrowe@apple.com>
 
         Reviewed by Tim Hatcher.
index 72d2f99..c3e6d2d 100644 (file)
@@ -83,6 +83,7 @@
                51F648D70BB4E2CA0033D760 /* RetainPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 51F648D60BB4E2CA0033D760 /* RetainPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5DBD18AC0C54018700C15EAE /* CollectorHeapIntrospector.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD18AA0C54018700C15EAE /* CollectorHeapIntrospector.h */; };
                5DBD18B00C5401A700C15EAE /* MallocZoneSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */; };
+               652246A50C8D7A0E007BDAF7 /* HashIterators.h in Headers */ = {isa = PBXBuildFile; fileRef = 652246A40C8D7A0E007BDAF7 /* HashIterators.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65400C120A69BAF200509887 /* PropertyNameArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 65400C100A69BAF200509887 /* PropertyNameArray.h */; settings = {ATTRIBUTES = (Private, ); }; };
                6541BD7208E80A17002CBEE7 /* TCPageMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6E08E80A17002CBEE7 /* TCPageMap.h */; };
                6541BD7308E80A17002CBEE7 /* TCSpinLock.h in Headers */ = {isa = PBXBuildFile; fileRef = 6541BD6F08E80A17002CBEE7 /* TCSpinLock.h */; };
                65C647B4093EF8D60022C380 /* RefPtr.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C647B3093EF8D60022C380 /* RefPtr.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65C7A1740A8EAACB00FA37EA /* JSWrapperObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65D6D87F09B5A32E0002E4D7 /* Platform.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D6D87E09B5A32E0002E4D7 /* Platform.h */; settings = {ATTRIBUTES = (Private, ); }; };
-               65D7D19C08F10B5B0015ABD8 /* FastMallocInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */; };
                65DFC93008EA173A00F7300B /* HashFunctions.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92A08EA173A00F7300B /* HashFunctions.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65DFC93108EA173A00F7300B /* HashMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92B08EA173A00F7300B /* HashMap.h */; settings = {ATTRIBUTES = (Private, ); }; };
                65DFC93208EA173A00F7300B /* HashSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 65DFC92C08EA173A00F7300B /* HashSet.h */; settings = {ATTRIBUTES = (Private, ); }; };
                5DBD18AF0C5401A700C15EAE /* MallocZoneSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MallocZoneSupport.h; sourceTree = "<group>"; };
                651F6412039D5B5F0078395C /* dtoa.cpp */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.cpp.cpp; path = dtoa.cpp; sourceTree = "<group>"; tabWidth = 8; };
                651F6413039D5B5F0078395C /* dtoa.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = dtoa.h; sourceTree = "<group>"; tabWidth = 8; };
+               652246A40C8D7A0E007BDAF7 /* HashIterators.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HashIterators.h; sourceTree = "<group>"; };
                65400C0F0A69BAF200509887 /* PropertyNameArray.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = PropertyNameArray.cpp; sourceTree = "<group>"; };
                65400C100A69BAF200509887 /* PropertyNameArray.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PropertyNameArray.h; sourceTree = "<group>"; };
                6541720E039E08B90058BFEB /* dftables.c */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.c; name = dftables.c; path = pcre/dftables.c; sourceTree = "<group>"; tabWidth = 8; };
                65C7A1710A8EAACB00FA37EA /* JSWrapperObject.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = JSWrapperObject.cpp; sourceTree = "<group>"; };
                65C7A1720A8EAACB00FA37EA /* JSWrapperObject.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = JSWrapperObject.h; sourceTree = "<group>"; };
                65D6D87E09B5A32E0002E4D7 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = "<group>"; };
-               65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = FastMallocInternal.h; sourceTree = "<group>"; tabWidth = 8; };
                65DFC92A08EA173A00F7300B /* HashFunctions.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashFunctions.h; sourceTree = "<group>"; tabWidth = 8; };
                65DFC92B08EA173A00F7300B /* HashMap.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashMap.h; sourceTree = "<group>"; tabWidth = 8; };
                65DFC92C08EA173A00F7300B /* HashSet.h */ = {isa = PBXFileReference; fileEncoding = 30; indentWidth = 4; lastKnownFileType = sourcecode.c.h; path = HashSet.h; sourceTree = "<group>"; tabWidth = 8; };
                65162EF108E6A21C007556CD /* wtf */ = {
                        isa = PBXGroup;
                        children = (
+                               652246A40C8D7A0E007BDAF7 /* HashIterators.h */,
                                E195678D09E7CF1200B89D13 /* unicode */,
                                93AA4F770957251F0084B3A7 /* AlwaysInline.h */,
                                65E217B808E7EECC0023E5F6 /* Assertions.cpp */,
                                65E217B708E7EECC0023E5F6 /* Assertions.h */,
                                65E217B908E7EECC0023E5F6 /* FastMalloc.cpp */,
                                65E217BA08E7EECC0023E5F6 /* FastMalloc.h */,
-                               65D7D19B08F10B5B0015ABD8 /* FastMallocInternal.h */,
                                9302043A0B790750000C6115 /* FastMallocPCRE.cpp */,
                                935AF46909E9D9DB00ACD1D8 /* Forward.h */,
                                93B6A0DE0AA64DA40076DE27 /* GetPtr.h */,
                                65DFC93208EA173A00F7300B /* HashSet.h in Headers */,
                                65DFC93408EA173A00F7300B /* HashTable.h in Headers */,
                                65DFC93508EA173A00F7300B /* HashTraits.h in Headers */,
-                               65D7D19C08F10B5B0015ABD8 /* FastMallocInternal.h in Headers */,
                                65EA4C9C092AF9E20093D800 /* JSLock.h in Headers */,
                                65C647B4093EF8D60022C380 /* RefPtr.h in Headers */,
                                6580F796094070560082C219 /* PassRefPtr.h in Headers */,
                                51F648D70BB4E2CA0033D760 /* RetainPtr.h in Headers */,
                                5DBD18AC0C54018700C15EAE /* CollectorHeapIntrospector.h in Headers */,
                                5DBD18B00C5401A700C15EAE /* MallocZoneSupport.h in Headers */,
+                               652246A50C8D7A0E007BDAF7 /* HashIterators.h in Headers */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
index dca1579..cedcce5 100644 (file)
@@ -29,7 +29,6 @@
 #include <setjmp.h>
 #include <stdlib.h>
 #include <wtf/FastMalloc.h>
-#include <wtf/FastMallocInternal.h>
 #include <wtf/HashCountedSet.h>
 #include <wtf/UnusedParam.h>
 
@@ -400,11 +399,9 @@ void Collector::registerThread()
   pthread_once(&registeredThreadKeyOnce, initializeRegisteredThreadKey);
 
   if (!pthread_getspecific(registeredThreadKey)) {
-    if (!onMainThread())
-        WTF::fastMallocSetIsMultiThreaded();
 #if PLATFORM(DARWIN)
-    else
-        CollectorHeapIntrospector::init(&heap);
+      if (onMainThread())
+          CollectorHeapIntrospector::init(&heap);
 #endif
 
     Collector::Thread *thread = new Collector::Thread(pthread_self(), getCurrentPlatformThread());
index c29ef6d..3b2ee89 100644 (file)
@@ -160,10 +160,6 @@ void *fastRealloc(void* p, size_t n)
     return realloc(p, n);
 }
 
-void fastMallocSetIsMultiThreaded() 
-{
-}
-
 } // namespace WTF
 
 #if PLATFORM(DARWIN)
@@ -1550,54 +1546,13 @@ inline void TCMalloc_ThreadCache::Scavenge() {
 #endif
 }
 
-#ifdef WTF_CHANGES
-bool isMultiThreaded;
-TCMalloc_ThreadCache *mainThreadCache;
-
-void fastMallocSetIsMultiThreaded()
-{
-    // We lock when writing mainThreadCache but not when reading it. It's OK if
-    // the main thread reads a stale, non-NULL value for mainThreadCache because
-    // mainThreadCache is the same as the main thread's thread-specific cache.
-    // Other threads can't read a stale, non-NULL value for mainThreadCache because
-    // clients must call this function before allocating on other threads, so they'll 
-    // have synchronized before reading mainThreadCache.
-    
-    // A similar principle applies to isMultiThreaded. It's OK for the main thread
-    // in GetCache() to read a stale, false value for isMultiThreaded because 
-    // doing so will just cause it to make an unnecessary call to InitModule(),
-    // which will synchronize it.
-
-    // To save a branch in some cases, mainThreadCache is only set when 
-    // isMultiThreaded is false.
-
-    {
-        SpinLockHolder lock(&pageheap_lock);
-        isMultiThreaded = true;
-        mainThreadCache = 0;
-    }
-
-    TCMalloc_ThreadCache::InitModule();
-}
-#endif
-
 ALWAYS_INLINE TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCache() {
   void* ptr = NULL;
-#ifndef WTF_CHANGES
   if (!tsd_inited) {
     InitModule();
   } else {
     ptr = pthread_getspecific(heap_key);
   }
-#else
-  if (mainThreadCache) // fast path for single-threaded mode
-    return mainThreadCache;
-
-  if (isMultiThreaded) // fast path for multi-threaded mode -- heap_key already initialized
-    ptr = pthread_getspecific(heap_key);
-  else // slow path for possible first-time init
-    InitModule();
-#endif
   if (ptr == NULL) ptr = CreateCacheIfNecessary();
   return reinterpret_cast<TCMalloc_ThreadCache*>(ptr);
 }
@@ -1606,8 +1561,6 @@ ALWAYS_INLINE TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCache() {
 // because we may be in the thread destruction code and may have
 // already cleaned up the cache for this thread.
 inline TCMalloc_ThreadCache* TCMalloc_ThreadCache::GetCacheIfPresent() {
-  if (mainThreadCache)
-      return mainThreadCache;
   if (!tsd_inited) return NULL;
   return reinterpret_cast<TCMalloc_ThreadCache*>
     (pthread_getspecific(heap_key));
@@ -1709,8 +1662,6 @@ void* TCMalloc_ThreadCache::CreateCacheIfNecessary() {
       thread_heaps = heap;
       thread_heap_count++;
       RecomputeThreadCacheSize(); 
-      if (!isMultiThreaded)
-        mainThreadCache = heap;
     }
   }
 
@@ -2041,7 +1992,6 @@ static Span* DoSampledAllocation(size_t size) {
 static ALWAYS_INLINE void* do_malloc(size_t size) {
 
 #ifdef WTF_CHANGES
-    ASSERT(isMultiThreaded || pthread_main_np());
     ASSERT(!isForbidden());
 #endif
 
diff --git a/JavaScriptCore/wtf/FastMallocInternal.h b/JavaScriptCore/wtf/FastMallocInternal.h
deleted file mode 100644 (file)
index c40b353..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-// -*- mode: c++; c-basic-offset: 4 -*-
-/*
- *  This file is part of the KDE libraries
- *  Copyright (C) 2005 Apple Computer, Inc.
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public
- *  License as published by the Free Software Foundation; either
- *  version 2 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public License
- *  along with this library; see the file COPYING.LIB.  If not, write to
- *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- *  Boston, MA 02110-1301, USA.
- *
- */
-
-#ifndef WTF_FastMallocInternal_h
-#define WTF_FastMallocInternal_h
-
-namespace WTF {
-    // Clients must call this function before allocating memory on a secondary thread.
-    void fastMallocSetIsMultiThreaded();
-}
-
-#endif //  WTF_FastMallocInternal_h
diff --git a/JavaScriptCore/wtf/HashIterators.h b/JavaScriptCore/wtf/HashIterators.h
new file mode 100644 (file)
index 0000000..c449112
--- /dev/null
@@ -0,0 +1,217 @@
+// -*- mode: c++; c-basic-offset: 4 -*-
+/*
+ * Copyright (C) 2007 Apple Inc.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
+ */
+
+#ifndef WTF_HashIterators_h
+#define WTF_HashIterators_h
+
+namespace WTF {
+
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstKeysIterator;
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstValuesIterator;
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableKeysIterator;
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableValuesIterator;
+
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > {
+    private:
+        typedef std::pair<KeyType, MappedType> ValueType;
+    public:
+        typedef HashTableConstKeysIterator<HashTableType, KeyType, MappedType> Keys;
+        typedef HashTableConstValuesIterator<HashTableType, KeyType, MappedType> Values;
+
+        HashTableConstIteratorAdapter(const typename HashTableType::const_iterator& impl) : m_impl(impl) {}
+
+        const ValueType* get() const { return (const ValueType*)m_impl.get(); }
+        const ValueType& operator*() const { return *get(); }
+        const ValueType* operator->() const { return get(); }
+
+        HashTableConstIteratorAdapter& operator++() { ++m_impl; return *this; }
+        // postfix ++ intentionally omitted
+
+        Keys keys() { return Keys(*this); }
+        Values values() { return Values(*this); }
+
+        typename HashTableType::const_iterator m_impl;
+    };
+
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > {
+    private:
+        typedef std::pair<KeyType, MappedType> ValueType;
+    public:
+        typedef HashTableKeysIterator<HashTableType, KeyType, MappedType> Keys;
+        typedef HashTableValuesIterator<HashTableType, KeyType, MappedType> Values;
+
+        HashTableIteratorAdapter(const typename HashTableType::iterator& impl) : m_impl(impl) {}
+
+        ValueType* get() const { return (ValueType*)m_impl.get(); }
+        ValueType& operator*() const { return *get(); }
+        ValueType* operator->() const { return get(); }
+
+        HashTableIteratorAdapter& operator++() { ++m_impl; return *this; }
+        // postfix ++ intentionally omitted
+
+        operator HashTableConstIteratorAdapter<HashTableType, ValueType>() {
+            typename HashTableType::const_iterator i = m_impl;
+            return i;
+        }
+
+        Keys keys() { return Keys(*this); }
+        Values values() { return Values(*this); }
+
+        typename HashTableType::iterator m_impl;
+    };
+
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstKeysIterator {
+    private:
+        typedef HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > ConstIterator;
+
+    public:
+        HashTableConstKeysIterator(const ConstIterator& impl) : m_impl(impl) {}
+        
+        const KeyType* get() const { return &(m_impl.get()->first); }
+        const KeyType& operator*() const { return *get(); }
+        const KeyType* operator->() const { return get(); }
+
+        HashTableConstKeysIterator& operator++() { ++m_impl; return *this; }
+        // postfix ++ intentionally omitted
+
+        ConstIterator m_impl;
+    };
+
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableConstValuesIterator {
+    private:
+        typedef HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > ConstIterator;
+
+    public:
+        HashTableConstValuesIterator(const ConstIterator& impl) : m_impl(impl) {}
+        
+        const MappedType* get() const { return &(m_impl.get()->second); }
+        const MappedType& operator*() const { return *get(); }
+        const MappedType* operator->() const { return get(); }
+
+        HashTableConstValuesIterator& operator++() { ++m_impl; return *this; }
+        // postfix ++ intentionally omitted
+
+        ConstIterator m_impl;
+    };
+
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableKeysIterator {
+    private:
+        typedef HashTableIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > Iterator;
+        typedef HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > ConstIterator;
+
+    public:
+        HashTableKeysIterator(const Iterator& impl) : m_impl(impl) {}
+        
+        KeyType* get() const { return &(m_impl.get()->first); }
+        KeyType& operator*() const { return *get(); }
+        KeyType* operator->() const { return get(); }
+
+        HashTableKeysIterator& operator++() { ++m_impl; return *this; }
+        // postfix ++ intentionally omitted
+
+        operator HashTableConstKeysIterator<HashTableType, KeyType, MappedType>() {
+            ConstIterator i = m_impl;
+            return i;
+        }
+
+        Iterator m_impl;
+    };
+
+    template<typename HashTableType, typename KeyType, typename MappedType> struct HashTableValuesIterator {
+    private:
+        typedef HashTableIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > Iterator;
+        typedef HashTableConstIteratorAdapter<HashTableType, std::pair<KeyType, MappedType> > ConstIterator;
+
+    public:
+        HashTableValuesIterator(const Iterator& impl) : m_impl(impl) {}
+        
+        MappedType* get() const { return &(m_impl.get()->second); }
+        MappedType& operator*() const { return *get(); }
+        MappedType* operator->() const { return get(); }
+
+        HashTableValuesIterator& operator++() { ++m_impl; return *this; }
+        // postfix ++ intentionally omitted
+
+        operator HashTableConstValuesIterator<HashTableType, KeyType, MappedType>() {
+            ConstIterator i = m_impl;
+            return i;
+        }
+
+        Iterator m_impl;
+    };
+
+    template<typename T, typename U, typename V>
+        inline bool operator==(const HashTableConstKeysIterator<T, U, V>& a, const HashTableConstKeysIterator<T, U, V>& b)
+    {
+        return a.m_impl == b.m_impl;
+    }
+
+    template<typename T, typename U, typename V>
+        inline bool operator!=(const HashTableConstKeysIterator<T, U, V>& a, const HashTableConstKeysIterator<T, U, V>& b)
+    {
+        return a.m_impl != b.m_impl;
+    }
+
+    template<typename T, typename U, typename V>
+        inline bool operator==(const HashTableConstValuesIterator<T, U, V>& a, const HashTableConstValuesIterator<T, U, V>& b)
+    {
+        return a.m_impl == b.m_impl;
+    }
+
+    template<typename T, typename U, typename V>
+        inline bool operator!=(const HashTableConstValuesIterator<T, U, V>& a, const HashTableConstValuesIterator<T, U, V>& b)
+    {
+        return a.m_impl != b.m_impl;
+    }
+
+    template<typename T, typename U, typename V>
+        inline bool operator==(const HashTableKeysIterator<T, U, V>& a, const HashTableKeysIterator<T, U, V>& b)
+    {
+        return a.m_impl == b.m_impl;
+    }
+
+    template<typename T, typename U, typename V>
+        inline bool operator!=(const HashTableKeysIterator<T, U, V>& a, const HashTableKeysIterator<T, U, V>& b)
+    {
+        return a.m_impl != b.m_impl;
+    }
+
+    template<typename T, typename U, typename V>
+        inline bool operator==(const HashTableValuesIterator<T, U, V>& a, const HashTableValuesIterator<T, U, V>& b)
+    {
+        return a.m_impl == b.m_impl;
+    }
+
+    template<typename T, typename U, typename V>
+        inline bool operator!=(const HashTableValuesIterator<T, U, V>& a, const HashTableValuesIterator<T, U, V>& b)
+    {
+        return a.m_impl != b.m_impl;
+    }
+
+
+} // namespace WTF
+
+#endif // WTF_HashIterators_h
index 76474de..1c6c116 100644 (file)
@@ -25,6 +25,7 @@
 #define WTF_HashMap_h
 
 #include "HashTable.h"
+#include "Vector.h"
 
 namespace WTF {
 
@@ -375,6 +376,19 @@ namespace WTF {
     {
         deleteAllPairFirsts<typename HashMap<T, U, V, W, X>::KeyType>(collection);
     }
+    
+    template<typename T, typename U, typename V, typename W, typename X>
+    inline void copyValuesToVector(const HashMap<T, U, V, W, X>& collection, Vector<U>& vector)
+    {
+        typedef typename HashMap<T, U, V, W, X>::const_iterator iterator;
+        
+        vector.resize(collection.size());
+        
+        iterator it = collection.begin();
+        iterator end = collection.end();
+        for (unsigned i = 0; it != end; ++it, ++i)
+            vector[i] = (*it).second;
+    }   
 
 } // namespace WTF
 
index 2cac61b..59009dc 100644 (file)
@@ -25,6 +25,7 @@
 #define WTF_HashSet_h
 
 #include "HashTable.h"
+#include "Vector.h"
 
 namespace WTF {
 
@@ -314,7 +315,19 @@ namespace WTF {
     {
         deleteAllValues<typename HashSet<T, U, V>::ValueType>(collection.m_impl);
     }
-
+    
+    template<typename T, typename U, typename V>
+    inline void copyToVector(const HashSet<T, U, V>& collection, Vector<T>& vector)
+    {
+        typedef typename HashSet<T, U, V>::const_iterator iterator;
+        
+        vector.resize(collection.size());
+        
+        iterator it = collection.begin();
+        iterator end = collection.end();
+        for (unsigned i = 0; it != end; ++it, ++i)
+            vector[i] = *it;
+    }  
 } // namespace WTF
 
 using WTF::HashSet;
index b3c9647..e966c13 100644 (file)
@@ -969,4 +969,6 @@ namespace WTF {
 
 } // namespace WTF
 
+#include "HashIterators.h"
+
 #endif // WTF_HashTable_h
index 713249e..317c0dc 100644 (file)
@@ -458,6 +458,8 @@ namespace WTF {
         void fill(const T&, size_t);
         void fill(const T& val) { fill(val, size()); }
 
+        template<typename Iterator> void appendRange(Iterator start, Iterator end);
+
         T* releaseBuffer();
 
         void swap(Vector<T, inlineCapacity>& other)
@@ -549,6 +551,14 @@ namespace WTF {
     }
 
     template<typename T, size_t inlineCapacity>
+    template<typename Iterator>
+    void Vector<T, inlineCapacity>::appendRange(Iterator start, Iterator end)
+    {
+        for (Iterator it = start; it != end; ++it)
+            append(*it);
+    }
+
+    template<typename T, size_t inlineCapacity>
     void Vector<T, inlineCapacity>::expandCapacity(size_t newMinCapacity)
     {
         reserveCapacity(max(newMinCapacity, max(static_cast<size_t>(16), capacity() + capacity() / 4 + 1)));