| 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 b740aec7bb03a16e170237be8a7185f1f80f969e..ad0f11b1d9bf46d062554580886b5ca12c7cc158 100644
|
| --- a/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
|
| +++ b/third_party/WebKit/Source/bindings/core/v8/V8GCController.cpp
|
| @@ -56,28 +56,6 @@
|
|
|
| namespace blink {
|
|
|
| -// FIXME: This should use opaque GC roots.
|
| -static void addReferencesForNodeWithEventListeners(
|
| - v8::Isolate* isolate,
|
| - Node* node,
|
| - const v8::Persistent<v8::Object>& wrapper) {
|
| - ASSERT(node->hasEventListeners());
|
| -
|
| - EventListenerIterator iterator(node);
|
| - while (EventListener* listener = iterator.nextListener()) {
|
| - if (listener->type() != EventListener::JSEventListenerType)
|
| - continue;
|
| - V8AbstractEventListener* v8listener =
|
| - static_cast<V8AbstractEventListener*>(listener);
|
| - if (!v8listener->hasExistingListenerObject())
|
| - continue;
|
| -
|
| - isolate->SetReference(
|
| - wrapper, v8::Persistent<v8::Value>::Cast(
|
| - v8listener->existingListenerObjectPersistentHandle()));
|
| - }
|
| -}
|
| -
|
| Node* V8GCController::opaqueRootForGC(v8::Isolate*, Node* node) {
|
| ASSERT(node);
|
| if (node->isConnected()) {
|
| @@ -292,116 +270,6 @@ v8::HeapProfiler::RetainerInfos V8GCController::getRetainerInfos(
|
| return v8::HeapProfiler::RetainerInfos{tracer->groups(), tracer->edges()};
|
| }
|
|
|
| -class MajorGCWrapperVisitor : public v8::PersistentHandleVisitor {
|
| - public:
|
| - explicit MajorGCWrapperVisitor(v8::Isolate* isolate,
|
| - bool constructRetainedObjectInfos)
|
| - : m_isolate(isolate),
|
| - m_domObjectsWithPendingActivity(0),
|
| - m_liveRootGroupIdSet(false),
|
| - m_constructRetainedObjectInfos(constructRetainedObjectInfos) {}
|
| -
|
| - void VisitPersistentHandle(v8::Persistent<v8::Value>* value,
|
| - uint16_t classId) override {
|
| - if (classId != WrapperTypeInfo::NodeClassId &&
|
| - classId != WrapperTypeInfo::ObjectClassId)
|
| - return;
|
| -
|
| - if (value->IsIndependent())
|
| - return;
|
| -
|
| - v8::Local<v8::Object> wrapper = v8::Local<v8::Object>::New(
|
| - m_isolate, v8::Persistent<v8::Object>::Cast(*value));
|
| - DCHECK(V8DOMWrapper::hasInternalFieldsSet(wrapper));
|
| -
|
| - const WrapperTypeInfo* type = toWrapperTypeInfo(wrapper);
|
| - if (type->isActiveScriptWrappable() &&
|
| - toScriptWrappable(wrapper)->hasPendingActivity()) {
|
| - // Enable hasPendingActivity only when the associated
|
| - // ExecutionContext is not yet detached. This is a work-around
|
| - // to avoid memory leaks caused by hasPendingActivity that keeps
|
| - // returning true forever. This will be okay in practice because
|
| - // the spec requires to stop almost all DOM activities when the
|
| - // associated browsing context is detached. However, the real
|
| - // problem is that some hasPendingActivity's are wrongly implemented
|
| - // and never return false.
|
| - // TODO(haraken): Implement correct lifetime using traceWrapper.
|
| - ExecutionContext* context =
|
| - toExecutionContext(wrapper->CreationContext());
|
| - if (context && !context->isContextDestroyed()) {
|
| - m_isolate->SetObjectGroupId(*value, liveRootId());
|
| - ++m_domObjectsWithPendingActivity;
|
| - }
|
| - }
|
| -
|
| - if (classId == WrapperTypeInfo::NodeClassId) {
|
| - DCHECK(V8Node::hasInstance(wrapper, m_isolate));
|
| - Node* node = V8Node::toImpl(wrapper);
|
| - if (node->hasEventListeners())
|
| - addReferencesForNodeWithEventListeners(
|
| - m_isolate, node, v8::Persistent<v8::Object>::Cast(*value));
|
| - Node* root = V8GCController::opaqueRootForGC(m_isolate, node);
|
| - m_isolate->SetObjectGroupId(
|
| - *value, v8::UniqueId(reinterpret_cast<intptr_t>(root)));
|
| - if (m_constructRetainedObjectInfos)
|
| - m_groupsWhichNeedRetainerInfo.push_back(root);
|
| - } else if (classId == WrapperTypeInfo::ObjectClassId) {
|
| - if (!RuntimeEnabledFeatures::traceWrappablesEnabled()) {
|
| - type->visitDOMWrapper(m_isolate, toScriptWrappable(wrapper),
|
| - v8::Persistent<v8::Object>::Cast(*value));
|
| - }
|
| - } else {
|
| - NOTREACHED();
|
| - }
|
| - }
|
| -
|
| - void notifyFinished() {
|
| - if (!m_constructRetainedObjectInfos)
|
| - return;
|
| - std::sort(m_groupsWhichNeedRetainerInfo.begin(),
|
| - m_groupsWhichNeedRetainerInfo.end());
|
| - Node* alreadyAdded = 0;
|
| - v8::HeapProfiler* profiler = m_isolate->GetHeapProfiler();
|
| - for (size_t i = 0; i < m_groupsWhichNeedRetainerInfo.size(); ++i) {
|
| - Node* root = m_groupsWhichNeedRetainerInfo[i];
|
| - if (root != alreadyAdded) {
|
| - profiler->SetRetainedObjectInfo(
|
| - v8::UniqueId(reinterpret_cast<intptr_t>(root)),
|
| - new RetainedDOMInfo(root));
|
| - alreadyAdded = root;
|
| - }
|
| - }
|
| - if (m_liveRootGroupIdSet) {
|
| - profiler->SetRetainedObjectInfo(
|
| - liveRootId(),
|
| - new SuspendableObjectsInfo(m_domObjectsWithPendingActivity));
|
| - }
|
| - }
|
| -
|
| - private:
|
| - v8::UniqueId liveRootId() {
|
| - const v8::Persistent<v8::Value>& liveRoot =
|
| - V8PerIsolateData::from(m_isolate)->ensureLiveRoot();
|
| - const intptr_t* idPointer = reinterpret_cast<const intptr_t*>(&liveRoot);
|
| - v8::UniqueId id(*idPointer);
|
| - if (!m_liveRootGroupIdSet) {
|
| - m_isolate->SetObjectGroupId(liveRoot, id);
|
| - m_liveRootGroupIdSet = true;
|
| - ++m_domObjectsWithPendingActivity;
|
| - }
|
| - return id;
|
| - }
|
| -
|
| - v8::Isolate* m_isolate;
|
| - // v8 guarantees that Blink will not regain control while a v8 GC runs
|
| - // (=> no Oilpan GCs will be triggered), hence raw, untraced members
|
| - // can safely be kept here.
|
| - Vector<UntracedMember<Node>> m_groupsWhichNeedRetainerInfo;
|
| - int m_domObjectsWithPendingActivity;
|
| - bool m_liveRootGroupIdSet;
|
| - bool m_constructRetainedObjectInfos;
|
| -};
|
| -
|
| static unsigned long long usedHeapSize(v8::Isolate* isolate) {
|
| v8::HeapStatistics heapStatistics;
|
| isolate->GetHeapStatistics(&heapStatistics);
|
| @@ -415,21 +283,6 @@ void visitWeakHandlesForMinorGC(v8::Isolate* isolate) {
|
| isolate->VisitWeakHandles(&visitor);
|
| }
|
|
|
| -void objectGroupingForMajorGC(v8::Isolate* isolate,
|
| - bool constructRetainedObjectInfos) {
|
| - MajorGCWrapperVisitor visitor(isolate, constructRetainedObjectInfos);
|
| - isolate->VisitHandlesWithClassIds(&visitor);
|
| - visitor.notifyFinished();
|
| -}
|
| -
|
| -void gcPrologueForMajorGC(v8::Isolate* isolate,
|
| - bool constructRetainedObjectInfos) {
|
| - if (!RuntimeEnabledFeatures::traceWrappablesEnabled() ||
|
| - constructRetainedObjectInfos) {
|
| - objectGroupingForMajorGC(isolate, constructRetainedObjectInfos);
|
| - }
|
| -}
|
| -
|
| } // namespace
|
|
|
| void V8GCController::gcPrologue(v8::Isolate* isolate,
|
| @@ -466,8 +319,6 @@ void V8GCController::gcPrologue(v8::Isolate* isolate,
|
| TRACE_EVENT_BEGIN2("devtools.timeline,v8", "MajorGC",
|
| "usedHeapSizeBefore", usedHeapSize(isolate), "type",
|
| "atomic pause");
|
| - gcPrologueForMajorGC(
|
| - isolate, flags & v8::kGCCallbackFlagConstructRetainedObjectInfos);
|
| break;
|
| case v8::kGCTypeIncrementalMarking:
|
| if (ThreadState::current())
|
| @@ -476,8 +327,6 @@ void V8GCController::gcPrologue(v8::Isolate* isolate,
|
| TRACE_EVENT_BEGIN2("devtools.timeline,v8", "MajorGC",
|
| "usedHeapSizeBefore", usedHeapSize(isolate), "type",
|
| "incremental marking");
|
| - gcPrologueForMajorGC(
|
| - isolate, flags & v8::kGCCallbackFlagConstructRetainedObjectInfos);
|
| break;
|
| case v8::kGCTypeProcessWeakCallbacks:
|
| TRACE_EVENT_BEGIN2("devtools.timeline,v8", "MajorGC",
|
|
|