| OLD | NEW |
| 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 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 // Regarding a minor GC algorithm for DOM nodes, see this document: | 102 // Regarding a minor GC algorithm for DOM nodes, see this document: |
| 103 // https://docs.google.com/a/google.com/presentation/d/1uifwVYGNYTZDoGLyCb7sXa7g
49mWNMW2gaWvMN5NLk8/edit#slide=id.p | 103 // https://docs.google.com/a/google.com/presentation/d/1uifwVYGNYTZDoGLyCb7sXa7g
49mWNMW2gaWvMN5NLk8/edit#slide=id.p |
| 104 class MinorGCWrapperVisitor : public v8::PersistentHandleVisitor { | 104 class MinorGCWrapperVisitor : public v8::PersistentHandleVisitor { |
| 105 public: | 105 public: |
| 106 explicit MinorGCWrapperVisitor(v8::Isolate* isolate) | 106 explicit MinorGCWrapperVisitor(v8::Isolate* isolate) |
| 107 : m_isolate(isolate) | 107 : m_isolate(isolate) |
| 108 { | 108 { |
| 109 UNUSED_PARAM(m_isolate); | 109 UNUSED_PARAM(m_isolate); |
| 110 } | 110 } |
| 111 | 111 |
| 112 #ifdef V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS |
| 112 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t
classId) OVERRIDE | 113 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t
classId) OVERRIDE |
| 113 { | 114 { |
| 115 VisitPersistentHandle(&value, classId); |
| 116 } |
| 117 |
| 118 virtual void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_
t classId) |
| 119 #else |
| 120 virtual void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_
t classId) OVERRIDE |
| 121 #endif |
| 122 { |
| 114 // A minor DOM GC can collect only Nodes. | 123 // A minor DOM GC can collect only Nodes. |
| 115 if (classId != v8DOMNodeClassId) | 124 if (classId != v8DOMNodeClassId) |
| 116 return; | 125 return; |
| 117 | 126 |
| 118 // To make minor GC cycle time bounded, we limit the number of wrappers
handled | 127 // To make minor GC cycle time bounded, we limit the number of wrappers
handled |
| 119 // by each minor GC cycle to 10000. This value was selected so that the
minor | 128 // by each minor GC cycle to 10000. This value was selected so that the
minor |
| 120 // GC cycle time is bounded to 20 ms in a case where the new space size | 129 // GC cycle time is bounded to 20 ms in a case where the new space size |
| 121 // is 16 MB and it is full of wrappers (which is almost the worst case). | 130 // is 16 MB and it is full of wrappers (which is almost the worst case). |
| 122 // Practically speaking, as far as I crawled real web applications, | 131 // Practically speaking, as far as I crawled real web applications, |
| 123 // the number of wrappers handled by each minor GC cycle is at most 3000
. | 132 // the number of wrappers handled by each minor GC cycle is at most 3000
. |
| 124 // So this limit is mainly for pathological micro benchmarks. | 133 // So this limit is mainly for pathological micro benchmarks. |
| 125 const unsigned wrappersHandledByEachMinorGC = 10000; | 134 const unsigned wrappersHandledByEachMinorGC = 10000; |
| 126 if (m_nodesInNewSpace.size() >= wrappersHandledByEachMinorGC) | 135 if (m_nodesInNewSpace.size() >= wrappersHandledByEachMinorGC) |
| 127 return; | 136 return; |
| 128 | 137 |
| 129 ASSERT(value->IsObject()); | 138 ASSERT((*value)->IsObject()); |
| 130 #ifdef V8_USE_UNSAFE_HANDLES | 139 #ifdef V8_USE_UNSAFE_HANDLES |
| 131 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(va
lue); | 140 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(*v
alue); |
| 132 #else | 141 #else |
| 133 v8::Persistent<v8::Object>& wrapper = v8::Persistent<v8::Object>::Cast(v
alue); | 142 v8::Persistent<v8::Object>& wrapper = v8::Persistent<v8::Object>::Cast(*
value); |
| 134 #endif | 143 #endif |
| 135 ASSERT(V8DOMWrapper::maybeDOMWrapper(value)); | 144 ASSERT(V8DOMWrapper::maybeDOMWrapper(*value)); |
| 136 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate)); | 145 ASSERT(V8Node::HasInstanceInAnyWorld(wrapper, m_isolate)); |
| 137 Node* node = V8Node::toNative(wrapper); | 146 Node* node = V8Node::toNative(wrapper); |
| 138 // A minor DOM GC can handle only node wrappers in the main world. | 147 // A minor DOM GC can handle only node wrappers in the main world. |
| 139 // Note that node->wrapper().IsEmpty() returns true for nodes that | 148 // Note that node->wrapper().IsEmpty() returns true for nodes that |
| 140 // do not have wrappers in the main world. | 149 // do not have wrappers in the main world. |
| 141 if (node->containsWrapper()) { | 150 if (node->containsWrapper()) { |
| 142 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); | 151 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); |
| 143 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper); | 152 ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper); |
| 144 if (activeDOMObject && activeDOMObject->hasPendingActivity()) | 153 if (activeDOMObject && activeDOMObject->hasPendingActivity()) |
| 145 return; | 154 return; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 231 | 240 |
| 232 class MajorGCWrapperVisitor : public v8::PersistentHandleVisitor { | 241 class MajorGCWrapperVisitor : public v8::PersistentHandleVisitor { |
| 233 public: | 242 public: |
| 234 explicit MajorGCWrapperVisitor(v8::Isolate* isolate, bool constructRetainedO
bjectInfos) | 243 explicit MajorGCWrapperVisitor(v8::Isolate* isolate, bool constructRetainedO
bjectInfos) |
| 235 : m_isolate(isolate) | 244 : m_isolate(isolate) |
| 236 , m_liveRootGroupIdSet(false) | 245 , m_liveRootGroupIdSet(false) |
| 237 , m_constructRetainedObjectInfos(constructRetainedObjectInfos) | 246 , m_constructRetainedObjectInfos(constructRetainedObjectInfos) |
| 238 { | 247 { |
| 239 } | 248 } |
| 240 | 249 |
| 250 #ifdef V8_USE_OLD_STYLE_PERSISTENT_HANDLE_VISITORS |
| 241 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t
classId) OVERRIDE | 251 virtual void VisitPersistentHandle(v8::Persistent<v8::Value> value, uint16_t
classId) OVERRIDE |
| 242 { | 252 { |
| 243 ASSERT(value->IsObject()); | 253 VisitPersistentHandle(&value, classId); |
| 254 } |
| 255 |
| 256 virtual void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_
t classId) |
| 257 #else |
| 258 virtual void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_
t classId) OVERRIDE |
| 259 #endif |
| 260 { |
| 261 ASSERT((*value)->IsObject()); |
| 244 #ifdef V8_USE_UNSAFE_HANDLES | 262 #ifdef V8_USE_UNSAFE_HANDLES |
| 245 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(va
lue); | 263 v8::Persistent<v8::Object> wrapper = v8::Persistent<v8::Object>::Cast(*v
alue); |
| 246 #else | 264 #else |
| 247 v8::Persistent<v8::Object>& wrapper = v8::Persistent<v8::Object>::Cast(v
alue); | 265 v8::Persistent<v8::Object>& wrapper = v8::Persistent<v8::Object>::Cast(*
value); |
| 248 #endif | 266 #endif |
| 249 | 267 |
| 250 if (classId != v8DOMNodeClassId && classId != v8DOMObjectClassId) | 268 if (classId != v8DOMNodeClassId && classId != v8DOMObjectClassId) |
| 251 return; | 269 return; |
| 252 | 270 |
| 253 ASSERT(V8DOMWrapper::maybeDOMWrapper(value)); | 271 ASSERT(V8DOMWrapper::maybeDOMWrapper(*value)); |
| 254 | 272 |
| 255 if (value.IsIndependent(m_isolate)) | 273 if (value->IsIndependent(m_isolate)) |
| 256 return; | 274 return; |
| 257 | 275 |
| 258 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); | 276 WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); |
| 259 void* object = toNative(wrapper); | 277 void* object = toNative(wrapper); |
| 260 | 278 |
| 261 if (V8MessagePort::info.equals(type)) { | 279 if (V8MessagePort::info.equals(type)) { |
| 262 // Mark each port as in-use if it's entangled. For simplicity's sake
, | 280 // Mark each port as in-use if it's entangled. For simplicity's sake
, |
| 263 // we assume all ports are remotely entangled, since the Chromium po
rt | 281 // we assume all ports are remotely entangled, since the Chromium po
rt |
| 264 // implementation can't tell the difference. | 282 // implementation can't tell the difference. |
| 265 MessagePort* port = static_cast<MessagePort*>(object); | 283 MessagePort* port = static_cast<MessagePort*>(object); |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 444 v8::V8::IdleNotification(longIdlePauseInMS); | 462 v8::V8::IdleNotification(longIdlePauseInMS); |
| 445 } | 463 } |
| 446 | 464 |
| 447 void V8GCController::collectGarbage(v8::Isolate* isolate) | 465 void V8GCController::collectGarbage(v8::Isolate* isolate) |
| 448 { | 466 { |
| 449 v8::HandleScope handleScope(isolate); | 467 v8::HandleScope handleScope(isolate); |
| 450 V8ScriptRunner::compileAndRunInternalScript(v8String("if (gc) gc();", isolat
e), isolate); | 468 V8ScriptRunner::compileAndRunInternalScript(v8String("if (gc) gc();", isolat
e), isolate); |
| 451 } | 469 } |
| 452 | 470 |
| 453 } // namespace WebCore | 471 } // namespace WebCore |
| OLD | NEW |