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

Side by Side Diff: Source/bindings/v8/V8GCController.cpp

Issue 14443007: Get rid of usages of ScriptWrappable::wrapper(). (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: rebased Created 7 years, 7 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2009 Google Inc. All rights reserved. 2 * Copyright (C) 2009 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 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 return node; 79 return node;
80 node = ownerElement; 80 node = ownerElement;
81 } 81 }
82 82
83 while (Node* parent = node->parentOrShadowHostNode()) 83 while (Node* parent = node->parentOrShadowHostNode())
84 node = parent; 84 node = parent;
85 85
86 return node; 86 return node;
87 } 87 }
88 88
89 static void gcTree(v8::Isolate* isolate, Node* startNode)
90 {
91 Vector<Node*, initialNodeVectorSize> newSpaceNodes;
92
93 // We traverse a DOM tree in the DFS order starting from startNode.
94 // The traversal order does not matter for correctness but does matter for p erformance.
95 Node* node = startNode;
96 // To make each minor GC time bounded, we might need to give up
97 // traversing at some point for a large DOM tree. That being said,
98 // I could not observe the need even in pathological test cases.
99 do {
100 ASSERT(node);
101 if (!node->wrapper().IsEmpty()) {
102 // FIXME: Remove the special handling for image elements.
103 // The same special handling is in V8GCController::opaqueRootForGC() .
104 // Maybe should image elements be active DOM nodes?
105 // See https://code.google.com/p/chromium/issues/detail?id=164882
106 if (!node->isV8CollectableDuringMinorGC() || (node->hasTagName(HTMLN ames::imgTag) && static_cast<HTMLImageElement*>(node)->hasPendingActivity())) {
107 // This node is not in the new space of V8. This indicates that
108 // the minor GC cannot anyway judge reachability of this DOM tre e.
109 // Thus we give up traversing the DOM tree.
110 return;
111 }
112 node->setV8CollectableDuringMinorGC(false);
113 newSpaceNodes.append(node);
114 }
115 if (node->firstChild()) {
116 node = node->firstChild();
117 continue;
118 }
119 while (!node->nextSibling()) {
120 if (!node->parentNode())
121 break;
122 node = node->parentNode();
123 }
124 if (node->parentNode())
125 node = node->nextSibling();
126 } while (node != startNode);
127
128 // We completed the DOM tree traversal. All wrappers in the DOM tree are
129 // stored in newSpaceNodes and are expected to exist in the new space of V8.
130 // We report those wrappers to V8 as an object group.
131 Node** nodeIterator = newSpaceNodes.begin();
132 Node** const nodeIteratorEnd = newSpaceNodes.end();
133 if (nodeIterator == nodeIteratorEnd)
134 return;
135 v8::UniqueId id(reinterpret_cast<intptr_t>(*(*nodeIterator)->wrapper()));
136 for (; nodeIterator != nodeIteratorEnd; ++nodeIterator) {
137 v8::Persistent<v8::Object> wrapper((*nodeIterator)->wrapper());
138 wrapper.MarkPartiallyDependent(isolate);
139 isolate->SetObjectGroupId(wrapper, id);
140 }
141 }
142
143 // Regarding a minor GC algorithm for DOM nodes, see this document: 89 // Regarding a minor GC algorithm for DOM nodes, see this document:
144 // https://docs.google.com/a/google.com/presentation/d/1uifwVYGNYTZDoGLyCb7sXa7g 49mWNMW2gaWvMN5NLk8/edit#slide=id.p 90 // https://docs.google.com/a/google.com/presentation/d/1uifwVYGNYTZDoGLyCb7sXa7g 49mWNMW2gaWvMN5NLk8/edit#slide=id.p
145 class MinorGCWrapperVisitor : public v8::PersistentHandleVisitor { 91 class MinorGCWrapperVisitor : public v8::PersistentHandleVisitor {
146 public: 92 public:
147 explicit MinorGCWrapperVisitor(v8::Isolate* isolate) 93 explicit MinorGCWrapperVisitor(v8::Isolate* isolate)
148 : m_isolate(isolate) 94 : m_isolate(isolate)
149 { 95 {
150 UNUSED_PARAM(m_isolate); 96 UNUSED_PARAM(m_isolate);
151 } 97 }
152 98
(...skipping 15 matching lines...) Expand all
168 return; 114 return;
169 115
170 ASSERT(value->IsObject()); 116 ASSERT(value->IsObject());
171 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(va lue); 117 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(va lue);
172 ASSERT(V8DOMWrapper::maybeDOMWrapper(value)); 118 ASSERT(V8DOMWrapper::maybeDOMWrapper(value));
173 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate)); 119 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate));
174 Node* node = V8Node::toNative(wrapper); 120 Node* node = V8Node::toNative(wrapper);
175 // A minor DOM GC can handle only node wrappers in the main world. 121 // A minor DOM GC can handle only node wrappers in the main world.
176 // Note that node->wrapper().IsEmpty() returns true for nodes that 122 // Note that node->wrapper().IsEmpty() returns true for nodes that
177 // do not have wrappers in the main world. 123 // do not have wrappers in the main world.
178 if (!node->wrapper().IsEmpty()) { 124 if (node->containsWrapper()) {
179 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); 125 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper);
180 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper); 126 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper);
181 if (activeDOMObject && activeDOMObject->hasPendingActivity()) 127 if (activeDOMObject && activeDOMObject->hasPendingActivity())
182 return; 128 return;
183 m_nodesInNewSpace.append(node); 129 m_nodesInNewSpace.append(node);
184 node->setV8CollectableDuringMinorGC(true); 130 node->setV8CollectableDuringMinorGC(true);
185 } 131 }
186 } 132 }
187 133
188 void notifyFinished() 134 void notifyFinished()
189 { 135 {
190 Node** nodeIterator = m_nodesInNewSpace.begin(); 136 Node** nodeIterator = m_nodesInNewSpace.begin();
191 Node** nodeIteratorEnd = m_nodesInNewSpace.end(); 137 Node** nodeIteratorEnd = m_nodesInNewSpace.end();
192 for (; nodeIterator < nodeIteratorEnd; ++nodeIterator) { 138 for (; nodeIterator < nodeIteratorEnd; ++nodeIterator) {
193 Node* node = *nodeIterator; 139 Node* node = *nodeIterator;
194 ASSERT(!node->wrapper().IsEmpty()); 140 ASSERT(node->containsWrapper());
195 if (node->isV8CollectableDuringMinorGC()) // This branch is just for performance. 141 if (node->isV8CollectableDuringMinorGC()) // This branch is just for performance.
196 gcTree(m_isolate, node); 142 gcTree(m_isolate, node);
197 } 143 }
198 } 144 }
199 145
200 private: 146 private:
147 void gcTree(v8::Isolate* isolate, Node* startNode)
148 {
149 Vector<Node*, initialNodeVectorSize> newSpaceNodes;
150
151 // We traverse a DOM tree in the DFS order starting from startNode.
152 // The traversal order does not matter for correctness but does matter f or performance.
153 Node* node = startNode;
154 // To make each minor GC time bounded, we might need to give up
155 // traversing at some point for a large DOM tree. That being said,
156 // I could not observe the need even in pathological test cases.
157 do {
158 ASSERT(node);
159 if (node->containsWrapper()) {
160 // FIXME: Remove the special handling for image elements.
161 // The same special handling is in V8GCController::opaqueRootFor GC().
162 // Maybe should image elements be active DOM nodes?
163 // See https://code.google.com/p/chromium/issues/detail?id=16488 2
164 if (!node->isV8CollectableDuringMinorGC() || (node->hasTagName(H TMLNames::imgTag) && static_cast< HTMLImageElement*>(node)->hasPendingActivit y())) {
abarth-chromium 2013/04/29 17:47:33 Looks like you've got some extra spaces between th
marja 2013/04/30 08:55:50 Oops. Done.
165 // This node is not in the new space of V8. This indicates t hat
166 // the minor GC cannot anyway judge reachability of this DOM tree.
167 // Thus we give up traversing the DOM tree.
168 return;
169 }
170 node->setV8CollectableDuringMinorGC(false);
171 newSpaceNodes.append(node);
172 }
173 if (node->firstChild()) {
174 node = node->firstChild();
175 continue;
176 }
177 while (!node->nextSibling()) {
178 if (!node->parentNode())
179 break;
180 node = node->parentNode();
181 }
182 if (node->parentNode())
183 node = node->nextSibling();
184 } while (node != startNode);
185
186 // We completed the DOM tree traversal. All wrappers in the DOM tree are
187 // stored in newSpaceNodes and are expected to exist in the new space of V8.
188 // We report those wrappers to V8 as an object group.
189 Node** nodeIterator = newSpaceNodes.begin();
190 Node** const nodeIteratorEnd = newSpaceNodes.end();
191 if (nodeIterator == nodeIteratorEnd)
192 return;
193 v8::UniqueId id(reinterpret_cast<intptr_t>((*nodeIterator)->unsafePersis tent().value()));
194 for (; nodeIterator != nodeIteratorEnd; ++nodeIterator) {
195 // This is safe because we know that GC won't happen before we
196 // dispose the UnsafePersistent (we're just preparing a GC).
197 v8::Persistent<v8::Object> wrapper;
198 (*nodeIterator)->unsafePersistent().makePersistentHandle(&wrapper);
199 wrapper.MarkPartiallyDependent(isolate);
200 isolate->SetObjectGroupId(wrapper, id);
201 }
202 }
203
201 Vector<Node*> m_nodesInNewSpace; 204 Vector<Node*> m_nodesInNewSpace;
202 v8::Isolate* m_isolate; 205 v8::Isolate* m_isolate;
203 }; 206 };
204 207
205 class MajorGCWrapperVisitor : public v8::PersistentHandleVisitor { 208 class MajorGCWrapperVisitor : public v8::PersistentHandleVisitor {
206 public: 209 public:
207 explicit MajorGCWrapperVisitor(v8::Isolate* isolate, bool constructRetainedO bjectInfos) 210 explicit MajorGCWrapperVisitor(v8::Isolate* isolate, bool constructRetainedO bjectInfos)
208 : m_isolate(isolate) 211 : m_isolate(isolate)
209 , m_liveRootGroupIdSet(false) 212 , m_liveRootGroupIdSet(false)
210 , m_constructRetainedObjectInfos(constructRetainedObjectInfos) 213 , m_constructRetainedObjectInfos(constructRetainedObjectInfos)
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
432 if (!script.IsEmpty()) { 435 if (!script.IsEmpty()) {
433 V8RecursionScope::MicrotaskSuppression scope; 436 V8RecursionScope::MicrotaskSuppression scope;
434 script->Run(); 437 script->Run();
435 } 438 }
436 } 439 }
437 440
438 context.clear(); 441 context.clear();
439 } 442 }
440 443
441 } // namespace WebCore 444 } // namespace WebCore
OLDNEW
« Source/bindings/v8/UnsafePersistent.h ('K') | « Source/bindings/v8/UnsafePersistent.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698