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

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: . 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 | « no previous file | Source/bindings/v8/V8PerIsolateData.cpp » ('j') | 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 "V8Binding.h" 40 #include "V8Binding.h"
41 #include "V8MessagePort.h" 41 #include "V8MessagePort.h"
42 #include "V8MutationObserver.h" 42 #include "V8MutationObserver.h"
43 #include "V8Node.h" 43 #include "V8Node.h"
44 #include "V8RecursionScope.h" 44 #include "V8RecursionScope.h"
45 #include "WrapperTypeInfo.h" 45 #include "WrapperTypeInfo.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 size_t i = 0;
138 while (i < m_connections.size()) {
139 void* root = m_connections[i].root();
140 v8::Persistent<v8::Object> groupRepresentativeWrapper = m_connection s[i].wrapper();
141 OwnPtr<RetainedObjectInfo> retainedObjectInfo = m_connections[i].ret ainedObjectInfo();
142
143 do {
144 group.append(m_connections[i++].wrapper());
145 } while (i < m_connections.size() && root == m_connections[i].root() );
146
147 if (group.size() > 1)
148 v8::V8::AddObjectGroup(group.data(), group.size(), retainedObjec tInfo.leakPtr());
149
150 HashMap<void*, v8::Persistent<v8::Object> >::iterator iter = m_rootG roupMap.find(root);
151 if (iter != m_rootGroupMap.end())
152 iter->value = groupRepresentativeWrapper;
153
154 group.shrink(0);
155 }
156
157 std::sort(m_references.begin(), m_references.end());
158 i = 0;
159 while (i < m_references.size()) {
160 void* parent = m_references[i].parent;
161 v8::Persistent<v8::Object> parentWrapper = m_rootGroupMap.get(parent );
162 if (parentWrapper.IsEmpty()) {
163 ++i;
164 continue;
165 }
166
167 Vector<v8::Persistent<v8::Value> > children;
168 do {
169 children.append(m_references[i++].child);
170 } while (i < m_references.size() && parent == m_references[i].parent );
171
172 v8::V8::AddImplicitReferences(parentWrapper, children.data(), childr en.size());
173 }
174 }
175
176 private:
177 Vector<v8::Persistent<v8::Value> > m_liveObjects;
178 Vector<ImplicitConnection> m_connections;
179 Vector<ImplicitReference> m_references;
180 HashMap<void*, v8::Persistent<v8::Object> > m_rootGroupMap;
181 };
182
183 // FIXME: This should use opaque GC roots. 50 // FIXME: This should use opaque GC roots.
184 static void addImplicitReferencesForNodeWithEventListeners(Node* node, v8::Persi stent<v8::Object> wrapper) 51 static void addImplicitReferencesForNodeWithEventListeners(v8::Isolate* isolate, Node* node, v8::Persistent<v8::Object> wrapper)
185 { 52 {
186 ASSERT(node->hasEventListeners()); 53 ASSERT(node->hasEventListeners());
187 54
188 Vector<v8::Persistent<v8::Value> > listeners; 55 // Add a new object group just for the wrapper.
56 v8::UniqueId id(reinterpret_cast<intptr_t>(*wrapper));
57 v8::V8::SetObjectGroupId(isolate, wrapper, id);
189 58
190 EventListenerIterator iterator(node); 59 EventListenerIterator iterator(node);
191 while (EventListener* listener = iterator.nextListener()) { 60 while (EventListener* listener = iterator.nextListener()) {
192 if (listener->type() != EventListener::JSEventListenerType) 61 if (listener->type() != EventListener::JSEventListenerType)
193 continue; 62 continue;
194 V8AbstractEventListener* v8listener = static_cast<V8AbstractEventListene r*>(listener); 63 V8AbstractEventListener* v8listener = static_cast<V8AbstractEventListene r*>(listener);
195 if (!v8listener->hasExistingListenerObject()) 64 if (!v8listener->hasExistingListenerObject())
196 continue; 65 continue;
197 listeners.append(v8listener->existingListenerObjectPersistentHandle()); 66
67 v8::V8::AddImplicitReference(isolate, id, v8listener->existingListenerOb jectPersistentHandle());
198 } 68 }
199
200 if (listeners.isEmpty())
201 return;
202
203 v8::V8::AddImplicitReferences(wrapper, listeners.data(), listeners.size());
204 } 69 }
205 70
206 Node* V8GCController::opaqueRootForGC(Node* node, v8::Isolate*) 71 Node* V8GCController::opaqueRootForGC(Node* node, v8::Isolate*)
207 { 72 {
208 // FIXME: Remove the special handling for image elements. 73 // FIXME: Remove the special handling for image elements.
209 // The same special handling is in V8GCController::gcTree(). 74 // The same special handling is in V8GCController::gcTree().
210 // Maybe should image elements be active DOM nodes? 75 // Maybe should image elements be active DOM nodes?
211 // See https://code.google.com/p/chromium/issues/detail?id=164882 76 // See https://code.google.com/p/chromium/issues/detail?id=164882
212 if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && static_cas t<HTMLImageElement*>(node)->hasPendingActivity())) 77 if (node->inDocument() || (node->hasTagName(HTMLNames::imgTag) && static_cas t<HTMLImageElement*>(node)->hasPendingActivity()))
213 return node->document(); 78 return node->document();
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 219
355 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); 220 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper);
356 void* object = toNative(wrapper); 221 void* object = toNative(wrapper);
357 222
358 if (V8MessagePort::info.equals(type)) { 223 if (V8MessagePort::info.equals(type)) {
359 // Mark each port as in-use if it's entangled. For simplicity's sake , 224 // Mark each port as in-use if it's entangled. For simplicity's sake ,
360 // we assume all ports are remotely entangled, since the Chromium po rt 225 // we assume all ports are remotely entangled, since the Chromium po rt
361 // implementation can't tell the difference. 226 // implementation can't tell the difference.
362 MessagePort* port = static_cast<MessagePort*>(object); 227 MessagePort* port = static_cast<MessagePort*>(object);
363 if (port->isEntangled() || port->hasPendingActivity()) 228 if (port->isEntangled() || port->hasPendingActivity())
364 m_grouper.keepAlive(wrapper); 229 SetObjectGroupId(wrapper, *V8PerIsolateData::current()->ensureLi veRoot());
365 } else if (V8MutationObserver::info.equals(type)) { 230 } else if (V8MutationObserver::info.equals(type)) {
366 // FIXME: Allow opaqueRootForGC to operate on multiple roots and mov e this logic into V8MutationObserverCustom. 231 // FIXME: Allow opaqueRootForGC to operate on multiple roots and mov e this logic into V8MutationObserverCustom.
367 MutationObserver* observer = static_cast<MutationObserver*>(object); 232 MutationObserver* observer = static_cast<MutationObserver*>(object);
368 HashSet<Node*> observedNodes = observer->getObservedNodes(); 233 HashSet<Node*> observedNodes = observer->getObservedNodes();
369 for (HashSet<Node*>::iterator it = observedNodes.begin(); it != obse rvedNodes.end(); ++it) 234 for (HashSet<Node*>::iterator it = observedNodes.begin(); it != obse rvedNodes.end(); ++it)
370 m_grouper.addImplicitReference(V8GCController::opaqueRootForGC(* it, m_isolate), wrapper); 235 v8::V8::AddImplicitReference(m_isolate, v8::UniqueId(reinterpret _cast<intptr_t>(V8GCController::opaqueRootForGC(*it, m_isolate))), wrapper);
371 } else { 236 } else {
372 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper); 237 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper);
373 if (activeDOMObject && activeDOMObject->hasPendingActivity()) 238 if (activeDOMObject && activeDOMObject->hasPendingActivity())
374 m_grouper.keepAlive(wrapper); 239 SetObjectGroupId(wrapper, *V8PerIsolateData::current()->ensureLi veRoot());
375 } 240 }
376 241
377 if (classId == v8DOMNodeClassId) { 242 if (classId == v8DOMNodeClassId) {
378 UNUSED_PARAM(m_isolate); 243 UNUSED_PARAM(m_isolate);
379 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate)); 244 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate));
380 ASSERT(!wrapper.IsIndependent(m_isolate)); 245 ASSERT(!wrapper.IsIndependent(m_isolate));
381 246
382 Node* node = static_cast<Node*>(object); 247 Node* node = static_cast<Node*>(object);
383 248
384 if (node->hasEventListeners()) 249 if (node->hasEventListeners())
385 addImplicitReferencesForNodeWithEventListeners(node, wrapper); 250 addImplicitReferencesForNodeWithEventListeners(m_isolate, node, wrapper);
386 251 Node* root = V8GCController::opaqueRootForGC(node, m_isolate);
387 m_grouper.addNodeWrapperToGroup(V8GCController::opaqueRootForGC(node , m_isolate), wrapper); 252 SetObjectGroupId(wrapper, root);
253 MaybeAddRetainedObjectInfo(root);
388 } else if (classId == v8DOMObjectClassId) { 254 } else if (classId == v8DOMObjectClassId) {
389 m_grouper.addObjectWrapperToGroup(type->opaqueRootForGC(object, wrap per, m_isolate), wrapper); 255 void* root = type->opaqueRootForGC(object, wrapper, m_isolate);
256 SetObjectGroupId(wrapper, root);
390 } else { 257 } else {
391 ASSERT_NOT_REACHED(); 258 ASSERT_NOT_REACHED();
392 } 259 }
393 } 260 }
394 261
395 void notifyFinished() 262 void MaybeAddRetainedObjectInfo(Node* root)
abarth-chromium 2013/04/12 17:23:44 MaybeAddRetainedObjectInfo -> maybeAddRetainedObje
396 { 263 {
397 m_grouper.apply(); 264 if (root && !groups_with_retained_info_.contains(root)) {
265 v8::V8::SetRetainedObjectInfo(m_isolate, v8::UniqueId(reinterpret_ca st<intptr_t>(root)), new RetainedDOMInfo(root));
266 groups_with_retained_info_.add(root);
267 }
268 }
269
270 void SetObjectGroupId(const v8::Persistent<v8::Object>& object, void* root)
abarth-chromium 2013/04/12 17:23:44 SetObjectGroupId -> setObjectGroupId
271 {
272 v8::UniqueId id(reinterpret_cast<intptr_t>(root));
273 v8::V8::SetObjectGroupId(m_isolate, object, id);
274 if (!groups_with_representative_objects_.contains(root)) {
275 v8::V8::SetObjectGroupRepresentativeObject(m_isolate, id, object);
276 groups_with_representative_objects_.add(root);
277 }
398 } 278 }
399 279
400 private: 280 private:
401 WrapperGrouper m_grouper;
402 v8::Isolate* m_isolate; 281 v8::Isolate* m_isolate;
282 HashSet<Node*> groups_with_retained_info_;
abarth-chromium 2013/04/12 17:23:44 m_groupsWithRetainedInfo
283 HashSet<void*> groups_with_representative_objects_;
abarth-chromium 2013/04/12 17:23:44 m_groupsWithRepresentiveObjects
403 }; 284 };
404 285
405 void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags) 286 void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags)
406 { 287 {
407 // It would be nice if the GC callbacks passed the Isolate directly.... 288 // It would be nice if the GC callbacks passed the Isolate directly....
408 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 289 v8::Isolate* isolate = v8::Isolate::GetCurrent();
409 if (type == v8::kGCTypeScavenge) 290 if (type == v8::kGCTypeScavenge)
410 minorGCPrologue(isolate); 291 minorGCPrologue(isolate);
411 else if (type == v8::kGCTypeMarkSweepCompact) 292 else if (type == v8::kGCTypeMarkSweepCompact)
412 majorGCPrologue(); 293 majorGCPrologue();
(...skipping 16 matching lines...) Expand all
429 // Create object groups for DOM tree nodes. 310 // Create object groups for DOM tree nodes.
430 void V8GCController::majorGCPrologue() 311 void V8GCController::majorGCPrologue()
431 { 312 {
432 TRACE_EVENT_BEGIN0("v8", "GC"); 313 TRACE_EVENT_BEGIN0("v8", "GC");
433 314
434 v8::Isolate* isolate = v8::Isolate::GetCurrent(); 315 v8::Isolate* isolate = v8::Isolate::GetCurrent();
435 v8::HandleScope scope; 316 v8::HandleScope scope;
436 317
437 MajorGCWrapperVisitor visitor(isolate); 318 MajorGCWrapperVisitor visitor(isolate);
438 v8::V8::VisitHandlesWithClassIds(&visitor); 319 v8::V8::VisitHandlesWithClassIds(&visitor);
439 visitor.notifyFinished();
440 320
441 V8PerIsolateData::from(isolate)->stringCache()->clearOnGC(); 321 V8PerIsolateData::from(isolate)->stringCache()->clearOnGC();
442 } 322 }
443 323
444 static int workingSetEstimateMB = 0; 324 static int workingSetEstimateMB = 0;
445 325
446 static Mutex& workingSetEstimateMBMutex() 326 static Mutex& workingSetEstimateMBMutex()
447 { 327 {
448 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex); 328 AtomicallyInitializedStatic(Mutex&, mutex = *new Mutex);
449 return mutex; 329 return mutex;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
531 if (!script.IsEmpty()) { 411 if (!script.IsEmpty()) {
532 V8RecursionScope::MicrotaskSuppression scope; 412 V8RecursionScope::MicrotaskSuppression scope;
533 script->Run(); 413 script->Run();
534 } 414 }
535 } 415 }
536 416
537 context.clear(); 417 context.clear();
538 } 418 }
539 419
540 } // namespace WebCore 420 } // namespace WebCore
OLDNEW
« no previous file with comments | « no previous file | Source/bindings/v8/V8PerIsolateData.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698