Changeset 141577 in webkit
- Timestamp:
- Feb 1, 2013 3:49:35 AM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r141574 r141577 1 2013-02-01 Kentaro Hara <haraken@chromium.org> 2 3 Unreviewed, rolling out r141548. 4 http://trac.webkit.org/changeset/141548 5 https://bugs.webkit.org/show_bug.cgi?id=108579 6 7 userscript-plugin-document.html is flaky 8 9 * bindings/v8/DOMDataStore.h: 10 (WebCore::DOMDataStore::setWrapperInObject): 11 * bindings/v8/V8GCController.cpp: 12 (WebCore): 13 (WebCore::gcTree): 14 (WebCore::V8GCController::didCreateWrapperForNode): 15 (WebCore::V8GCController::gcPrologue): 16 (WebCore::V8GCController::minorGCPrologue): 17 (WebCore::V8GCController::majorGCPrologue): 18 * bindings/v8/V8GCController.h: 19 (V8GCController): 20 1 21 2013-02-01 Andrey Adaikin <aandrey@chromium.org> 2 22 -
trunk/Source/WebCore/bindings/v8/DOMDataStore.h
r141548 r141577 165 165 wrapper.MakeWeak(object, weakCallback); 166 166 } 167 static void setWrapperInObject(Node* object, v8::Persistent<v8::Object> wrapper) 168 { 169 ASSERT(object->wrapper().IsEmpty()); 170 object->setWrapper(wrapper); 171 V8GCController::didCreateWrapperForNode(object); 172 wrapper.MakeWeak(static_cast<ScriptWrappable*>(object), weakCallback); 173 } 167 174 168 175 static void weakCallback(v8::Persistent<v8::Value>, void* context); -
trunk/Source/WebCore/bindings/v8/V8GCController.cpp
r141548 r141577 179 179 } 180 180 181 static void gcTree(Node* startNode) 182 { 183 Vector<v8::Persistent<v8::Value>, initialNodeVectorSize> newSpaceWrappers; 184 185 // We traverse a DOM tree in the DFS order starting from startNode. 186 // The traversal order does not matter for correctness but does matter for performance. 187 Node* node = startNode; 188 // To make each minor GC time bounded, we might need to give up 189 // traversing at some point for a large DOM tree. That being said, 190 // I could not observe the need even in pathological test cases. 191 do { 192 ASSERT(node); 193 if (!node->wrapper().IsEmpty()) { 194 // FIXME: Remove the special handling for image elements. 195 // The same special handling is in V8GCController::opaqueRootForGC(). 196 // Maybe should image elements be active DOM nodes? 197 // See https://code.google.com/p/chromium/issues/detail?id=164882 198 if (!node->isV8CollectableDuringMinorGC() || (node->hasTagName(HTMLNames::imgTag) && static_cast<HTMLImageElement*>(node)->hasPendingActivity())) { 199 // This node is not in the new space of V8. This indicates that 200 // the minor GC cannot anyway judge reachability of this DOM tree. 201 // Thus we give up traversing the DOM tree. 202 return; 203 } 204 node->setV8CollectableDuringMinorGC(false); 205 newSpaceWrappers.append(node->wrapper()); 206 } 207 if (node->firstChild()) { 208 node = node->firstChild(); 209 continue; 210 } 211 while (!node->nextSibling()) { 212 if (!node->parentNode()) 213 break; 214 node = node->parentNode(); 215 } 216 if (node->parentNode()) 217 node = node->nextSibling(); 218 } while (node != startNode); 219 220 // We completed the DOM tree traversal. All wrappers in the DOM tree are 221 // stored in newSpaceWrappers and are expected to exist in the new space of V8. 222 // We report those wrappers to V8 as an object group. 223 for (size_t i = 0; i < newSpaceWrappers.size(); i++) 224 newSpaceWrappers[i].MarkPartiallyDependent(); 225 if (newSpaceWrappers.size() > 0) 226 v8::V8::AddObjectGroup(&newSpaceWrappers[0], newSpaceWrappers.size()); 227 } 228 229 // Regarding a minor GC algorithm for DOM nodes, see this document: 230 // https://docs.google.com/a/google.com/presentation/d/1uifwVYGNYTZDoGLyCb7sXa7g49mWNMW2gaWvMN5NLk8/edit#slide=id.p 231 class MinorGCWrapperVisitor : public v8::PersistentHandleVisitor { 232 public: 233 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t classId) OVERRIDE 234 { 235 // A minor DOM GC can collect only Nodes. 236 if (classId != v8DOMNodeClassId) 237 return; 238 239 // To make minor GC cycle time bounded, we limit the number of wrappers handled 240 // by each minor GC cycle to 10000. This value was selected so that the minor 241 // GC cycle time is bounded to 20 ms in a case where the new space size 242 // is 16 MB and it is full of wrappers (which is almost the worst case). 243 // Practically speaking, as far as I crawled real web applications, 244 // the number of wrappers handled by each minor GC cycle is at most 3000. 245 // So this limit is mainly for pathological micro benchmarks. 246 const unsigned wrappersHandledByEachMinorGC = 10000; 247 if (m_nodesInNewSpace.size() >= wrappersHandledByEachMinorGC) 248 return; 249 250 ASSERT(value->IsObject()); 251 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(value); 252 ASSERT(V8DOMWrapper::maybeDOMWrapper(value)); 253 ASSERT(V8Node::HasInstance(wrapper)); 254 Node* node = V8Node::toNative(wrapper); 255 m_nodesInNewSpace.append(node); 256 node->setV8CollectableDuringMinorGC(true); 257 } 258 259 void notifyFinished() 260 { 261 for (size_t i = 0; i < m_nodesInNewSpace.size(); i++) { 262 ASSERT(!m_nodesInNewSpace[i]->wrapper().IsEmpty()); 263 if (m_nodesInNewSpace[i]->isV8CollectableDuringMinorGC()) // This branch is just for performance. 264 gcTree(m_nodesInNewSpace[i]); 265 } 266 } 267 268 private: 269 Vector<Node*> m_nodesInNewSpace; 270 }; 271 272 class MajorGCWrapperVisitor : public v8::PersistentHandleVisitor { 181 class WrapperVisitor : public v8::PersistentHandleVisitor { 273 182 public: 274 183 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t classId) OVERRIDE … … 333 242 }; 334 243 244 // Regarding a minor GC algorithm for DOM nodes, see this document: 245 // https://docs.google.com/a/google.com/presentation/d/1uifwVYGNYTZDoGLyCb7sXa7g49mWNMW2gaWvMN5NLk8/edit#slide=id.p 246 // 247 // m_edenNodes stores nodes that have wrappers that have been created since the last minor/major GC. 248 Vector<Node*>* V8GCController::m_edenNodes = 0; 249 250 static void gcTree(Node* startNode) 251 { 252 Vector<v8::Persistent<v8::Value>, initialNodeVectorSize> newSpaceWrappers; 253 254 // We traverse a DOM tree in the DFS order starting from startNode. 255 // The traversal order does not matter for correctness but does matter for performance. 256 Node* node = startNode; 257 // To make each minor GC time bounded, we might need to give up 258 // traversing at some point for a large DOM tree. That being said, 259 // I could not observe the need even in pathological test cases. 260 do { 261 ASSERT(node); 262 if (!node->wrapper().IsEmpty()) { 263 // FIXME: Remove the special handling for image elements. 264 // The same special handling is in V8GCController::opaqueRootForGC(). 265 // Maybe should image elements be active DOM nodes? 266 // See https://code.google.com/p/chromium/issues/detail?id=164882 267 if (!node->isV8CollectableDuringMinorGC() || (node->hasTagName(HTMLNames::imgTag) && static_cast<HTMLImageElement*>(node)->hasPendingActivity())) { 268 // The fact that we encounter a node that is not in the Eden space 269 // implies that its wrapper might be in the old space of V8. 270 // This indicates that the minor GC cannot anyway judge reachability 271 // of this DOM tree. Thus we give up traversing the DOM tree. 272 return; 273 } 274 // A once traversed node is removed from the Eden space. 275 node->setV8CollectableDuringMinorGC(false); 276 newSpaceWrappers.append(node->wrapper()); 277 } 278 if (node->firstChild()) { 279 node = node->firstChild(); 280 continue; 281 } 282 while (!node->nextSibling()) { 283 if (!node->parentNode()) 284 break; 285 node = node->parentNode(); 286 } 287 if (node->parentNode()) 288 node = node->nextSibling(); 289 } while (node != startNode); 290 291 // We completed the DOM tree traversal. All wrappers in the DOM tree are 292 // stored in newSpaceWrappers and are expected to exist in the new space of V8. 293 // We report those wrappers to V8 as an object group. 294 for (size_t i = 0; i < newSpaceWrappers.size(); i++) 295 newSpaceWrappers[i].MarkPartiallyDependent(); 296 if (newSpaceWrappers.size() > 0) 297 v8::V8::AddObjectGroup(&newSpaceWrappers[0], newSpaceWrappers.size()); 298 } 299 300 void V8GCController::didCreateWrapperForNode(Node* node) 301 { 302 // To make minor GC cycle time bounded, we limit the number of wrappers handled 303 // by each minor GC cycle to 10000. This value was selected so that the minor 304 // GC cycle time is bounded to 20 ms in a case where the new space size 305 // is 16 MB and it is full of wrappers (which is almost the worst case). 306 // Practically speaking, as far as I crawled real web applications, 307 // the number of wrappers handled by each minor GC cycle is at most 3000. 308 // So this limit is mainly for pathological micro benchmarks. 309 const unsigned wrappersHandledByEachMinorGC = 10000; 310 ASSERT(!node->wrapper().IsEmpty()); 311 if (!m_edenNodes) 312 m_edenNodes = adoptPtr(new Vector<Node*>).leakPtr(); 313 if (m_edenNodes->size() <= wrappersHandledByEachMinorGC) { 314 // A node of a newly created wrapper is put into the Eden space. 315 m_edenNodes->append(node); 316 node->setV8CollectableDuringMinorGC(true); 317 } 318 } 319 335 320 void V8GCController::gcPrologue(v8::GCType type, v8::GCCallbackFlags flags) 336 321 { … … 339 324 else if (type == v8::kGCTypeMarkSweepCompact) 340 325 majorGCPrologue(); 326 327 if (isMainThreadOrGCThread() && m_edenNodes) { 328 // The Eden space is cleared at every minor/major GC. 329 m_edenNodes->clear(); 330 } 341 331 } 342 332 … … 345 335 TRACE_EVENT_BEGIN0("v8", "GC"); 346 336 347 v8::HandleScope scope; 348 349 MinorGCWrapperVisitor visitor; 350 v8::V8::VisitHandlesForPartialDependence(v8::Isolate::GetCurrent(), &visitor); 351 visitor.notifyFinished(); 337 if (isMainThreadOrGCThread() && m_edenNodes) { 338 for (size_t i = 0; i < m_edenNodes->size(); i++) { 339 ASSERT(!m_edenNodes->at(i)->wrapper().IsEmpty()); 340 if (m_edenNodes->at(i)->isV8CollectableDuringMinorGC()) // This branch is just for performance. 341 gcTree(m_edenNodes->at(i)); 342 } 343 } 352 344 } 353 345 … … 359 351 v8::HandleScope scope; 360 352 361 MajorGCWrapperVisitor visitor;353 WrapperVisitor visitor; 362 354 v8::V8::VisitHandlesWithClassIds(&visitor); 363 355 visitor.notifyFinished(); -
trunk/Source/WebCore/bindings/v8/V8GCController.h
r141548 r141577 53 53 54 54 static Node* opaqueRootForGC(Node*); 55 static void didCreateWrapperForNode(Node*); 55 56 56 57 private:
Note: See TracChangeset
for help on using the changeset viewer.