Revert "Use DoublyLinkedList instead of ListHashSet in DocumentState"

This reverts commit 252e8a49c9383eceebe0938a1e876f0b4ab5aa8e.

Reason for revert: Caused http://crbug.com/790739

Original change's description:
> Use DoublyLinkedList instead of ListHashSet in DocumentState
>
> The only operations carried out on form_controls_ are insertions, removals
> and iterating through the entire list. Insertion and removal can be done
> faster with a DoublyLinkedList.
>
> Since the nodes for the DoublyLinkedList are Oilpan objects, this CL
> introduces HeapDoublyLinkedList that uses Member for the head and tail
> pointers, and traces the pointers.
>
> This improves the performance of HTMLInputElement::InsertedInto and
> HTMLInputElement::RemovedFrom by ~15%.
>
> Bug:
> Change-Id: I5b4cd20737e0276bece2430edfb7ec9609690f04
> Reviewed-on: https://chromium-review.googlesource.com/758877
> Reviewed-by: Kentaro Hara <haraken@chromium.org>
> Reviewed-by: Keishi Hattori <keishi@chromium.org>
> Reviewed-by: Jeremy Roman <jbroman@chromium.org>
> Commit-Queue: Adithya Srinivasan <adithyas@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#517876}

Bug: 790739
TBR=jbroman@chromium.org,haraken@chromium.org,keishi@chromium.org,adithyas@chromium.org,lfg@chromium.org

