1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "config.h" 6 #include "core/dom/WeakNodeMap.h" 7 8 #include "core/dom/Node.h" 9 10 namespace blink { 11 12 #if !ENABLE(OILPAN) 13 class NodeToWeakNodeMaps { 14 public: 15 bool addedToMap(Node*, WeakNodeMap*); 16 bool removedFromMap(Node*, WeakNodeMap*); 17 void nodeDestroyed(Node*); 18 19 static NodeToWeakNodeMaps& instance() 20 { 21 DEFINE_STATIC_LOCAL(NodeToWeakNodeMaps, self, ()); 22 return self; 23 } 24 25 private: 26 typedef Vector<WeakNodeMap*, 1> MapList; 27 typedef HashMap<Node*, OwnPtr<MapList> > NodeToMapList; 28 NodeToMapList m_nodeToMapList; 29 }; 30 31 bool NodeToWeakNodeMaps::addedToMap(Node* node, WeakNodeMap* map) 32 { 33 NodeToMapList::AddResult result = m_nodeToMapList.add(node, nullptr); 34 if (result.isNewEntry) 35 result.storedValue->value = adoptPtr(new MapList()); 36 result.storedValue->value->append(map); 37 return result.isNewEntry; 38 } 39 40 bool NodeToWeakNodeMaps::removedFromMap(Node* node, WeakNodeMap* map) 41 { 42 NodeToMapList::iterator it = m_nodeToMapList.find(node); 43 ASSERT(it != m_nodeToMapList.end()); 44 MapList* mapList = it->value.get(); 45 size_t position = mapList->find(map); 46 ASSERT(position != kNotFound); 47 mapList->remove(position); 48 if (mapList->size() == 0) { 49 m_nodeToMapList.remove(it); 50 return true; 51 } 52 return false; 53 } 54 55 void NodeToWeakNodeMaps::nodeDestroyed(Node* node) 56 { 57 OwnPtr<NodeToWeakNodeMaps::MapList> maps = m_nodeToMapList.take(node); 58 for (size_t i = 0; i < maps->size(); i++) 59 (*maps)[i]->nodeDestroyed(node); 60 } 61 62 WeakNodeMap::~WeakNodeMap() 63 { 64 NodeToWeakNodeMaps& allMaps = NodeToWeakNodeMaps::instance(); 65 for (NodeToValue::iterator it = m_nodeToValue.begin(); it != m_nodeToValue.end(); ++it) { 66 Node* node = it->key; 67 if (allMaps.removedFromMap(node, this)) 68 node->clearFlag(Node::HasWeakReferencesFlag); 69 } 70 } 71 72 void WeakNodeMap::put(Node* node, int value) 73 { 74 ASSERT(node && !m_nodeToValue.contains(node)); 75 m_nodeToValue.set(node, value); 76 m_valueToNode.set(value, node); 77 78 NodeToWeakNodeMaps& maps = NodeToWeakNodeMaps::instance(); 79 if (maps.addedToMap(node, this)) 80 node->setFlag(Node::HasWeakReferencesFlag); 81 } 82 83 int WeakNodeMap::value(Node* node) 84 { 85 return m_nodeToValue.get(node); 86 } 87 88 Node* WeakNodeMap::node(int value) 89 { 90 return m_valueToNode.get(value); 91 } 92 93 void WeakNodeMap::nodeDestroyed(Node* node) 94 { 95 int value = m_nodeToValue.take(node); 96 ASSERT(value); 97 m_valueToNode.remove(value); 98 } 99 100 void WeakNodeMap::notifyNodeDestroyed(Node* node) 101 { 102 NodeToWeakNodeMaps::instance().nodeDestroyed(node); 103 } 104 #endif 105 106 } 107