[wrapper-tracing] Trace EventListener_s through EventListenerMap

Aligns behavior as closely as possible to Oilpan and remove the
manual write barrier when attaching event listeners.

Bug: 
Change-Id: I39d421e53cd2779fdb97a0a3c996ebc63a8918a9
Reviewed-on: https://chromium-review.googlesource.com/618888
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Commit-Queue: Michael Lippautz <mlippautz@chromium.org>
Cr-Commit-Position: refs/heads/master@{#495275}
diff --git a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.h b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.h
index a99866a..996fcc3 100644
--- a/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.h
+++ b/third_party/WebKit/Source/bindings/core/v8/V8AbstractEventListener.h
@@ -52,8 +52,7 @@
 // Why does this matter?
 // WebKit does not allow duplicated HTML event handlers of the same type,
 // but ALLOWs duplicated non-HTML event handlers.
-class CORE_EXPORT V8AbstractEventListener : public EventListener,
-                                            public TraceWrapperBase {
+class CORE_EXPORT V8AbstractEventListener : public EventListener {
  public:
   ~V8AbstractEventListener() override;
 
diff --git a/third_party/WebKit/Source/core/dom/Node.cpp b/third_party/WebKit/Source/core/dom/Node.cpp
index 84702ed0..0481aff4 100644
--- a/third_party/WebKit/Source/core/dom/Node.cpp
+++ b/third_party/WebKit/Source/core/dom/Node.cpp
@@ -2002,7 +2002,8 @@
 }
 
 using EventTargetDataMap =
-    PersistentHeapHashMap<WeakMember<Node>, Member<EventTargetData>>;
+    PersistentHeapHashMap<WeakMember<Node>,
+                          TraceWrapperMember<EventTargetData>>;
 static EventTargetDataMap& GetEventTargetDataMap() {
   DEFINE_STATIC_LOCAL(EventTargetDataMap, map, ());
   return map;
@@ -2639,6 +2640,7 @@
     visitor->Trace(RareData());
 
   visitor->Trace(tree_scope_);
+  // EventTargetData is traced through EventTargetDataMap.
   EventTarget::Trace(visitor);
 }
 
@@ -2648,6 +2650,8 @@
   visitor->TraceWrappers(next_);
   if (HasRareData())
     visitor->TraceWrappersWithManualWriteBarrier(RareData());
+  visitor->TraceWrappersWithManualWriteBarrier(
+      const_cast<Node*>(this)->GetEventTargetData());
   EventTarget::TraceWrappers(visitor);
 }
 
diff --git a/third_party/WebKit/Source/core/events/EventListener.h b/third_party/WebKit/Source/core/events/EventListener.h
index 03045cc..fd1b362 100644
--- a/third_party/WebKit/Source/core/events/EventListener.h
+++ b/third_party/WebKit/Source/core/events/EventListener.h
@@ -22,6 +22,7 @@
 #define EventListener_h
 
 #include "core/CoreExport.h"
+#include "platform/bindings/ScriptWrappable.h"
 #include "platform/heap/Handle.h"
 #include "platform/wtf/text/WTFString.h"
 
@@ -31,7 +32,8 @@
 class ExecutionContext;
 
 class CORE_EXPORT EventListener
-    : public GarbageCollectedFinalized<EventListener> {
+    : public GarbageCollectedFinalized<EventListener>,
+      public TraceWrapperBase {
  public:
   enum ListenerType {
     kJSEventListenerType,
@@ -54,6 +56,7 @@
   ListenerType GetType() const { return type_; }
 
   DEFINE_INLINE_VIRTUAL_TRACE() {}
+  DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() {}
 
  protected:
   explicit EventListener(ListenerType type) : type_(type) {}
diff --git a/third_party/WebKit/Source/core/events/EventListenerMap.cpp b/third_party/WebKit/Source/core/events/EventListenerMap.cpp
index fbf07c3..8d6e3bc 100644
--- a/third_party/WebKit/Source/core/events/EventListenerMap.cpp
+++ b/third_party/WebKit/Source/core/events/EventListenerMap.cpp
@@ -209,45 +209,13 @@
   visitor->Trace(entries_);
 }
 
-EventListenerIterator::EventListenerIterator(EventTarget* target)
-    : map_(nullptr), entry_index_(0), index_(0) {
-  DCHECK(target);
-  EventTargetData* data = target->GetEventTargetData();
-
-  if (!data)
-    return;
-
-  map_ = &data->event_listener_map;
-
-#if DCHECK_IS_ON()
-  {
-    MutexLocker locker(ActiveIteratorCountMutex());
-    map_->active_iterator_count_++;
+DEFINE_TRACE_WRAPPERS(EventListenerMap) {
+  // Trace wrappers in entries_.
+  for (auto& entry : entries_) {
+    for (auto& listener : *entry.second) {
+      visitor->TraceWrappers(listener);
+    }
   }
-#endif
-}
-
-#if DCHECK_IS_ON()
-EventListenerIterator::~EventListenerIterator() {
-  if (map_) {
-    MutexLocker locker(ActiveIteratorCountMutex());
-    map_->active_iterator_count_--;
-  }
-}
-#endif
-
-EventListener* EventListenerIterator::NextListener() {
-  if (!map_)
-    return nullptr;
-
-  for (; entry_index_ < map_->entries_.size(); ++entry_index_) {
-    EventListenerVector& listeners = *map_->entries_[entry_index_].second;
-    if (index_ < listeners.size())
-      return listeners[index_++].Listener();
-    index_ = 0;
-  }
-
-  return nullptr;
 }
 
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/events/EventListenerMap.h b/third_party/WebKit/Source/core/events/EventListenerMap.h
index ca45eb0..664e40ca 100644
--- a/third_party/WebKit/Source/core/events/EventListenerMap.h
+++ b/third_party/WebKit/Source/core/events/EventListenerMap.h
@@ -37,6 +37,7 @@
 #include "core/events/AddEventListenerOptionsResolved.h"
 #include "core/events/EventListenerOptions.h"
 #include "core/events/RegisteredEventListener.h"
+#include "platform/bindings/ScriptWrappableVisitor.h"
 #include "platform/wtf/Noncopyable.h"
 #include "platform/wtf/text/AtomicStringHash.h"
 
@@ -73,6 +74,7 @@
   void CopyEventListenersNotCreatedFromMarkupToTarget(EventTarget*);
 
   DECLARE_TRACE();
+  DECLARE_TRACE_WRAPPERS();
 
  private:
   friend class EventListenerIterator;
@@ -90,26 +92,6 @@
 #endif
 };
 
-class EventListenerIterator {
-  WTF_MAKE_NONCOPYABLE(EventListenerIterator);
-  STACK_ALLOCATED();
-
- public:
-  explicit EventListenerIterator(EventTarget*);
-#if DCHECK_IS_ON()
-  ~EventListenerIterator();
-#endif
-
-  EventListener* NextListener();
-
- private:
-  // This cannot be a Member because it is pointing to a part of object.
-  // TODO(haraken): Use Member<EventTarget> instead of EventListenerMap*.
-  EventListenerMap* map_;
-  unsigned entry_index_;
-  unsigned index_;
-};
-
 #if !DCHECK_IS_ON()
 inline void EventListenerMap::CheckNoActiveIterators() {}
 #endif
diff --git a/third_party/WebKit/Source/core/events/EventTarget.cpp b/third_party/WebKit/Source/core/events/EventTarget.cpp
index 42e75ff..ad67357 100644
--- a/third_party/WebKit/Source/core/events/EventTarget.cpp
+++ b/third_party/WebKit/Source/core/events/EventTarget.cpp
@@ -155,14 +155,8 @@
   visitor->Trace(event_listener_map);
 }
 
-DEFINE_TRACE_WRAPPERS(EventTarget) {
-  EventListenerIterator iterator(const_cast<EventTarget*>(this));
-  while (EventListener* listener = iterator.NextListener()) {
-    if (listener->GetType() != EventListener::kJSEventListenerType)
-      continue;
-    visitor->TraceWrappersWithManualWriteBarrier(
-        static_cast<V8AbstractEventListener*>(listener));
-  }
+DEFINE_TRACE_WRAPPERS(EventTargetData) {
+  visitor->TraceWrappers(event_listener_map);
 }
 
 EventTarget::EventTarget() {}
@@ -357,10 +351,6 @@
   bool added = EnsureEventTargetData().event_listener_map.Add(
       event_type, listener, options, &registered_listener);
   if (added) {
-    if (listener->GetType() == EventListener::kJSEventListenerType) {
-      ScriptWrappableVisitor::WriteBarrier(
-          static_cast<V8AbstractEventListener*>(listener));
-    }
     AddedEventListener(event_type, registered_listener);
   }
   return added;
diff --git a/third_party/WebKit/Source/core/events/EventTarget.h b/third_party/WebKit/Source/core/events/EventTarget.h
index 9be4bcd..5c8b23bd 100644
--- a/third_party/WebKit/Source/core/events/EventTarget.h
+++ b/third_party/WebKit/Source/core/events/EventTarget.h
@@ -79,11 +79,14 @@
   ~EventTargetData();
 
   DECLARE_TRACE();
+  DECLARE_TRACE_WRAPPERS();
 
   EventListenerMap event_listener_map;
   std::unique_ptr<FiringEventIteratorVector> firing_event_iterators;
 };
 
+DEFINE_TRAIT_FOR_TRACE_WRAPPERS(EventTargetData);
+
 // All DOM event targets extend EventTarget. The spec is defined here:
 // https://dom.spec.whatwg.org/#interface-eventtarget
 // EventTarget objects allow us to add and remove an event
@@ -173,8 +176,7 @@
   static DispatchEventResult GetDispatchEventResult(const Event&);
 
   DEFINE_INLINE_VIRTUAL_TRACE() {}
-
-  DECLARE_VIRTUAL_TRACE_WRAPPERS();
+  DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() {}
 
   virtual bool KeepEventInNode(Event*) { return false; }
 
@@ -234,6 +236,11 @@
     EventTarget::Trace(visitor);
   }
 
+  DEFINE_INLINE_VIRTUAL_TRACE_WRAPPERS() {
+    visitor->TraceWrappers(event_target_data_);
+    EventTarget::TraceWrappers(visitor);
+  }
+
  protected:
   EventTargetData* GetEventTargetData() final { return &event_target_data_; }
   EventTargetData& EnsureEventTargetData() final { return event_target_data_; }
diff --git a/third_party/WebKit/Source/core/events/RegisteredEventListener.h b/third_party/WebKit/Source/core/events/RegisteredEventListener.h
index 6d8ea9e6..1909a0f 100644
--- a/third_party/WebKit/Source/core/events/RegisteredEventListener.h
+++ b/third_party/WebKit/Source/core/events/RegisteredEventListener.h
@@ -27,6 +27,7 @@
 
 #include "core/events/AddEventListenerOptionsResolved.h"
 #include "core/events/EventListener.h"
+#include "platform/bindings/TraceWrapperMember.h"
 #include "platform/wtf/RefPtr.h"
 
 namespace blink {
@@ -55,6 +56,7 @@
         passive_specified_(options.PassiveSpecified()) {}
 
   DEFINE_INLINE_TRACE() { visitor->Trace(listener_); }
+  DEFINE_INLINE_TRACE_WRAPPERS() { visitor->TraceWrappers(listener_); }
 
   AddEventListenerOptionsResolved Options() const {
     AddEventListenerOptionsResolved result;
@@ -108,7 +110,7 @@
   }
 
  private:
-  Member<EventListener> listener_;
+  TraceWrapperMember<EventListener> listener_;
   unsigned use_capture_ : 1;
   unsigned passive_ : 1;
   unsigned once_ : 1;
diff --git a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h
index 439161f..cb745ad 100644
--- a/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h
+++ b/third_party/WebKit/Source/platform/bindings/ScriptWrappableVisitor.h
@@ -170,13 +170,21 @@
   // Member and |TraceWrappersWithManualWriteBarrier()|. See below.
   template <typename T>
   void TraceWrappers(const TraceWrapperMember<T>& t) const {
-    TraceWrappers(t.Get());
+    MarkAndTraceWrappers(t.Get());
+  }
+
+  // Enable partial tracing of objects. This is used when tracing interior
+  // objects without their own header.
+  template <typename T>
+  void TraceWrappers(const T& traceable) const {
+    static_assert(sizeof(T), "T must be fully defined");
+    traceable.TraceWrappers(this);
   }
 
   // Only called from automatically generated bindings code.
   template <typename T>
   void TraceWrappersFromGeneratedCode(const T* traceable) const {
-    TraceWrappers(traceable);
+    MarkAndTraceWrappers(traceable);
   }
 
   // Require all users of manual write barriers to make this explicit in their
@@ -185,17 +193,17 @@
   // the field. Otherwise, the objects may be collected prematurely.
   template <typename T>
   void TraceWrappersWithManualWriteBarrier(const Member<T>& t) const {
-    TraceWrappers(t.Get());
+    MarkAndTraceWrappers(t.Get());
   }
 
   template <typename T>
   void TraceWrappersWithManualWriteBarrier(const WeakMember<T>& t) const {
-    TraceWrappers(t.Get());
+    MarkAndTraceWrappers(t.Get());
   }
 
   template <typename T>
   void TraceWrappersWithManualWriteBarrier(const T* traceable) const {
-    TraceWrappers(traceable);
+    MarkAndTraceWrappers(traceable);
   }
 
   virtual void DispatchTraceWrappers(const TraceWrapperBase*) const;
@@ -230,7 +238,7 @@
   }
 
   template <typename T>
-  void TraceWrappers(const T* traceable) const {
+  void MarkAndTraceWrappers(const T* traceable) const {
     static_assert(sizeof(T), "T must be fully defined");
 
     if (!traceable) {