Change-Id: I48ddedd7b356efa6b1f6f69c58e2022e9a0872f1
Reviewed-on: https://chromium-review.googlesource.com/802774
Commit-Queue: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Kenneth Russell <kbr@chromium.org>
Reviewed-by: Kentaro Hara <haraken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#520840}
diff --git a/third_party/WebKit/Source/core/html/forms/FormController.cpp b/third_party/WebKit/Source/core/html/forms/FormController.cpp
index 535b3ce..3157e8d7 100644
--- a/third_party/WebKit/Source/core/html/forms/FormController.cpp
+++ b/third_party/WebKit/Source/core/html/forms/FormController.cpp
@@ -410,14 +410,14 @@
 }
 
 void DocumentState::AddControl(HTMLFormControlElementWithState* control) {
-  DCHECK(!control->Next() && !control->Prev());
-  form_controls_.Append(control);
+  auto result = form_controls_.insert(control);
+  DCHECK(result.is_new_entry);
 }
 
 void DocumentState::RemoveControl(HTMLFormControlElementWithState* control) {
-  form_controls_.Remove(control);
-  control->SetPrev(nullptr);
-  control->SetNext(nullptr);
+  auto it = form_controls_.find(control);
+  CHECK(it != form_controls_.end());
+  form_controls_.erase(it);
 }
 
 static String FormStateSignature() {
@@ -433,8 +433,8 @@
   FormKeyGenerator* key_generator = FormKeyGenerator::Create();
   std::unique_ptr<SavedFormStateMap> state_map =
       WTF::WrapUnique(new SavedFormStateMap);
-  for (HTMLFormControlElementWithState* control = form_controls_.Head();
-       control; control = control->Next()) {
+  for (const auto& form_control : form_controls_) {
+    HTMLFormControlElementWithState* control = form_control.Get();
     DCHECK(control->isConnected());
     if (!control->ShouldSaveAndRestoreFormControlState())
       continue;
diff --git a/third_party/WebKit/Source/core/html/forms/FormController.h b/third_party/WebKit/Source/core/html/forms/FormController.h
index c21565d5..7ec8019 100644
--- a/third_party/WebKit/Source/core/html/forms/FormController.h
+++ b/third_party/WebKit/Source/core/html/forms/FormController.h
@@ -25,7 +25,6 @@
 
 #include <memory>
 #include "platform/heap/Handle.h"
-#include "platform/heap/HeapAllocator.h"
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/Forward.h"
 #include "platform/wtf/ListHashSet.h"
@@ -92,8 +91,9 @@
   Vector<String> ToStateVector();
 
  private:
-  using FormElementList = HeapDoublyLinkedList<HTMLFormControlElementWithState>;
-  FormElementList form_controls_;
+  using FormElementListHashSet =
+      HeapListHashSet<Member<HTMLFormControlElementWithState>, 64>;
+  FormElementListHashSet form_controls_;
 };
 
 class FormController final : public GarbageCollectedFinalized<FormController> {
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementWithState.cpp b/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementWithState.cpp
index 740ae5a..b8dd24f 100644
--- a/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementWithState.cpp
+++ b/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementWithState.cpp
@@ -87,10 +87,4 @@
   return true;
 }
 
-void HTMLFormControlElementWithState::Trace(Visitor* visitor) {
-  visitor->Trace(prev_);
-  visitor->Trace(next_);
-  HTMLFormControlElement::Trace(visitor);
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementWithState.h b/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementWithState.h
index 0a4db72c..31320d6 100644
--- a/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementWithState.h
+++ b/third_party/WebKit/Source/core/html/forms/HTMLFormControlElementWithState.h
@@ -27,15 +27,13 @@
 
 #include "core/CoreExport.h"
 #include "core/html/forms/HTMLFormControlElement.h"
-#include "platform/wtf/DoublyLinkedList.h"
 
 namespace blink {
 
 class FormControlState;
 
 class CORE_EXPORT HTMLFormControlElementWithState
-    : public HTMLFormControlElement,
-      public DoublyLinkedListNode<HTMLFormControlElementWithState> {
+    : public HTMLFormControlElement {
  public:
   ~HTMLFormControlElementWithState() override;
 
@@ -48,8 +46,6 @@
   virtual void RestoreFormControlState(const FormControlState&) {}
   void NotifyFormStateChanged();
 
-  void Trace(Visitor*) override;
-
  protected:
   HTMLFormControlElementWithState(const QualifiedName& tag_name, Document&);
 
@@ -57,15 +53,6 @@
   InsertionNotificationRequest InsertedInto(ContainerNode*) override;
   void RemovedFrom(ContainerNode*) override;
   bool IsFormControlElementWithState() const final;
-
- private:
-  // Pointers for DoublyLinkedListNode<HTMLFormControlElementWithState>. This
-  // is used for adding an instance to a list of form controls stored in
-  // DocumentState. Each instance is only added to its containing document's
-  // DocumentState list.
-  friend class WTF::DoublyLinkedListNode<HTMLFormControlElementWithState>;
-  Member<HTMLFormControlElementWithState> prev_;
-  Member<HTMLFormControlElementWithState> next_;
 };
 
 DEFINE_TYPE_CASTS(HTMLFormControlElementWithState,
diff --git a/third_party/WebKit/Source/platform/heap/HeapAllocator.h b/third_party/WebKit/Source/platform/heap/HeapAllocator.h
index 60af8f95..490e6b6 100644
--- a/third_party/WebKit/Source/platform/heap/HeapAllocator.h
+++ b/third_party/WebKit/Source/platform/heap/HeapAllocator.h
@@ -12,7 +12,6 @@
 #include "platform/wtf/Allocator.h"
 #include "platform/wtf/Assertions.h"
 #include "platform/wtf/Deque.h"
-#include "platform/wtf/DoublyLinkedList.h"
 #include "platform/wtf/HashCountedSet.h"
 #include "platform/wtf/HashMap.h"
 #include "platform/wtf/HashSet.h"
@@ -480,23 +479,6 @@
       : Deque<T, inlineCapacity, HeapAllocator>(other) {}
 };
 
-template <typename T>
-class HeapDoublyLinkedList : public DoublyLinkedList<T, Member<T>> {
-  IS_GARBAGE_COLLECTED_TYPE();
-  DISALLOW_NEW();
-
- public:
-  HeapDoublyLinkedList() {
-    static_assert(WTF::IsGarbageCollectedType<T>::value,
-                  "This should only be used for garbage collected types.");
-  }
-
-  void Trace(Visitor* visitor) {
-    visitor->Trace(this->head_);
-    visitor->Trace(this->tail_);
-  }
-};
-
 }  // namespace blink
 
 namespace WTF {
diff --git a/third_party/WebKit/Source/platform/heap/HeapTerminatedArray.h b/third_party/WebKit/Source/platform/heap/HeapTerminatedArray.h
index c422d31..5cd2ec8 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTerminatedArray.h
+++ b/third_party/WebKit/Source/platform/heap/HeapTerminatedArray.h
@@ -59,6 +59,12 @@
   friend class WTF::TerminatedArrayBuilder;
 };
 
+template <typename T>
+class TraceEagerlyTrait<HeapTerminatedArray<T>> {
+ public:
+  static const bool value = TraceEagerlyTrait<T>::value;
+};
+
 }  // namespace blink
 
 #endif  // HeapTerminatedArray_h
diff --git a/third_party/WebKit/Source/platform/heap/HeapTest.cpp b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
index d772ab8..99bf5dd8 100644
--- a/third_party/WebKit/Source/platform/heap/HeapTest.cpp
+++ b/third_party/WebKit/Source/platform/heap/HeapTest.cpp
@@ -6709,62 +6709,4 @@
   EXPECT_TRUE(string.Impl()->HasOneRef());
 }
 
-class DoublyLinkedListNodeImpl
-    : public GarbageCollectedFinalized<DoublyLinkedListNodeImpl>,
-      public DoublyLinkedListNode<DoublyLinkedListNodeImpl> {
- public:
-  DoublyLinkedListNodeImpl() {}
-  static DoublyLinkedListNodeImpl* Create() {
-    return new DoublyLinkedListNodeImpl();
-  }
-
-  static int destructor_calls_;
-  ~DoublyLinkedListNodeImpl() { ++destructor_calls_; }
-
-  void Trace(Visitor* visitor) {
-    visitor->Trace(prev_);
-    visitor->Trace(next_);
-  }
-
- private:
-  friend class WTF::DoublyLinkedListNode<DoublyLinkedListNodeImpl>;
-  Member<DoublyLinkedListNodeImpl> prev_;
-  Member<DoublyLinkedListNodeImpl> next_;
-};
-
-int DoublyLinkedListNodeImpl::destructor_calls_ = 0;
-
-template <typename T>
-class HeapDoublyLinkedListContainer
-    : public GarbageCollected<HeapDoublyLinkedListContainer<T>> {
- public:
-  static HeapDoublyLinkedListContainer<T>* Create() {
-    return new HeapDoublyLinkedListContainer<T>();
-  }
-  HeapDoublyLinkedListContainer<T>() {}
-  HeapDoublyLinkedList<T> list_;
-  void Trace(Visitor* visitor) { visitor->Trace(list_); }
-};
-
-TEST(HeapTest, HeapDoublyLinkedList) {
-  Persistent<HeapDoublyLinkedListContainer<DoublyLinkedListNodeImpl>>
-      container =
-          HeapDoublyLinkedListContainer<DoublyLinkedListNodeImpl>::Create();
-  DoublyLinkedListNodeImpl::destructor_calls_ = 0;
-
-  container->list_.Append(DoublyLinkedListNodeImpl::Create());
-  container->list_.Append(DoublyLinkedListNodeImpl::Create());
-
-  PreciselyCollectGarbage();
-  EXPECT_EQ(DoublyLinkedListNodeImpl::destructor_calls_, 0);
-
-  container->list_.RemoveHead();
-  PreciselyCollectGarbage();
-  EXPECT_EQ(DoublyLinkedListNodeImpl::destructor_calls_, 1);
-
-  container->list_.RemoveHead();
-  PreciselyCollectGarbage();
-  EXPECT_EQ(DoublyLinkedListNodeImpl::destructor_calls_, 2);
-}
-
 }  // namespace blink
diff --git a/third_party/WebKit/Source/platform/heap/TraceTraits.h b/third_party/WebKit/Source/platform/heap/TraceTraits.h
index f2464fe..899966d 100644
--- a/third_party/WebKit/Source/platform/heap/TraceTraits.h
+++ b/third_party/WebKit/Source/platform/heap/TraceTraits.h
@@ -27,10 +27,6 @@
 template <typename T>
 class CrossThreadWeakPersistent;
 template <typename T>
-class HeapDoublyLinkedList;
-template <typename T>
-class HeapTerminatedArray;
-template <typename T>
 class Member;
 template <typename T>
 class TraceEagerlyTrait;
@@ -438,20 +434,6 @@
   static const bool value = TraceEagerlyTrait<T>::value;
 };
 
