Changeset 19352 in webkit for trunk/JavaScriptCore/wtf


Ignore:
Timestamp:
Feb 2, 2007, 1:09:59 AM (18 years ago)
Author:
mjs
Message:

Reviewed by Darin.


  • use a custom allocator for ListHashSet, to fix ~1% per regression using it for form control
  • wtf/ListHashSet.h: (WTF::ListHashSetNodeAllocator::ListHashSetNodeAllocator): (WTF::ListHashSetNodeAllocator::allocate): (WTF::ListHashSetNodeAllocator::deallocate): (WTF::ListHashSetNode::operator new): (WTF::ListHashSetNode::operator delete): (WTF::ListHashSetNode::destroy): (WTF::ListHashSetTranslator::translate): (WTF::::ListHashSet): (WTF::::~ListHashSet): (WTF::::add): (WTF::::unlinkAndDelete): (WTF::::deleteAllNodes):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/wtf/ListHashSet.h

    r19320 r19352  
    4949
    5050    template<typename ValueArg> struct ListHashSetNode;
     51    template<typename ValueArg> struct ListHashSetNodeAllocator;
    5152    template<typename ValueArg, typename HashArg> struct ListHashSetNodeHashFunctions;
    5253
     
    5455    private:
    5556        typedef ListHashSetNode<ValueArg> Node;
     57        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;
    5658
    5759        typedef HashTraits<Node*> NodeTraits;
     
    107109        Node* m_head;
    108110        Node* m_tail;
     111        NodeAllocator* m_allocator;
     112    };
     113
     114
     115    template<typename ValueArg> struct ListHashSetNodeAllocator {
     116        typedef ListHashSetNode<ValueArg> Node;
     117        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;
     118
     119        ListHashSetNodeAllocator()
     120            : m_freeList(pool())
     121        {
     122            memset(m_pool, 0, sizeof(m_pool)); 
     123        }
     124
     125        Node* allocate()
     126        {
     127            Node* result = m_freeList;
     128
     129            if (!result)
     130                return static_cast<Node*>(fastMalloc(sizeof(Node)));
     131
     132            Node* next = result->m_next;
     133            if (!next && inPool(result + 1))
     134                next = result + 1;
     135            m_freeList = next;
     136           
     137            return result;
     138        }
     139
     140        void deallocate(Node* node)
     141        {
     142            if (inPool(node)) {
     143                node->m_next = m_freeList;
     144                m_freeList = node;
     145                return;
     146            }
     147
     148            fastFree(node);
     149        }
     150       
     151
     152    private:
     153        Node* pool() { return reinterpret_cast<Node*>(m_pool.pool); }
     154        bool inPool(Node* node)
     155        {
     156            return reinterpret_cast<char*>(node) >= m_pool.pool && reinterpret_cast<char*>(node) < m_pool.pool + sizeof(m_pool.pool);
     157        }
     158
     159        Node* m_freeList;
     160        static const size_t m_poolSize = 256;
     161        union {
     162            char pool[sizeof(Node) * m_poolSize];
     163            double forAlignment;
     164        } m_pool;
    109165    };
    110166
    111167    template<typename ValueArg> struct ListHashSetNode {
    112         // FIXME: arguably this should use a recycling custom allocator
     168        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;
     169
    113170        ListHashSetNode(ValueArg value) : m_value(value), m_prev(0), m_next(0) {}
     171
     172        void* operator new(size_t s, NodeAllocator* allocator) { return allocator->allocate(); }
     173        void operator delete(void* p) { }
     174        void destroy(NodeAllocator* allocator) { delete this; allocator->deallocate(this); }
     175       
    114176        ValueArg m_value;
    115177        ListHashSetNode* m_prev;
     
    242304    private:
    243305        typedef ListHashSetNode<ValueType> Node;
     306        typedef ListHashSetNodeAllocator<ValueType> NodeAllocator;
    244307    public:
    245308        static unsigned hash(const ValueType& key) { return HashFunctions::hash(key); }
    246309        static bool equal(Node* const& a, const ValueType& b) { return HashFunctions::equal(a->m_value, b); }
    247         static void translate(Node*& location, const ValueType& key, const ValueType&, unsigned)
    248         {
    249             location = new Node(key);
     310        static void translate(Node*& location, const ValueType& key, NodeAllocator* allocator, unsigned)
     311        {
     312            location = new (allocator) Node(key);
    250313        }
    251314    };
     
    255318        : m_head(0)
    256319        , m_tail(0)
     320        , m_allocator(new NodeAllocator)
    257321    {
    258322    }
     
    280344    {
    281345        deleteAllNodes();
     346        delete m_allocator;
    282347    }
    283348
     
    356421    {
    357422        typedef ListHashSetTranslator<ValueType, HashFunctions> Translator;
    358         pair<typename ImplType::iterator, bool> result =  m_impl.template add<ValueType, ValueType, Translator>(value, value);
     423        pair<typename ImplType::iterator, bool> result =  m_impl.template add<ValueType, NodeAllocator*, Translator>(value, m_allocator);
    359424        if (result.second)
    360425            appendNode(*(result.first));
     
    407472        }
    408473
    409         delete node;
     474        node->destroy(m_allocator);
    410475    }
    411476
     
    434499
    435500        for (Node* node = m_head, *next = m_head->m_next; node; node = next, next = node ? node->m_next : 0)
    436             delete node;
     501            node->destroy(m_allocator);
    437502    }
    438503
Note: See TracChangeset for help on using the changeset viewer.