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

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: only ctruct retainedobjectinfos if necessary Created 7 years, 8 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 addImplicitReferencesForNodeWithEventListeners(v8::Isolate* isolate, Node* node, const v8::Persistent<v8::Object>& wrapper)
haraken 2013/04/25 14:55:54 addImplicitReferencesForNodeWithEventListeners =>
marja 2013/04/26 08:14:47 As agreed offline: addReferencesFromNodeToEventLis
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> newSpaceWrappers;
haraken 2013/04/25 14:55:54 newSpaceWrappers => newSpaceNodes
marja 2013/04/26 08:14:47 Done.
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 newSpaceWrappers.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 newSpaceWrappers 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 = newSpaceWrappers.begin();
275 const v8::Persistent<v8::Value>* wrapperIteratorEnd = newSpaceWrappers.end() ; 132 Node** const nodeIteratorEnd = newSpaceWrappers.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 = v8::Persistent<v8::Object>((*nodeIt erator)->wrapper());
haraken 2013/04/25 14:55:54 Nit: It looks redundant to access (*nodeIterator)-
marja 2013/04/26 08:14:47 Discussed offline -> not changing this. Streamlien
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), m_liveRootGroupIdSet(false), m_constructRetainedOb jectInfos(constructRetainedObjectInfos)
haraken 2013/04/25 14:55:54 Nit: We normally write one initialization per line
marja 2013/04/26 08:14:47 Done.
348 { 209 {
349 } 210 }
350 211
351 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t classId) OVERRIDE 212 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t classId) OVERRIDE
352 { 213 {
353 ASSERT(value->IsObject()); 214 ASSERT(value->IsObject());
354 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(va lue); 215 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(va lue);
355 216
356 if (classId != v8DOMNodeClassId && classId != v8DOMObjectClassId) 217 if (classId != v8DOMNodeClassId && classId != v8DOMObjectClassId)
357 return; 218 return;
358 219
359 ASSERT(V8DOMWrapper::maybeDOMWrapper(value)); 220 ASSERT(V8DOMWrapper::maybeDOMWrapper(value));
360 221
361 if (value.IsIndependent(m_isolate)) 222 if (value.IsIndependent(m_isolate))
362 return; 223 return;
363 224
364 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); 225 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper);
365 void* object = toNative(wrapper); 226 void* object = toNative(wrapper);
366 227
367 if (V8MessagePort::info.equals(type)) { 228 if (V8MessagePort::info.equals(type)) {
368 // Mark each port as in-use if it's entangled. For simplicity's sake , 229 // 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 230 // we assume all ports are remotely entangled, since the Chromium po rt
370 // implementation can't tell the difference. 231 // implementation can't tell the difference.
371 MessagePort* port = static_cast<MessagePort*>(object); 232 MessagePort* port = static_cast<MessagePort*>(object);
372 if (port->isEntangled() || port->hasPendingActivity()) 233 if (port->isEntangled() || port->hasPendingActivity())
373 m_grouper.keepAlive(wrapper); 234 setObjectGroupId(wrapper, ensureLiveRoot());
374 } else if (V8MutationObserver::info.equals(type)) { 235 } else if (V8MutationObserver::info.equals(type)) {
375 // FIXME: Allow opaqueRootForGC to operate on multiple roots and mov e this logic into V8MutationObserverCustom. 236 // FIXME: Allow opaqueRootForGC to operate on multiple roots and mov e this logic into V8MutationObserverCustom.
376 MutationObserver* observer = static_cast<MutationObserver*>(object); 237 MutationObserver* observer = static_cast<MutationObserver*>(object);
377 HashSet<Node*> observedNodes = observer->getObservedNodes(); 238 HashSet<Node*> observedNodes = observer->getObservedNodes();
378 for (HashSet<Node*>::iterator it = observedNodes.begin(); it != obse rvedNodes.end(); ++it) 239 for (HashSet<Node*>::iterator it = observedNodes.begin(); it != obse rvedNodes.end(); ++it)
379 m_grouper.addImplicitReference(V8GCController::opaqueRootForGC(* it, m_isolate), wrapper); 240 m_isolate->SetReferenceFromGroup(v8::UniqueId(reinterpret_cast<i ntptr_t>(V8GCController::opaqueRootForGC(*it, m_isolate))), wrapper);
haraken 2013/04/25 14:55:54 Nit: Shall we write this in two lines? v8::Unique
marja 2013/04/26 08:14:47 Offline discussion -> not going to change the logi
380 } else { 241 } else {
381 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper); 242 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper);
382 if (activeDOMObject && activeDOMObject->hasPendingActivity()) 243 if (activeDOMObject && activeDOMObject->hasPendingActivity())
383 m_grouper.keepAlive(wrapper); 244 setObjectGroupId(wrapper, ensureLiveRoot());
384 } 245 }
385 246
386 if (classId == v8DOMNodeClassId) { 247 if (classId == v8DOMNodeClassId) {
387 UNUSED_PARAM(m_isolate); 248 UNUSED_PARAM(m_isolate);
388 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate)); 249 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate));
389 ASSERT(!wrapper.IsIndependent(m_isolate)); 250 ASSERT(!wrapper.IsIndependent(m_isolate));
390 251
391 Node* node = static_cast<Node*>(object); 252 Node* node = static_cast<Node*>(object);
392 253
393 if (node->hasEventListeners()) 254 if (node->hasEventListeners())
394 addImplicitReferencesForNodeWithEventListeners(node, wrapper); 255 addImplicitReferencesForNodeWithEventListeners(m_isolate, node, wrapper);
395 256 Node* root = V8GCController::opaqueRootForGC(node, m_isolate);
396 m_grouper.addNodeWrapperToGroup(V8GCController::opaqueRootForGC(node , m_isolate), wrapper); 257 setObjectGroupId(wrapper, root);
258 if (m_constructRetainedObjectInfos)
259 m_groupsWhichNeedRetainerInfo.append(root);
397 } else if (classId == v8DOMObjectClassId) { 260 } else if (classId == v8DOMObjectClassId) {
398 m_grouper.addObjectWrapperToGroup(type->opaqueRootForGC(object, wrap per, m_isolate), wrapper); 261 void* root = type->opaqueRootForGC(object, wrapper, m_isolate);
262 setObjectGroupId(wrapper, root);
399 } else { 263 } else {
400 ASSERT_NOT_REACHED(); 264 ASSERT_NOT_REACHED();
401 } 265 }
402 } 266 }
403 267
404 void notifyFinished() 268 void notifyFinished() {
405 { 269 std::sort(m_groupsWhichNeedRetainerInfo.begin(), m_groupsWhichNeedRetain erInfo.end());
406 m_grouper.apply(); 270 Node* already_added = 0;
haraken 2013/04/25 14:55:54 Nit: already_added => alreadyAdded
marja 2013/04/26 08:14:47 Done.
271 v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler();
272 for (size_t i = 0; i < m_groupsWhichNeedRetainerInfo.size(); ++i) {
273 Node* root = m_groupsWhichNeedRetainerInfo[i];
274 if (root != already_added) {
275 profiler->SetRetainedObjectInfo(v8::UniqueId(reinterpret_cast<in tptr_t>(root)), new RetainedDOMInfo(root));
276 already_added = root;
277 }
278 }
407 } 279 }
408 280
409 private: 281 private:
410 WrapperGrouper m_grouper; 282 void setObjectGroupId(const v8::Persistent<v8::Object>& object, void* root)
283 {
284 v8::UniqueId id(reinterpret_cast<intptr_t>(root));
285 m_isolate->SetObjectGroupId(object, id);
286 }
287
288 void* ensureLiveRoot()
289 {
290 v8::Persistent<v8::Value> liveRoot = V8PerIsolateData::current()->ensure LiveRoot();
haraken 2013/04/25 14:55:54 V8PerIsolateData::current() is heavy. You should u
marja 2013/04/26 08:14:47 Ahh, thanks for pointing that out. The previous ve
291 if (!m_liveRootGroupIdSet) {
292 v8::UniqueId id(reinterpret_cast<intptr_t>(*liveRoot));
293 m_isolate->SetObjectGroupId(*liveRoot, id);
294 m_liveRootGroupIdSet = true;
295 }
296 return *liveRoot;
haraken 2013/04/25 14:55:54 How about returning id from this method? Currentl
marja 2013/04/26 08:14:47 Done.
297 }
298
411 v8::Isolate* m_isolate; 299 v8::Isolate* m_isolate;
300 Vector<Node*> m_groupsWhichNeedRetainerInfo;
301 bool m_liveRootGroupIdSet;
302 bool m_constructRetainedObjectInfos;
412 }; 303 };
413 304
414 void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags) 305 void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags)
415 { 306 {
416 // It would be nice if the GC callbacks passed the Isolate directly.... 307 // It would be nice if the GC callbacks passed the Isolate directly....
417 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 308 v8::Isolate* isolate = v8::Isolate::GetCurrent();
418 if (type == v8::kGCTypeScavenge) 309 if (type == v8::kGCTypeScavenge)
419 minorGCPrologue(isolate); 310 minorGCPrologue(isolate);
420 else if (type == v8::kGCTypeMarkSweepCompact) 311 else if (type == v8::kGCTypeMarkSweepCompact)
421 majorGCPrologue(); 312 majorGCPrologue(flags & v8::kGCCallbackFlagConstructRetainedObjectInfos) ;
422 } 313 }
423 314
424 void V8GCController::minorGCPrologue(v8::Isolate* isolate) 315 void V8GCController::minorGCPrologue(v8::Isolate* isolate)
425 { 316 {
426 TRACE_EVENT_BEGIN0("v8", "GC"); 317 TRACE_EVENT_BEGIN0("v8", "GC");
427 318
428 if (isMainThread()) { 319 if (isMainThread()) {
429 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 320 v8::Isolate* isolate = v8::Isolate::GetCurrent();
430 v8::HandleScope scope; 321 v8::HandleScope scope;
431 322
432 MinorGCWrapperVisitor visitor(isolate); 323 MinorGCWrapperVisitor visitor(isolate);
433 v8::V8::VisitHandlesForPartialDependence(isolate, &visitor); 324 v8::V8::VisitHandlesForPartialDependence(isolate, &visitor);
434 visitor.notifyFinished(); 325 visitor.notifyFinished();
435 } 326 }
436 } 327 }
437 328
438 // Create object groups for DOM tree nodes. 329 // Create object groups for DOM tree nodes.
439 void V8GCController::majorGCPrologue() 330 void V8GCController::majorGCPrologue(bool constructRetainedObjectInfos)
440 { 331 {
441 TRACE_EVENT_BEGIN0("v8", "GC"); 332 TRACE_EVENT_BEGIN0("v8", "GC");
442 333
443 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 334 v8::Isolate* isolate = v8::Isolate::GetCurrent();
444 v8::HandleScope scope; 335 v8::HandleScope scope;
445 336
446 MajorGCWrapperVisitor visitor(isolate); 337 MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos);
447 v8::V8::VisitHandlesWithClassIds(&visitor); 338 v8::V8::VisitHandlesWithClassIds(&visitor);
448 visitor.notifyFinished(); 339 visitor.notifyFinished();
449 340
450 V8PerIsolateData::from(isolate)->stringCache()->clearOnGC(); 341 V8PerIsolateData::from(isolate)->stringCache()->clearOnGC();
451 } 342 }
452 343
453 static int workingSetEstimateMB = 0; 344 static int workingSetEstimateMB = 0;
454 345
455 static Mutex& workingSetEstimateMBMutex() 346 static Mutex& workingSetEstimateMBMutex()
456 { 347 {
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 if (!script.IsEmpty()) { 431 if (!script.IsEmpty()) {
541 V8RecursionScope::MicrotaskSuppression scope; 432 V8RecursionScope::MicrotaskSuppression scope;
542 script->Run(); 433 script->Run();
543 } 434 }
544 } 435 }
545 436
546 context.clear(); 437 context.clear();
547 } 438 }
548 439
549 } // namespace WebCore 440 } // 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