-template <typename T>
-class TraceEagerlyTrait<HeapTerminatedArray<T>> {
- public:
-  static const bool value = TraceEagerlyTrait<T>::value;
-};
-
-template <typename T>
-class TraceEagerlyTrait<HeapDoublyLinkedList<T>> {
-  STATIC_ONLY(TraceEagerlyTrait);
-
- public:
-  static const bool value = TraceEagerlyTrait<T>::value;
-};
-
 template <typename ValueArg, size_t inlineCapacity>
 class HeapListHashSetAllocator;
 template <typename T, size_t inlineCapacity>
diff --git a/third_party/WebKit/Source/platform/wtf/DoublyLinkedList.h b/third_party/WebKit/Source/platform/wtf/DoublyLinkedList.h
index 4c2e9a0..5280f77 100644
--- a/third_party/WebKit/Source/platform/wtf/DoublyLinkedList.h
+++ b/third_party/WebKit/Source/platform/wtf/DoublyLinkedList.h
@@ -70,7 +70,7 @@
   return static_cast<const T*>(this)->next_;
 }
 
-template <typename T, typename PointerType = T*>
+template <typename T>
 class DoublyLinkedList {
   USING_FAST_MALLOC(DoublyLinkedList);
 
@@ -90,90 +90,83 @@
   void Append(T*);
   void Remove(T*);
 
- protected:
-  PointerType head_;
-  PointerType tail_;
+ private:
+  T* head_;
+  T* tail_;
 
   DISALLOW_COPY_AND_ASSIGN(DoublyLinkedList);
 };
 
