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

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

Issue 13975005: Update V8GCController to use new V8 GC-related APIs. (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
« no previous file with comments | « Source/bindings/v8/V8GCController.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) 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 29 matching lines...) Expand all
40 #include "bindings/v8/V8RecursionScope.h" 40 #include "bindings/v8/V8RecursionScope.h"
41 #include "bindings/v8/WrapperTypeInfo.h" 41 #include "bindings/v8/WrapperTypeInfo.h"
42 #include "core/dom/Attr.h" 42 #include "core/dom/Attr.h"
43 #include "core/html/HTMLImageElement.h" 43 #include "core/html/HTMLImageElement.h"
44 #include "core/platform/MemoryUsageSupport.h" 44 #include "core/platform/MemoryUsageSupport.h"
45 #include "core/platform/chromium/TraceEvent.h" 45 #include "core/platform/chromium/TraceEvent.h"
46 #include <algorithm> 46 #include <algorithm>
47 47
48 namespace WebCore { 48 namespace WebCore {
49 49
50 class ImplicitConnection {
51 public:
52 ImplicitConnection(void* root, v8::Persistent<v8::Object> wrapper)
53 : m_root(root)
54 , m_wrapper(wrapper)
55 , m_rootNode(0)
56 {
57 }
58 ImplicitConnection(Node* root, v8::Persistent<v8::Object> wrapper)
59 : m_root(root)
60 , m_wrapper(wrapper)
61 , m_rootNode(root)
62 {
63 }
64
65 void* root() const { return m_root; }
66 v8::Persistent<v8::Object> wrapper() const { return m_wrapper; }
67
68 PassOwnPtr<RetainedObjectInfo> retainedObjectInfo()
69 {
70 if (!m_rootNode)
71 return nullptr;
72 return adoptPtr(new RetainedDOMInfo(m_rootNode));
73 }
74
75 private:
76 void* m_root;
77 v8::Persistent<v8::Object> m_wrapper;
78 Node* m_rootNode;
79 };
80
81 bool operator<(const ImplicitConnection& left, const ImplicitConnection& right)
82 {
83 return left.root() < right.root();
84 }
85
86 struct ImplicitReference {
87 ImplicitReference(void* parent, v8::Persistent<v8::Object> child)
88 : parent(parent)
89 , child(child)
90 {
91 }
92
93 void* parent;
94 v8::Persistent<v8::Object> child;
95 };
96
97 bool operator<(const ImplicitReference& left, const ImplicitReference& right)
98 {
99 return left.parent < right.parent;
100 }
101
102 class WrapperGrouper {
103 public:
104 WrapperGrouper()
105 {
106 m_liveObjects.append(V8PerIsolateData::current()->ensureLiveRoot());
107 }
108
109 void addObjectWrapperToGroup(void* root, v8::Persistent<v8::Object> wrapper)
110 {
111 m_connections.append(ImplicitConnection(root, wrapper));
112 }
113
114 void addNodeWrapperToGroup(Node* root, v8::Persistent<v8::Object> wrapper)
115 {
116 m_connections.append(ImplicitConnection(root, wrapper));
117 }
118
119 void addImplicitReference(void* parent, v8::Persistent<v8::Object> child)
120 {
121 m_references.append(ImplicitReference(parent, child));
122 m_rootGroupMap.add(parent, v8::Persistent<v8::Object>());
123 }
124
125 void keepAlive(v8::Persistent<v8::Value> wrapper)
126 {
127 m_liveObjects.append(wrapper);
128 }
129
130 void apply()
131 {
132 if (m_liveObjects.size() > 1)
133 v8::V8::AddObjectGroup(m_liveObjects.data(), m_liveObjects.size());
134
135 std::sort(m_connections.begin(), m_connections.end());
136 Vector<v8::Persistent<v8::Value> > group;
137 ImplicitConnection* connectionIterator = m_connections.begin();
138 const ImplicitConnection* connectionIteratorEnd = m_connections.end();
139 while (connectionIterator < connectionIteratorEnd) {
140 void* root = connectionIterator->root();
141 v8::Persistent<v8::Object> groupRepresentativeWrapper = connectionIt erator->wrapper();
142 OwnPtr<RetainedObjectInfo> retainedObjectInfo = connectionIterator-> retainedObjectInfo();
143
144 do {
145 group.append(connectionIterator->wrapper());
146 ++connectionIterator;
147 } while (connectionIterator < connectionIteratorEnd && root == conne ctionIterator->root());
148
149 if (group.size() > 1)
150 v8::V8::AddObjectGroup(group.data(), group.size(), retainedObjec tInfo.leakPtr());
151
152 HashMap<void*, v8::Persistent<v8::Object> >::iterator iter = m_rootG roupMap.find(root);
153 if (iter != m_rootGroupMap.end())
154 iter->value = groupRepresentativeWrapper;
155
156 group.shrink(0);
157 }
158
159 std::sort(m_references.begin(), m_references.end());
160 const ImplicitReference* referenceIterator = m_references.begin();
161 const ImplicitReference* referenceIteratorEnd = m_references.end();
162 while (referenceIterator < referenceIteratorEnd) {
163 void* parent = referenceIterator->parent;
164 v8::Persistent<v8::Object> parentWrapper = m_rootGroupMap.get(parent );
165 if (parentWrapper.IsEmpty()) {
166 ++referenceIterator;
167 continue;
168 }
169
170 Vector<v8::Persistent<v8::Value> > children;
171 do {
172 children.append(referenceIterator->child);
173 ++referenceIterator;
174 } while (referenceIterator < referenceIteratorEnd && parent == refer enceIterator->parent);
175
176 v8::V8::AddImplicitReferences(parentWrapper, children.data(), childr en.size());
177 }
178 }
179
180 private:
181 Vector<v8::Persistent<v8::Value> > m_liveObjects;
182 Vector<ImplicitConnection> m_connections;
183 Vector<ImplicitReference> m_references;
184 HashMap<void*, v8::Persistent<v8::Object> > m_rootGroupMap;
185 };
186
187 // FIXME: This should use opaque GC roots. 50 // FIXME: This should use opaque GC roots.
188 static void addImplicitReferencesForNodeWithEventListeners(Node* node, v8::Persi stent<v8::Object> wrapper) 51 static void addReferencesForNodeWithEventListeners(v8::Isolate* isolate, Node* n ode, const v8::Persistent<v8::Object>& wrapper)
189 { 52 {
190 ASSERT(node->hasEventListeners()); 53 ASSERT(node->hasEventListeners());
191 54
192 Vector<v8::Persistent<v8::Value> > listeners;
193
194 EventListenerIterator iterator(node); 55 EventListenerIterator iterator(node);
195 while (EventListener* listener = iterator.nextListener()) { 56 while (EventListener* listener = iterator.nextListener()) {
196 if (listener->type() != EventListener::JSEventListenerType) 57 if (listener->type() != EventListener::JSEventListenerType)
197 continue; 58 continue;
198 V8AbstractEventListener* v8listener = static_cast<V8AbstractEventListene r*>(listener); 59 V8AbstractEventListener* v8listener = static_cast<V8AbstractEventListene r*>(listener);
199 if (!v8listener->hasExistingListenerObject()) 60 if (!v8listener->hasExistingListenerObject())
200 continue; 61 continue;
201 listeners.append(v8listener->existingListenerObjectPersistentHandle()); 62
63 isolate->SetReference(wrapper, v8listener->existingListenerObjectPersist entHandle());
202 } 64 }
203
204 if (listeners.isEmpty())
205 return;
206
207 v8::V8::AddImplicitReferences(wrapper, listeners.data(), listeners.size());
208 } 65 }
209 66
210 Node* V8GCController::opaqueRootForGC(Node* node, v8::Isolate*) 67 Node* V8GCController::opaqueRootForGC(Node* node, v8::Isolate*)
211 { 68 {
212 // FIXME: Remove the special handling for image elements. 69 // FIXME: Remove the special handling for image elements.
213 // The same special handling is in V8GCController::gcTree(). 70 // The same special handling is in V8GCController::gcTree().
214 // Maybe should image elements be active DOM nodes? 71 // Maybe should image elements be active DOM nodes?
215 // See https://code.google.com/p/chromium/issues/detail?id=164882 72 // See https://code.google.com/p/chromium/issues/detail?id=164882
216 if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && static_cas t<HTMLImageElement*>(node)->hasPendingActivity())) 73 if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && static_cas t<HTMLImageElement*>(node)->hasPendingActivity()))
217 return node->document(); 74 return node->document();
218 75
219 if (node->isAttributeNode()) { 76 if (node->isAttributeNode()) {
220 Node* ownerElement = static_cast<Attr*>(node)->ownerElement(); 77 Node* ownerElement = static_cast<Attr*>(node)->ownerElement();
221 if (!ownerElement) 78 if (!ownerElement)
222 return node; 79 return node;
223 node = ownerElement; 80 node = ownerElement;
224 } 81 }
225 82
226 while (Node* parent = node->parentOrShadowHostNode()) 83 while (Node* parent = node->parentOrShadowHostNode())
227 node = parent; 84 node = parent;
228 85
229 return node; 86 return node;
230 } 87 }
231 88
232 static void gcTree(v8::Isolate* isolate, Node* startNode) 89 static void gcTree(v8::Isolate* isolate, Node* startNode)
233 { 90 {
234 Vector<v8::Persistent<v8::Value>, initialNodeVectorSize> newSpaceWrappers; 91 Vector<Node*, initialNodeVectorSize> newSpaceNodes;
235 92
236 // We traverse a DOM tree in the DFS order starting from startNode. 93 // We traverse a DOM tree in the DFS order starting from startNode.
237 // The traversal order does not matter for correctness but does matter for p erformance. 94 // The traversal order does not matter for correctness but does matter for p erformance.
238 Node* node = startNode; 95 Node* node = startNode;
239 // To make each minor GC time bounded, we might need to give up 96 // To make each minor GC time bounded, we might need to give up
240 // traversing at some point for a large DOM tree. That being said, 97 // traversing at some point for a large DOM tree. That being said,
241 // I could not observe the need even in pathological test cases. 98 // I could not observe the need even in pathological test cases.
242 do { 99 do {
243 ASSERT(node); 100 ASSERT(node);
244 if (!node->wrapper().IsEmpty()) { 101 if (!node->wrapper().IsEmpty()) {
245 // FIXME: Remove the special handling for image elements. 102 // FIXME: Remove the special handling for image elements.
246 // The same special handling is in V8GCController::opaqueRootForGC() . 103 // The same special handling is in V8GCController::opaqueRootForGC() .
247 // Maybe should image elements be active DOM nodes? 104 // Maybe should image elements be active DOM nodes?
248 // See https://code.google.com/p/chromium/issues/detail?id=164882 105 // See https://code.google.com/p/chromium/issues/detail?id=164882
249 if (!node->isV8CollectableDuringMinorGC() || (node->hasTagName(HTMLN ames::imgTag) && static_cast<HTMLImageElement*>(node)->hasPendingActivity())) { 106 if (!node->isV8CollectableDuringMinorGC() || (node->hasTagName(HTMLN ames::imgTag) && static_cast<HTMLImageElement*>(node)->hasPendingActivity())) {
250 // This node is not in the new space of V8. This indicates that 107 // This node is not in the new space of V8. This indicates that
251 // the minor GC cannot anyway judge reachability of this DOM tre e. 108 // the minor GC cannot anyway judge reachability of this DOM tre e.
252 // Thus we give up traversing the DOM tree. 109 // Thus we give up traversing the DOM tree.
253 return; 110 return;
254 } 111 }
255 node->setV8CollectableDuringMinorGC(false); 112 node->setV8CollectableDuringMinorGC(false);
256 newSpaceWrappers.append(node->wrapper()); 113 newSpaceNodes.append(node);
257 } 114 }
258 if (node->firstChild()) { 115 if (node->firstChild()) {
259 node = node->firstChild(); 116 node = node->firstChild();
260 continue; 117 continue;
261 } 118 }
262 while (!node->nextSibling()) { 119 while (!node->nextSibling()) {
263 if (!node->parentNode()) 120 if (!node->parentNode())
264 break; 121 break;
265 node = node->parentNode(); 122 node = node->parentNode();
266 } 123 }
267 if (node->parentNode()) 124 if (node->parentNode())
268 node = node->nextSibling(); 125 node = node->nextSibling();
269 } while (node != startNode); 126 } while (node != startNode);
270 127
271 // We completed the DOM tree traversal. All wrappers in the DOM tree are 128 // We completed the DOM tree traversal. All wrappers in the DOM tree are
272 // stored in newSpaceWrappers and are expected to exist in the new space of V8. 129 // stored in newSpaceNodes and are expected to exist in the new space of V8.
273 // We report those wrappers to V8 as an object group. 130 // We report those wrappers to V8 as an object group.
274 v8::Persistent<v8::Value>* wrapperIterator = newSpaceWrappers.begin(); 131 Node** nodeIterator = newSpaceNodes.begin();
275 const v8::Persistent<v8::Value>* wrapperIteratorEnd = newSpaceWrappers.end() ; 132 Node** const nodeIteratorEnd = newSpaceNodes.end();
276 for (; wrapperIterator != wrapperIteratorEnd; ++wrapperIterator) 133 if (nodeIterator == nodeIteratorEnd)
277 wrapperIterator->MarkPartiallyDependent(isolate); 134 return;
278 if (newSpaceWrappers.size() > 0) 135 v8::UniqueId id(reinterpret_cast<intptr_t>(*(*nodeIterator)->wrapper()));
279 v8::V8::AddObjectGroup(&newSpaceWrappers[0], newSpaceWrappers.size()); 136 for (; nodeIterator != nodeIteratorEnd; ++nodeIterator) {
137 v8::Persistent<v8::Object> wrapper((*nodeIterator)->wrapper());
138 wrapper.MarkPartiallyDependent(isolate);
139 isolate->SetObjectGroupId(wrapper, id);
140 }
280 } 141 }
281 142
282 // Regarding a minor GC algorithm for DOM nodes, see this document: 143 // Regarding a minor GC algorithm for DOM nodes, see this document:
283 // https://docs.google.com/a/google.com/presentation/d/1uifwVYGNYTZDoGLyCb7sXa7g 49mWNMW2gaWvMN5NLk8/edit#slide=id.p 144 // https://docs.google.com/a/google.com/presentation/d/1uifwVYGNYTZDoGLyCb7sXa7g 49mWNMW2gaWvMN5NLk8/edit#slide=id.p
284 class MinorGCWrapperVisitor : public v8::PersistentHandleVisitor { 145 class MinorGCWrapperVisitor : public v8::PersistentHandleVisitor {
285 public: 146 public:
286 explicit MinorGCWrapperVisitor(v8::Isolate* isolate) 147 explicit MinorGCWrapperVisitor(v8::Isolate* isolate)
287 : m_isolate(isolate) 148 : m_isolate(isolate)
288 { 149 {
289 UNUSED_PARAM(m_isolate); 150 UNUSED_PARAM(m_isolate);
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 } 197 }
337 } 198 }
338 199
339 private: 200 private:
340 Vector<Node*> m_nodesInNewSpace; 201 Vector<Node*> m_nodesInNewSpace;
341 v8::Isolate* m_isolate; 202 v8::Isolate* m_isolate;
342 }; 203 };
343 204
344 class MajorGCWrapperVisitor : public v8::PersistentHandleVisitor { 205 class MajorGCWrapperVisitor : public v8::PersistentHandleVisitor {
345 public: 206 public:
346 explicit MajorGCWrapperVisitor(v8::Isolate* isolate) 207 explicit MajorGCWrapperVisitor(v8::Isolate* isolate, bool constructRetainedO bjectInfos)
347 : m_isolate(isolate) 208 : m_isolate(isolate)
209 , m_liveRootGroupIdSet(false)
210 , m_constructRetainedObjectInfos(constructRetainedObjectInfos)
348 { 211 {
349 } 212 }
350 213
351 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t classId) OVERRIDE 214 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t classId) OVERRIDE
352 { 215 {
353 ASSERT(value->IsObject()); 216 ASSERT(value->IsObject());
354 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(va lue); 217 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(va lue);
355 218
356 if (classId != v8DOMNodeClassId && classId != v8DOMObjectClassId) 219 if (classId != v8DOMNodeClassId && classId != v8DOMObjectClassId)
357 return; 220 return;
358 221
359 ASSERT(V8DOMWrapper::maybeDOMWrapper(value)); 222 ASSERT(V8DOMWrapper::maybeDOMWrapper(value));
360 223
361 if (value.IsIndependent(m_isolate)) 224 if (value.IsIndependent(m_isolate))
362 return; 225 return;
363 226
364 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); 227 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper);
365 void* object = toNative(wrapper); 228 void* object = toNative(wrapper);
366 229
367 if (V8MessagePort::info.equals(type)) { 230 if (V8MessagePort::info.equals(type)) {
368 // Mark each port as in-use if it's entangled. For simplicity's sake , 231 // Mark each port as in-use if it's entangled. For simplicity's sake ,
369 // we assume all ports are remotely entangled, since the Chromium po rt 232 // we assume all ports are remotely entangled, since the Chromium po rt
370 // implementation can't tell the difference. 233 // implementation can't tell the difference.
371 MessagePort* port = static_cast<MessagePort*>(object); 234 MessagePort* port = static_cast<MessagePort*>(object);
372 if (port->isEntangled() || port->hasPendingActivity()) 235 if (port->isEntangled() || port->hasPendingActivity())
373 m_grouper.keepAlive(wrapper); 236 m_isolate->SetObjectGroupId(wrapper, liveRootId());
374 } else if (V8MutationObserver::info.equals(type)) { 237 } else if (V8MutationObserver::info.equals(type)) {
375 // FIXME: Allow opaqueRootForGC to operate on multiple roots and mov e this logic into V8MutationObserverCustom. 238 // FIXME: Allow opaqueRootForGC to operate on multiple roots and mov e this logic into V8MutationObserverCustom.
376 MutationObserver* observer = static_cast<MutationObserver*>(object); 239 MutationObserver* observer = static_cast<MutationObserver*>(object);
377 HashSet<Node*> observedNodes = observer->getObservedNodes(); 240 HashSet<Node*> observedNodes = observer->getObservedNodes();
378 for (HashSet<Node*>::iterator it = observedNodes.begin(); it != obse rvedNodes.end(); ++it) 241 for (HashSet<Node*>::iterator it = observedNodes.begin(); it != obse rvedNodes.end(); ++it) {
379 m_grouper.addImplicitReference(V8GCController::opaqueRootForGC(* it, m_isolate), wrapper); 242 v8::UniqueId id(reinterpret_cast<intptr_t>(V8GCController::opaqu eRootForGC(*it, m_isolate)));
243 m_isolate->SetReferenceFromGroup(id, wrapper);
244 }
380 } else { 245 } else {
381 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper); 246 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper);
382 if (activeDOMObject && activeDOMObject->hasPendingActivity()) 247 if (activeDOMObject && activeDOMObject->hasPendingActivity())
383 m_grouper.keepAlive(wrapper); 248 m_isolate->SetObjectGroupId(wrapper, liveRootId());
384 } 249 }
385 250
386 if (classId == v8DOMNodeClassId) { 251 if (classId == v8DOMNodeClassId) {
387 UNUSED_PARAM(m_isolate); 252 UNUSED_PARAM(m_isolate);
388 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate)); 253 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate));
389 ASSERT(!wrapper.IsIndependent(m_isolate)); 254 ASSERT(!wrapper.IsIndependent(m_isolate));
390 255
391 Node* node = static_cast<Node*>(object); 256 Node* node = static_cast<Node*>(object);
392 257
393 if (node->hasEventListeners()) 258 if (node->hasEventListeners())
394 addImplicitReferencesForNodeWithEventListeners(node, wrapper); 259 addReferencesForNodeWithEventListeners(m_isolate, node, wrapper) ;
395 260 Node* root = V8GCController::opaqueRootForGC(node, m_isolate);
396 m_grouper.addNodeWrapperToGroup(V8GCController::opaqueRootForGC(node , m_isolate), wrapper); 261 m_isolate->SetObjectGroupId(wrapper, v8::UniqueId(reinterpret_cast<i ntptr_t>(root)));
262 if (m_constructRetainedObjectInfos)
263 m_groupsWhichNeedRetainerInfo.append(root);
397 } else if (classId == v8DOMObjectClassId) { 264 } else if (classId == v8DOMObjectClassId) {
398 m_grouper.addObjectWrapperToGroup(type->opaqueRootForGC(object, wrap per, m_isolate), wrapper); 265 void* root = type->opaqueRootForGC(object, wrapper, m_isolate);
266 m_isolate->SetObjectGroupId(wrapper, v8::UniqueId(reinterpret_cast<i ntptr_t>(root)));
399 } else { 267 } else {
400 ASSERT_NOT_REACHED(); 268 ASSERT_NOT_REACHED();
401 } 269 }
402 } 270 }
403 271
404 void notifyFinished() 272 void notifyFinished()
405 { 273 {
406 m_grouper.apply(); 274 if (!m_constructRetainedObjectInfos)
275 return;
276 std::sort(m_groupsWhichNeedRetainerInfo.begin(), m_groupsWhichNeedRetain erInfo.end());
277 Node* alreadyAdded = 0;
278 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler();
279 for (size_t i = 0; i < m_groupsWhichNeedRetainerInfo.size(); ++i) {
280 Node* root = m_groupsWhichNeedRetainerInfo[i];
281 if (root != alreadyAdded) {
282 profiler->SetRetainedObjectInfo(v8::UniqueId(reinterpret_cast<in tptr_t>(root)), new RetainedDOMInfo(root));
283 alreadyAdded = root;
284 }
285 }
407 } 286 }
408 287
409 private: 288 private:
410 WrapperGrouper m_grouper; 289 v8::UniqueId liveRootId()
290 {
291 const v8::Persistent<v8::Value>& liveRoot = V8PerIsolateData::from(m_iso late)->ensureLiveRoot();
292 v8::UniqueId id(reinterpret_cast<intptr_t>(*liveRoot));
293 if (!m_liveRootGroupIdSet) {
294 m_isolate->SetObjectGroupId(*liveRoot, id);
295 m_liveRootGroupIdSet = true;
296 }
297 return id;
298 }
299
411 v8::Isolate* m_isolate; 300 v8::Isolate* m_isolate;
301 Vector<Node*> m_groupsWhichNeedRetainerInfo;
302 bool m_liveRootGroupIdSet;
303 bool m_constructRetainedObjectInfos;
412 }; 304 };
413 305
414 void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags) 306 void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags)
415 { 307 {
416 // It would be nice if the GC callbacks passed the Isolate directly.... 308 // It would be nice if the GC callbacks passed the Isolate directly....
417 if (type == v8::kGCTypeScavenge) 309 if (type == v8::kGCTypeScavenge)
418 minorGCPrologue(v8::Isolate::GetCurrent()); 310 minorGCPrologue(v8::Isolate::GetCurrent());
419 else if (type == v8::kGCTypeMarkSweepCompact) 311 else if (type == v8::kGCTypeMarkSweepCompact)
420 majorGCPrologue(); 312 majorGCPrologue(flags & v8::kGCCallbackFlagConstructRetainedObjectInfos) ;
421 } 313 }
422 314
423 void V8GCController::minorGCPrologue(v8::Isolate* isolate) 315 void V8GCController::minorGCPrologue(v8::Isolate* isolate)
424 { 316 {
425 TRACE_EVENT_BEGIN0("v8", "GC"); 317 TRACE_EVENT_BEGIN0("v8", "GC");
426 318
427 if (isMainThread()) { 319 if (isMainThread()) {
428 v8::HandleScope scope; 320 v8::HandleScope scope;
429 321
430 MinorGCWrapperVisitor visitor(isolate); 322 MinorGCWrapperVisitor visitor(isolate);
431 v8::V8::VisitHandlesForPartialDependence(isolate, &visitor); 323 v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
432 visitor.notifyFinished(); 324 visitor.notifyFinished();
433 } 325 }
434 } 326 }
435 327
436 // Create object groups for DOM tree nodes. 328 // Create object groups for DOM tree nodes.
437 void V8GCController::majorGCPrologue() 329 void V8GCController::majorGCPrologue(bool constructRetainedObjectInfos)
438 { 330 {
439 TRACE_EVENT_BEGIN0("v8", "GC"); 331 TRACE_EVENT_BEGIN0("v8", "GC");
440 332
441 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 333 v8::Isolate* isolate = v8::Isolate::GetCurrent();
442 v8::HandleScope scope; 334 v8::HandleScope scope;
443 335
444 MajorGCWrapperVisitor visitor(isolate); 336 MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos);
445 v8::V8::VisitHandlesWithClassIds(&visitor); 337 v8::V8::VisitHandlesWithClassIds(&visitor);
446 visitor.notifyFinished(); 338 visitor.notifyFinished();
447 339
448 V8PerIsolateData::from(isolate)->stringCache()->clearOnGC(); 340 V8PerIsolateData::from(isolate)->stringCache()->clearOnGC();
449 } 341 }
450 342
451 static int workingSetEstimateMB = 0; 343 static int workingSetEstimateMB = 0;
452 344
453 static Mutex& workingSetEstimateMBMutex() 345 static Mutex& workingSetEstimateMBMutex()
454 { 346 {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
538 if (!script.IsEmpty()) { 430 if (!script.IsEmpty()) {
539 V8RecursionScope::MicrotaskSuppression scope; 431 V8RecursionScope::MicrotaskSuppression scope;
540 script->Run(); 432 script->Run();
541 } 433 }
542 } 434 }
543 435
544 context.clear(); 436 context.clear();
545 } 437 }
546 438
547 } // namespace WebCore 439 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/bindings/v8/V8GCController.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698