Index: third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp |
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp |
index 908535a2b661cab50b0fe854a9a53dfb043f663b..0a4ff7833ab65ace85072c2abc2603fb5854d232 100644 |
--- a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp |
+++ b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp |
@@ -30,6 +30,7 @@ |
#include "bindings/core/v8/V8GCController.h" |
+#include "bindings/core/v8/NPV8Object.h" |
#include "bindings/core/v8/RetainedDOMInfo.h" |
#include "bindings/core/v8/V8AbstractEventListener.h" |
#include "bindings/core/v8/V8Binding.h" |
@@ -121,11 +122,8 @@ public: |
v8::Local<v8::Object> wrapper = v8::Local<v8::Object>::New(m_isolate, v8::Persistent<v8::Object>::Cast(*value)); |
ASSERT(V8DOMWrapper::hasInternalFieldsSet(wrapper)); |
const WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); |
- ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper); |
- if (activeDOMObject && activeDOMObject->hasPendingActivity()) { |
- v8::Persistent<v8::Object>::Cast(*value).MarkActive(); |
+ if (type != npObjectTypeInfo() && toScriptWrappable(wrapper)->hasPendingActivity()) |
return; |
- } |
if (classId == WrapperTypeInfo::NodeClassId) { |
ASSERT(V8Node::hasInstance(wrapper, m_isolate)); |
@@ -179,8 +177,7 @@ public: |
const WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); |
- ActiveDOMObject* activeDOMObject = type->toActiveDOMObject(wrapper); |
- if (activeDOMObject && activeDOMObject->hasPendingActivity()) { |
+ if (type != npObjectTypeInfo() && toScriptWrappable(wrapper)->hasPendingActivity()) { |
m_isolate->SetObjectGroupId(*value, liveRootId()); |
++m_domObjectsWithPendingActivity; |
} |
@@ -459,4 +456,49 @@ void V8GCController::traceDOMWrappers(v8::Isolate* isolate, Visitor* visitor) |
isolate->VisitHandlesWithClassIds(&tracer); |
} |
+class PendingActivityVisitor : public v8::PersistentHandleVisitor { |
+public: |
+ explicit PendingActivityVisitor(ExecutionContext* executionContext) |
+ : m_executionContext(executionContext) |
+ , m_pendingActivityFound(false) |
+ { |
+ } |
+ |
+ void VisitPersistentHandle(v8::Persistent<v8::Value>* value, uint16_t classId) override |
+ { |
kinuko
2016/01/25 04:06:25
Could we count how many # of handles this class vi
haraken
2016/01/25 04:08:42
Sounds nice. Will do.
|
+ // If we have already found any wrapper that has a pending activity, |
+ // we don't need to check other wrappers. |
+ if (m_pendingActivityFound) |
kinuko
2016/01/25 04:06:25
Would there be a way to exit the visitor loop once
haraken
2016/01/25 04:08:42
Yeah, in the current V8 API, we don't have a way t
|
+ return; |
+ |
+ if (classId != WrapperTypeInfo::NodeClassId && classId != WrapperTypeInfo::ObjectClassId) |
+ return; |
+ |
+ const v8::Persistent<v8::Object>& wrapper = v8::Persistent<v8::Object>::Cast(*value); |
+ const WrapperTypeInfo* type = toWrapperTypeInfo(wrapper); |
+ // The ExecutionContext check is heavy, so it should be done at the last. |
+ if (type != npObjectTypeInfo() |
+ && toScriptWrappable(wrapper)->hasPendingActivity() |
+ /* && toExecutionContext(v8::Object::CreationContext(wrapper)) == m_executionContext */ |
haraken
2016/01/22 17:15:44
To enable this condition, I need to implement the
|
+ ) |
+ m_pendingActivityFound = true; |
+ } |
+ |
+ bool pendingActivityFound() const { return m_pendingActivityFound; } |
+ |
+private: |
+ RawPtrWillBePersistent<ExecutionContext> m_executionContext; |
+ bool m_pendingActivityFound; |
+}; |
+ |
+bool V8GCController::hasPendingActivity(ExecutionContext* executionContext) |
+{ |
+ // V8GCController::hasPendingActivity is used only when a worker checks if |
+ // the worker contains any wrapper that has pending activities. |
+ ASSERT(!isMainThread()); |
+ PendingActivityVisitor visitor(executionContext); |
+ toIsolate(executionContext)->VisitHandlesWithClassIds(&visitor); |
+ return visitor.pendingActivityFound(); |
+} |
+ |
} // namespace blink |