Home | History | Annotate | Download | only in runtime
      1 /*
      2  * Copyright (C) 2009 Apple Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1. Redistributions of source code must retain the above copyright
      8  *    notice, this list of conditions and the following disclaimer.
      9  * 2. Redistributions in binary form must reproduce the above copyright
     10  *    notice, this list of conditions and the following disclaimer in the
     11  *    documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
     14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
     17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
     23  * THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #ifndef WeakGCMap_h
     27 #define WeakGCMap_h
     28 
     29 #include "Collector.h"
     30 #include <wtf/HashMap.h>
     31 
     32 namespace JSC {
     33 
     34 class JSCell;
     35 
     36 // A HashMap whose get() function returns emptyValue() for cells awaiting destruction.
     37 template<typename KeyType, typename MappedType>
     38 class WeakGCMap : public FastAllocBase {
     39     /*
     40     Invariants:
     41         * A value enters the WeakGCMap marked. (Guaranteed by set().)
     42         * A value that becomes unmarked leaves the WeakGCMap before being recycled. (Guaranteed by the value's destructor removing it from the WeakGCMap.)
     43         * A value that becomes unmarked leaves the WeakGCMap before becoming marked again. (Guaranteed by all destructors running before the mark phase begins.)
     44         * During the mark phase, all values in the WeakGCMap are valid. (Guaranteed by all destructors running before the mark phase begins.)
     45     */
     46 
     47 public:
     48     typedef typename HashMap<KeyType, MappedType>::iterator iterator;
     49     typedef typename HashMap<KeyType, MappedType>::const_iterator const_iterator;
     50 
     51     bool isEmpty() { return m_map.isEmpty(); }
     52 
     53     MappedType get(const KeyType& key) const;
     54     pair<iterator, bool> set(const KeyType&, const MappedType&);
     55     MappedType take(const KeyType& key);
     56 
     57     // These unchecked functions provide access to a value even if the value's
     58     // mark bit is not set. This is used, among other things, to retrieve values
     59     // during the GC mark phase, which begins by clearing all mark bits.
     60 
     61     MappedType uncheckedGet(const KeyType& key) const { return m_map.get(key); }
     62     bool uncheckedRemove(const KeyType&, const MappedType&);
     63 
     64     iterator uncheckedBegin() { return m_map.begin(); }
     65     iterator uncheckedEnd() { return m_map.end(); }
     66 
     67     const_iterator uncheckedBegin() const { return m_map.begin(); }
     68     const_iterator uncheckedEnd() const { return m_map.end(); }
     69 
     70 private:
     71     HashMap<KeyType, MappedType> m_map;
     72 };
     73 
     74 template<typename KeyType, typename MappedType>
     75 inline MappedType WeakGCMap<KeyType, MappedType>::get(const KeyType& key) const
     76 {
     77     MappedType result = m_map.get(key);
     78     if (result == HashTraits<MappedType>::emptyValue())
     79         return result;
     80     if (!Heap::isCellMarked(result))
     81         return HashTraits<MappedType>::emptyValue();
     82     return result;
     83 }
     84 
     85 template<typename KeyType, typename MappedType>
     86 MappedType WeakGCMap<KeyType, MappedType>::take(const KeyType& key)
     87 {
     88     MappedType result = m_map.take(key);
     89     if (result == HashTraits<MappedType>::emptyValue())
     90         return result;
     91     if (!Heap::isCellMarked(result))
     92         return HashTraits<MappedType>::emptyValue();
     93     return result;
     94 }
     95 
     96 template<typename KeyType, typename MappedType>
     97 pair<typename HashMap<KeyType, MappedType>::iterator, bool> WeakGCMap<KeyType, MappedType>::set(const KeyType& key, const MappedType& value)
     98 {
     99     Heap::markCell(value); // If value is newly allocated, it's not marked, so mark it now.
    100     pair<iterator, bool> result = m_map.add(key, value);
    101     if (!result.second) { // pre-existing entry
    102         result.second = !Heap::isCellMarked(result.first->second);
    103         result.first->second = value;
    104     }
    105     return result;
    106 }
    107 
    108 template<typename KeyType, typename MappedType>
    109 bool WeakGCMap<KeyType, MappedType>::uncheckedRemove(const KeyType& key, const MappedType& value)
    110 {
    111     iterator it = m_map.find(key);
    112     if (it == m_map.end())
    113         return false;
    114     if (it->second != value)
    115         return false;
    116     m_map.remove(it);
    117     return true;
    118 }
    119 
    120 } // namespace JSC
    121 
    122 #endif // WeakGCMap_h
    123