-template <typename T, typename PointerType>
-inline DoublyLinkedList<T, PointerType>::DoublyLinkedList()
-    : head_(nullptr), tail_(nullptr) {
-  static_assert(
-      !IsGarbageCollectedType<T>::value ||
-          !std::is_same<PointerType, T*>::value,
-      "Cannot use DoublyLinkedList<> with garbage collected types, use "
-      "HeapDoublyLinkedList<> instead.");
-}
+template <typename T>
+inline DoublyLinkedList<T>::DoublyLinkedList() : head_(0), tail_(0) {}
 
-template <typename T, typename PointerType>
-inline bool DoublyLinkedList<T, PointerType>::IsEmpty() const {
+template <typename T>
+inline bool DoublyLinkedList<T>::IsEmpty() const {
   return !head_;
 }
 
-template <typename T, typename PointerType>
-inline size_t DoublyLinkedList<T, PointerType>::size() const {
+template <typename T>
+inline size_t DoublyLinkedList<T>::size() const {
   size_t size = 0;
   for (T* node = head_; node; node = node->Next())
     ++size;
   return size;
 }
 
-template <typename T, typename PointerType>
-inline void DoublyLinkedList<T, PointerType>::Clear() {
-  head_ = nullptr;
-  tail_ = nullptr;
+template <typename T>
+inline void DoublyLinkedList<T>::Clear() {
+  head_ = 0;
+  tail_ = 0;
 }
 
-template <typename T, typename PointerType>
-inline T* DoublyLinkedList<T, PointerType>::Head() const {
+template <typename T>
+inline T* DoublyLinkedList<T>::Head() const {
   return head_;
 }
 
-template <typename T, typename PointerType>
-inline T* DoublyLinkedList<T, PointerType>::Tail() const {
+template <typename T>
+inline T* DoublyLinkedList<T>::Tail() const {
   return tail_;
 }
 
-template <typename T, typename PointerType>
-inline void DoublyLinkedList<T, PointerType>::Push(T* node) {
+template <typename T>
+inline void DoublyLinkedList<T>::Push(T* node) {
   if (!head_) {
     DCHECK(!tail_);
     head_ = node;
     tail_ = node;
-    node->SetPrev(nullptr);
-    node->SetNext(nullptr);
+    node->SetPrev(0);
+    node->SetNext(0);
     return;
   }
 
   DCHECK(tail_);
   head_->SetPrev(node);
   node->SetNext(head_);
-  node->SetPrev(nullptr);
+  node->SetPrev(0);
   head_ = node;
 }
 
-template <typename T, typename PointerType>
-inline void DoublyLinkedList<T, PointerType>::Append(T* node) {
+template <typename T>
+inline void DoublyLinkedList<T>::Append(T* node) {
   if (!tail_) {
     DCHECK(!head_);
     head_ = node;
     tail_ = node;
-    node->SetPrev(nullptr);
-    node->SetNext(nullptr);
+    node->SetPrev(0);
+    node->SetNext(0);
     return;
   }
 
   DCHECK(head_);
   tail_->SetNext(node);
   node->SetPrev(tail_);
-  node->SetNext(nullptr);
+  node->SetNext(0);
   tail_ = node;
 }
 
-template <typename T, typename PointerType>
-inline void DoublyLinkedList<T, PointerType>::Remove(T* node) {
+template <typename T>
+inline void DoublyLinkedList<T>::Remove(T* node) {
   if (node->Prev()) {
     DCHECK_NE(node, head_);
     node->Prev()->SetNext(node->Next());
@@ -191,8 +184,8 @@
   }
 }
 
-template <typename T, typename PointerType>
-inline T* DoublyLinkedList<T, PointerType>::RemoveHead() {
+template <typename T>
+inline T* DoublyLinkedList<T>::RemoveHead() {
   T* node = Head();
   if (node)
     Remove(node);