Changeset 21175 in webkit for trunk/JavaScriptCore/wtf


Ignore:
Timestamp:
Apr 28, 2007, 9:25:33 PM (18 years ago)
Author:
darin
Message:

JavaScriptCore:

Reviewed by Maciej.

  • fix <rdar://problem/5154144> Hamachi test fails: assertion failure in ListHashSet

Test: fast/forms/add-remove-form-elements-stress-test.html

  • wtf/ListHashSet.h: (WTF::ListHashSetNodeAllocator::ListHashSetNodeAllocator): Initialize m_isDoneWithInitialFreeList to false. (WTF::ListHashSetNodeAllocator::allocate): Added assertions based on a debug-only m_isAllocated flag that make sure we don't allocate a block that's already allocated. These assertions helped pinpoint the bug. Set m_isDoneWithInitialFreeList when we allocate the last block of the initial free list. Once we're done with the initial free list, turn off the rule that says that the next node in the pool after the last node in the free list is also free. This rule works because any free nodes are added to the head of the free list, so a node that hasn't been allocated even once is always at the tail of the free list. But it doesn't work any longer once the entire pool has been used at least once. (WTF::ListHashSetNodeAllocator::deallocate): Set the node's m_isAllocated to false. (WTF::ListHashSetNodeAllocator::pastPool): Added. Used above. (WTF::ListHashSetNodeAllocator::inPool): Changed to use the pastPool function. (WTF::ListHashSetNode::ListHashSetNode): Initialize m_isAllocated to true. (WTF::ListHashSetNode::operator new): Removed variable name for unused size parameter. (WTF::ListHashSetNode::destroy): Changed to call the destructor rather than delete -- this gets rid of the need to define an operator delete.

LayoutTests:

Reviewed by Maciej.

  • test for <rdar://problem/5154144> Hamachi test fails: assertion failure in ListHashSet
  • fast/forms/add-remove-form-elements-stress-test-expected.txt: Added.
  • fast/forms/add-remove-form-elements-stress-test.html: Added.
File:
1 edited

Legend:

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

    r19365 r21175  
    11// -*- mode: c++; c-basic-offset: 4 -*-
    22/*
    3  * Copyright (C) 2005, 2006, 2007 Apple Inc.
     3 * Copyright (C) 2005, 2006, 2007 Apple Inc. All rights reserved.
    44 *
    55 * This library is free software; you can redistribute it and/or
     
    2323#define WTF_ListHashSet_h
    2424
     25#include "Assertions.h"
    2526#include "HashSet.h"
    2627#include "OwnPtr.h"
     
    2829namespace WTF {
    2930
    30     // ListHashSet: just like HashSet, this class provides a Set
     31    // ListHashSet: Just like HashSet, this class provides a Set
    3132    // interface - a collection of unique objects with O(1) insertion,
    3233    // removal and test for containership. However, it also has an
     
    120121        ListHashSetNodeAllocator()
    121122            : m_freeList(pool())
     123            , m_isDoneWithInitialFreeList(false)
    122124        {
    123125            memset(m_pool.pool, 0, sizeof(m_pool.pool));
     
    131133                return static_cast<Node*>(fastMalloc(sizeof(Node)));
    132134
     135            ASSERT(!result->m_isAllocated);
     136
    133137            Node* next = result->m_next;
    134             if (!next && inPool(result + 1))
     138            ASSERT(!next || !next->m_isAllocated);
     139            if (!next && !m_isDoneWithInitialFreeList) {
    135140                next = result + 1;
     141                if (next == pastPool()) {
     142                    m_isDoneWithInitialFreeList = true;
     143                    next = 0;
     144                } else {
     145                    ASSERT(inPool(next));
     146                    ASSERT(!next->m_isAllocated);
     147                }
     148            }
    136149            m_freeList = next;
    137            
     150
    138151            return result;
    139152        }
     
    142155        {
    143156            if (inPool(node)) {
     157#ifndef NDEBUG
     158                node->m_isAllocated = false;
     159#endif
    144160                node->m_next = m_freeList;
    145161                m_freeList = node;
     
    152168    private:
    153169        Node* pool() { return reinterpret_cast<Node*>(m_pool.pool); }
     170        Node* pastPool() { return pool() + m_poolSize; }
    154171
    155172        bool inPool(Node* node)
    156173        {
    157             return node >= pool() && node < pool() + m_poolSize;
     174            return node >= pool() && node < pastPool();
    158175        }
    159176
    160177        Node* m_freeList;
     178        bool m_isDoneWithInitialFreeList;
    161179        static const size_t m_poolSize = 256;
    162180        union {
     
    169187        typedef ListHashSetNodeAllocator<ValueArg> NodeAllocator;
    170188
    171         ListHashSetNode(ValueArg value) : m_value(value), m_prev(0), m_next(0) {}
    172 
    173         void* operator new(size_t s, NodeAllocator* allocator) { return allocator->allocate(); }
    174         void operator delete(void* p) { }
    175         void destroy(NodeAllocator* allocator) { delete this; allocator->deallocate(this); }
    176        
     189        ListHashSetNode(ValueArg value)
     190            : m_value(value)
     191            , m_prev(0)
     192            , m_next(0)
     193#ifndef NDEBUG
     194            , m_isAllocated(true)
     195#endif
     196        {
     197        }
     198
     199        void* operator new(size_t, NodeAllocator* allocator)
     200        {
     201            return allocator->allocate();
     202        }
     203        void destroy(NodeAllocator* allocator)
     204        {
     205            this->~ListHashSetNode();
     206            allocator->deallocate(this);
     207        }
     208
    177209        ValueArg m_value;
    178210        ListHashSetNode* m_prev;
    179211        ListHashSetNode* m_next;
     212
     213#ifndef NDEBUG
     214        bool m_isAllocated;
     215#endif
    180216    };
    181217
Note: See TracChangeset for help on using the changeset viewer.