| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2012 Google Inc. All rights reserved. | 2 * Copyright (C) 2012 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 | 41 |
| 42 #include <wtf/Vector.h> | 42 #include <wtf/Vector.h> |
| 43 | 43 |
| 44 namespace WebCore { | 44 namespace WebCore { |
| 45 | 45 |
| 46 struct WeakReferenceSet { | 46 struct WeakReferenceSet { |
| 47 Vector<Dart_Handle> keys; | 47 Vector<Dart_Handle> keys; |
| 48 Vector<Dart_Handle> values; | 48 Vector<Dart_Handle> values; |
| 49 }; | 49 }; |
| 50 | 50 |
| 51 typedef HashMap<Node*, WeakReferenceSet*> weakReferenceSetForRootMap; | 51 typedef Vector<WeakReferenceSet*> WeakReferenceSets; |
| 52 | 52 |
| 53 static weakReferenceSetForRootMap* weakReferenceSetForRoot() | 53 static WeakReferenceSets* weakReferenceSets() |
| 54 { | 54 { |
| 55 DEFINE_STATIC_LOCAL(weakReferenceSetForRootMap, map, ()); | 55 DEFINE_STATIC_LOCAL(WeakReferenceSets, sets, ()); |
| 56 return ↦ | 56 return &sets; |
| 57 } | 57 } |
| 58 | 58 |
| 59 static Node* calculateRootNode(Node*); | 59 static Node* calculateRootNode(Node*); |
| 60 static void addEventListenersToReferenceSet(EventTarget*, WeakReferenceSet*); | 60 static void addEventListenersToReferenceSet(EventTarget*, WeakReferenceSet*); |
| 61 | 61 |
| 62 void DartGCController::prologueCallback() | 62 static void createWeakReferenceSetsForNodes(DartDOMData* domData, WeakReferenceS
et* documentWeakReferenceSet, WeakReferenceSets* weakReferenceSets) |
| 63 { | 63 { |
| 64 ASSERT(DartIsolate::isDOMIsolate(Dart_CurrentIsolate())); | 64 typedef HashMap<Node*, WeakReferenceSet*> WeakReferenceSetForRootMap; |
| 65 | 65 WeakReferenceSetForRootMap weakReferenceSetForRootMap; |
| 66 // FIXME: pass the state to epilogue callback instead of using statics. | |
| 67 ASSERT(weakReferenceSetForRoot()->isEmpty()); | |
| 68 | |
| 69 DartDOMData* domData = DartIsolate::currentDOMData(); | |
| 70 | |
| 71 ASSERT(domData->scriptExecutionContext()->isDocument()); | |
| 72 Document* document = static_cast<Document*>(domData->scriptExecutionContext(
)); | |
| 73 | |
| 74 WeakReferenceSet* documentWeakReferenceSet = new WeakReferenceSet; | |
| 75 weakReferenceSetForRoot()->set(document, documentWeakReferenceSet); | |
| 76 | 66 |
| 77 DartDOMNodeMap* nodeMap = domData->nodeMap(); | 67 DartDOMNodeMap* nodeMap = domData->nodeMap(); |
| 78 for (DartDOMNodeMap::iterator it = nodeMap->begin(); it != nodeMap->end(); +
+it) { | 68 for (DartDOMNodeMap::iterator it = nodeMap->begin(); it != nodeMap->end(); +
+it) { |
| 79 Node* node = it->first; | 69 Node* node = it->first; |
| 80 | 70 |
| 81 WeakReferenceSet* weakReferenceSet = 0; | 71 WeakReferenceSet* weakReferenceSet = 0; |
| 82 if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && static
_cast<HTMLImageElement*>(node)->hasPendingLoadEvent())) { | 72 if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && static
_cast<HTMLImageElement*>(node)->hasPendingLoadEvent())) { |
| 83 ASSERT(node->document() == document); | 73 ASSERT(node->document() == document); |
| 84 weakReferenceSet = documentWeakReferenceSet; | 74 weakReferenceSet = documentWeakReferenceSet; |
| 85 } else { | 75 } else { |
| 86 Node* root = calculateRootNode(node); | 76 Node* root = calculateRootNode(node); |
| 87 if (!root) | 77 if (!root) |
| 88 continue; | 78 continue; |
| 89 weakReferenceSetForRootMap::iterator weakReferenceSetIterator = weak
ReferenceSetForRoot()->find(root); | 79 WeakReferenceSetForRootMap::iterator weakReferenceSetIterator = weak
ReferenceSetForRootMap.find(root); |
| 90 if (weakReferenceSetIterator != weakReferenceSetForRoot()->end()) | 80 if (weakReferenceSetIterator != weakReferenceSetForRootMap.end()) |
| 91 weakReferenceSet = weakReferenceSetIterator->second; | 81 weakReferenceSet = weakReferenceSetIterator->second; |
| 92 else { | 82 else { |
| 93 weakReferenceSet = new WeakReferenceSet; | 83 weakReferenceSet = new WeakReferenceSet; |
| 94 weakReferenceSetForRoot()->set(root, weakReferenceSet); | 84 weakReferenceSets->append(weakReferenceSet); |
| 85 weakReferenceSetForRootMap.set(root, weakReferenceSet); |
| 95 } | 86 } |
| 96 } | 87 } |
| 97 ASSERT(weakReferenceSet); | 88 ASSERT(weakReferenceSet); |
| 98 | 89 |
| 99 Dart_Handle wrapper = it->second; | 90 Dart_Handle wrapper = it->second; |
| 100 weakReferenceSet->keys.append(wrapper); | 91 weakReferenceSet->keys.append(wrapper); |
| 101 weakReferenceSet->values.append(wrapper); | 92 weakReferenceSet->values.append(wrapper); |
| 102 addEventListenersToReferenceSet(node, weakReferenceSet); | 93 addEventListenersToReferenceSet(node, weakReferenceSet); |
| 103 } | 94 } |
| 95 } |
| 104 | 96 |
| 97 static void collectRetainedActiveDOMObjectWrappers(DartDOMData* domData, Vector<
Dart_Handle>& wrappers) |
| 98 { |
| 105 DartActiveDOMObjectMap* activeObjectMap = domData->activeObjectMap(); | 99 DartActiveDOMObjectMap* activeObjectMap = domData->activeObjectMap(); |
| 106 for (DartActiveDOMObjectMap::iterator it = activeObjectMap->begin(); it != a
ctiveObjectMap->end(); ++it) { | 100 for (DartActiveDOMObjectMap::iterator it = activeObjectMap->begin(); it != a
ctiveObjectMap->end(); ++it) { |
| 107 ActiveDOMObject* activeDOMObject = it->first; | 101 ActiveDOMObject* activeDOMObject = it->first; |
| 108 if (activeDOMObject->hasPendingActivity()) { | 102 if (activeDOMObject->hasPendingActivity()) { |
| 109 Dart_Handle wrapper = it->second; | 103 Dart_Handle wrapper = it->second; |
| 110 documentWeakReferenceSet->values.append(wrapper); | 104 wrappers.append(wrapper); |
| 111 } | 105 } |
| 112 } | 106 } |
| 113 | 107 |
| 114 DartMessagePortMap* messagePortMap = domData->messagePortMap(); | 108 DartMessagePortMap* messagePortMap = domData->messagePortMap(); |
| 115 for (DartMessagePortMap::iterator it = messagePortMap->begin(); it != messag
ePortMap->end(); ++it) { | 109 for (DartMessagePortMap::iterator it = messagePortMap->begin(); it != messag
ePortMap->end(); ++it) { |
| 116 MessagePort* messagePort = it->first; | 110 MessagePort* messagePort = it->first; |
| 117 if (messagePort->isEntangled() || messagePort->hasPendingActivity()) { | 111 if (messagePort->isEntangled() || messagePort->hasPendingActivity()) { |
| 118 Dart_Handle wrapper = it->second; | 112 Dart_Handle wrapper = it->second; |
| 119 documentWeakReferenceSet->values.append(wrapper); | 113 wrappers.append(wrapper); |
| 120 } | 114 } |
| 121 } | 115 } |
| 122 | |
| 123 addEventListenersToReferenceSet(document->domWindow(), documentWeakReference
Set); | |
| 124 | |
| 125 for (weakReferenceSetForRootMap::iterator it = weakReferenceSetForRoot()->be
gin(); it != weakReferenceSetForRoot()->end(); ++it) { | |
| 126 WeakReferenceSet* set = it->second; | |
| 127 Dart_NewWeakReferenceSet(set->keys.data(), set->keys.size(), set->values
.data(), set->values.size()); | |
| 128 } | |
| 129 } | 116 } |
| 130 | 117 |
| 131 void DartGCController::epilogueCallback() | 118 static void createWeakReferenceSetsForEventTargets(DartDOMData* domData, WeakRef
erenceSets* weakReferenceSets) |
| 132 { | 119 { |
| 133 WTF::deleteAllValues(*weakReferenceSetForRoot()); | 120 DartEventTargetMap* eventTargetMap = domData->eventTargetMap(); |
| 134 weakReferenceSetForRoot()->clear(); | 121 for (DartEventTargetMap::iterator it = eventTargetMap->begin(); it != eventT
argetMap->end(); ++it) { |
| 122 WeakReferenceSet* weakReferenceSet = new WeakReferenceSet; |
| 123 weakReferenceSets->append(weakReferenceSet); |
| 124 weakReferenceSet->keys.append(it->second); |
| 125 addEventListenersToReferenceSet(it->first, weakReferenceSet); |
| 126 } |
| 135 } | 127 } |
| 136 | 128 |
| 137 static Node* calculateRootNode(Node* node) | 129 static Node* calculateRootNode(Node* node) |
| 138 { | 130 { |
| 139 Node* root = node; | 131 Node* root = node; |
| 140 if (node->isAttributeNode()) { | 132 if (node->isAttributeNode()) { |
| 141 root = static_cast<Attr*>(node)->ownerElement(); | 133 root = static_cast<Attr*>(node)->ownerElement(); |
| 142 // If the attribute has no element, no need to put it in the group, | 134 // If the attribute has no element, no need to put it in the group, |
| 143 // because it'll always be a group of 1. | 135 // because it'll always be a group of 1. |
| 144 if (!root) | 136 if (!root) |
| (...skipping 14 matching lines...) Expand all Loading... |
| 159 while (EventListener* listener = iterator.nextListener()) { | 151 while (EventListener* listener = iterator.nextListener()) { |
| 160 if (listener->type() != static_cast<int>(DartEventListenerType)) | 152 if (listener->type() != static_cast<int>(DartEventListenerType)) |
| 161 continue; | 153 continue; |
| 162 DartEventListener* dartListener = static_cast<DartEventListener*>(listen
er); | 154 DartEventListener* dartListener = static_cast<DartEventListener*>(listen
er); |
| 163 if (dartListener->isolate() != DartIsolate::current()) | 155 if (dartListener->isolate() != DartIsolate::current()) |
| 164 continue; | 156 continue; |
| 165 weakReferenceSet->values.append(dartListener->listenerObject()); | 157 weakReferenceSet->values.append(dartListener->listenerObject()); |
| 166 } | 158 } |
| 167 } | 159 } |
| 168 | 160 |
| 161 void DartGCController::prologueCallback() |
| 162 { |
| 163 ASSERT(DartIsolate::isDOMIsolate(Dart_CurrentIsolate())); |
| 164 // FIXME: pass the state to epilogue callback instead of using statics. |
| 165 ASSERT(weakReferenceSets()->isEmpty()); |
| 166 |
| 167 DartDOMData* domData = DartIsolate::currentDOMData(); |
| 168 |
| 169 WeakReferenceSet* documentWeakReferenceSet = new WeakReferenceSet; |
| 170 weakReferenceSets()->append(documentWeakReferenceSet); |
| 171 |
| 172 createWeakReferenceSetsForNodes(domData, documentWeakReferenceSet, weakRefer
enceSets()); |
| 173 createWeakReferenceSetsForEventTargets(domData, weakReferenceSets()); |
| 174 collectRetainedActiveDOMObjectWrappers(domData, documentWeakReferenceSet->va
lues); |
| 175 |
| 176 for (size_t i = 0; i < weakReferenceSets()->size(); ++i) { |
| 177 WeakReferenceSet* set = (*weakReferenceSets())[i]; |
| 178 Dart_NewWeakReferenceSet(set->keys.data(), set->keys.size(), set->values
.data(), set->values.size()); |
| 179 } |
| 169 } | 180 } |
| 181 |
| 182 void DartGCController::epilogueCallback() |
| 183 { |
| 184 WTF::deleteAllValues(*weakReferenceSets()); |
| 185 weakReferenceSets()->clear(); |
| 186 } |
| 187 |
| 188 } |
| OLD | NEW |