Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Side by Side Diff: Source/WebCore/bindings/dart/DartGCController.cpp

Issue 10745003: Properly retain non-node event listeners. (Closed) Base URL: svn://svn.chromium.org/multivm/trunk/webkit
Patch Set: . Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/WebCore/bindings/dart/DartDOMWrapper.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 &map; 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 collectEventListenerWrappers(EventTarget*, Vector<Dart_Handle>& wrap pers);
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 collectEventListenerWrappers(node, weakReferenceSet->values);
103 } 94 }
95 }
104 96
97 static void createWeakReferenceSetsForEventTargets(DartDOMData* domData, WeakRef erenceSets* weakReferenceSets)
98 {
99 DartEventTargetMap* eventTargetMap = domData->eventTargetMap();
100 for (DartEventTargetMap::iterator it = eventTargetMap->begin(); it != eventT argetMap->end(); ++it) {
101 WeakReferenceSet* weakReferenceSet = new WeakReferenceSet;
102 weakReferenceSets->append(weakReferenceSet);
103 weakReferenceSet->keys.append(it->second);
104 collectEventListenerWrappers(it->first, weakReferenceSet->values);
105 }
106 }
107
108 static void collectRetainedActiveDOMObjectWrappers(DartDOMData* domData, Vector< Dart_Handle>& wrappers)
109 {
105 DartActiveDOMObjectMap* activeObjectMap = domData->activeObjectMap(); 110 DartActiveDOMObjectMap* activeObjectMap = domData->activeObjectMap();
106 for (DartActiveDOMObjectMap::iterator it = activeObjectMap->begin(); it != a ctiveObjectMap->end(); ++it) { 111 for (DartActiveDOMObjectMap::iterator it = activeObjectMap->begin(); it != a ctiveObjectMap->end(); ++it) {
107 ActiveDOMObject* activeDOMObject = it->first; 112 ActiveDOMObject* activeDOMObject = it->first;
108 if (activeDOMObject->hasPendingActivity()) { 113 if (activeDOMObject->hasPendingActivity()) {
109 Dart_Handle wrapper = it->second; 114 Dart_Handle wrapper = it->second;
110 documentWeakReferenceSet->values.append(wrapper); 115 wrappers.append(wrapper);
111 } 116 }
112 } 117 }
113 118
114 DartMessagePortMap* messagePortMap = domData->messagePortMap(); 119 DartMessagePortMap* messagePortMap = domData->messagePortMap();
115 for (DartMessagePortMap::iterator it = messagePortMap->begin(); it != messag ePortMap->end(); ++it) { 120 for (DartMessagePortMap::iterator it = messagePortMap->begin(); it != messag ePortMap->end(); ++it) {
116 MessagePort* messagePort = it->first; 121 MessagePort* messagePort = it->first;
117 if (messagePort->isEntangled() || messagePort->hasPendingActivity()) { 122 if (messagePort->isEntangled() || messagePort->hasPendingActivity()) {
118 Dart_Handle wrapper = it->second; 123 Dart_Handle wrapper = it->second;
119 documentWeakReferenceSet->values.append(wrapper); 124 wrappers.append(wrapper);
120 } 125 }
121 } 126 }
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 } 127 }
130 128
131 void DartGCController::epilogueCallback()
132 {
133 WTF::deleteAllValues(*weakReferenceSetForRoot());
134 weakReferenceSetForRoot()->clear();
135 }
136
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)
145 return 0; 137 return 0;
146 } else { 138 } else {
147 while (Node* parent = root->parentOrHostNode()) 139 while (Node* parent = root->parentOrHostNode())
148 root = parent; 140 root = parent;
149 } 141 }
150 return root; 142 return root;
151 } 143 }
152 144
153 static void addEventListenersToReferenceSet(EventTarget* eventTarget, WeakRefere nceSet* weakReferenceSet) 145 static void collectEventListenerWrappers(EventTarget* eventTarget, Vector<Dart_H andle>& wrappers)
154 { 146 {
155 if (!eventTarget->hasEventListeners()) 147 if (!eventTarget->hasEventListeners())
156 return; 148 return;
157 149
158 EventListenerIterator iterator(eventTarget); 150 EventListenerIterator iterator(eventTarget);
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 wrappers.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 }
OLDNEW
« no previous file with comments | « Source/WebCore/bindings/dart/DartDOMWrapper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698