Revert "ipcz: Ref counted fragments"

This reverts commit 6385cfb931f738334dc59e9d7d39eb7daa70f7ba.

Reason for revert: The introduced tests are consistently failing on 2 Linux builders. First failure on each:

https://ci.chromium.org/ui/p/chromium/builders/ci/Linux%20Tests%20(dbg)(1)/106281/overview

https://ci.chromium.org/ui/p/chromium/builders/ci/linux-chromeos-dbg/29400/overview

Original change's description:
> ipcz: Ref counted fragments
>
> Introduces RefCountedFragment and FragmentRef<T> as helpers to support
> ref-counted objects living in shared memory fragments, as allocated
> via NodeLinkMemory.
>
> Also introduces some builtin BlockAllocators to each NodeLinkMemory's
> primary buffer.
>
> This change lays the ground work for dynamic allocation of managed state
> objects between each connected pair of Routers.
>
> Bug: 1299283
> Change-Id: Ibc2859a8cdcca00fd0d9602664eceaaccb5bd9ae
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3750056
> Reviewed-by: Alex Gough <ajgo@chromium.org>
> Commit-Queue: Ken Rockot <rockot@google.com>
> Cr-Commit-Position: refs/heads/main@{#1021940}

Bug: 1299283
Change-Id: Ib4ac409e26d358366f735b224b233729f4ea257a
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3750295
Commit-Queue: Guillaume Jenkins <gujen@google.com>
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Owners-Override: Guillaume Jenkins <gujen@google.com>
Cr-Commit-Position: refs/heads/main@{#1022125}
NOKEYCHECK=True
GitOrigin-RevId: 02f9e51c84006f83a5dc6f5d47ed038b97274f5e
diff --git a/src/BUILD.gn b/src/BUILD.gn
index 85a4b98..75aef4a 100644
--- a/src/BUILD.gn
+++ b/src/BUILD.gn
@@ -218,7 +218,6 @@
     "ipcz/driver_transport.h",
     "ipcz/fragment.h",
     "ipcz/fragment_descriptor.h",
-    "ipcz/fragment_ref.h",
     "ipcz/link_side.h",
     "ipcz/link_type.h",
     "ipcz/message.h",
@@ -230,7 +229,6 @@
     "ipcz/parcel.h",
     "ipcz/parcel_queue.h",
     "ipcz/portal.h",
-    "ipcz/ref_counted_fragment.h",
     "ipcz/remote_router_link.h",
     "ipcz/router.h",
     "ipcz/sequence_number.h",
@@ -252,7 +250,6 @@
     "ipcz/driver_transport.cc",
     "ipcz/fragment.cc",
     "ipcz/fragment_descriptor.cc",
-    "ipcz/fragment_ref.cc",
     "ipcz/handle_type.h",
     "ipcz/link_side.cc",
     "ipcz/link_type.cc",
@@ -278,7 +275,6 @@
     "ipcz/parcel.cc",
     "ipcz/parcel_queue.cc",
     "ipcz/portal.cc",
-    "ipcz/ref_counted_fragment.cc",
     "ipcz/remote_router_link.cc",
     "ipcz/router.cc",
     "ipcz/router_descriptor.cc",
@@ -334,7 +330,6 @@
     "ipcz/node_connector_test.cc",
     "ipcz/node_link_test.cc",
     "ipcz/parcel_queue_test.cc",
-    "ipcz/ref_counted_fragment_test.cc",
     "ipcz/sequenced_queue_test.cc",
     "reference_drivers/sync_reference_driver_test.cc",
     "remote_portal_test.cc",
diff --git a/src/ipcz/fragment_ref.cc b/src/ipcz/fragment_ref.cc
deleted file mode 100644
index e586924..0000000
--- a/src/ipcz/fragment_ref.cc
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ipcz/fragment_ref.h"
-
-#include <algorithm>
-#include <utility>
-
-#include "ipcz/fragment.h"
-#include "ipcz/node_link_memory.h"
-#include "ipcz/ref_counted_fragment.h"
-#include "util/ref_counted.h"
-
-namespace ipcz::internal {
-
-GenericFragmentRef::GenericFragmentRef() = default;
-
-GenericFragmentRef::GenericFragmentRef(Ref<NodeLinkMemory> memory,
-                                       const Fragment& fragment)
-    : memory_(std::move(memory)), fragment_(fragment) {}
-
-GenericFragmentRef::~GenericFragmentRef() {
-  reset();
-}
-
-void GenericFragmentRef::reset() {
-  Ref<NodeLinkMemory> memory = std::move(memory_);
-  if (fragment_.is_null()) {
-    return;
-  }
-
-  Fragment fragment;
-  std::swap(fragment, fragment_);
-  if (!fragment.is_addressable()) {
-    return;
-  }
-
-  auto* ref_counted = static_cast<RefCountedFragment*>(fragment.address());
-  if (ref_counted->ReleaseRef() > 1 || !memory) {
-    return;
-  }
-
-  memory->buffer_pool().FreeFragment(fragment);
-}
-
-Fragment GenericFragmentRef::release() {
-  Fragment fragment;
-  std::swap(fragment_, fragment);
-  memory_.reset();
-  return fragment;
-}
-
-}  // namespace ipcz::internal
diff --git a/src/ipcz/fragment_ref.h b/src/ipcz/fragment_ref.h
deleted file mode 100644
index e54135b..0000000
--- a/src/ipcz/fragment_ref.h
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IPCZ_SRC_IPCZ_FRAGMENT_REF_H_
-#define IPCZ_SRC_IPCZ_FRAGMENT_REF_H_
-
-#include <algorithm>
-#include <type_traits>
-#include <utility>
-
-#include "ipcz/fragment.h"
-#include "ipcz/fragment_descriptor.h"
-#include "ipcz/ref_counted_fragment.h"
-#include "third_party/abseil-cpp/absl/base/macros.h"
-#include "util/ref_counted.h"
-
-namespace ipcz {
-
-class NodeLinkMemory;
-
-namespace internal {
-
-// Base class for any FragmentRef<T>, implementing common behavior for managing
-// the underlying RefCountedFragment.
-class GenericFragmentRef {
- public:
-  GenericFragmentRef();
-
-  // Does not increase the ref count of the underlying RefCountedFragment,
-  // effectively assuming ownership of a previously acquired ref.
-  GenericFragmentRef(Ref<NodeLinkMemory> memory, const Fragment& fragment);
-
-  ~GenericFragmentRef();
-
-  const Ref<NodeLinkMemory>& memory() const { return memory_; }
-  const Fragment& fragment() const { return fragment_; }
-
-  bool is_null() const { return fragment_.is_null(); }
-  bool is_addressable() const { return fragment_.is_addressable(); }
-  bool is_pending() const { return fragment_.is_pending(); }
-
-  void reset();
-  Fragment release();
-
-  int32_t ref_count_for_testing() const {
-    return AsRefCountedFragment()->ref_count_for_testing();
-  }
-
- protected:
-  RefCountedFragment* AsRefCountedFragment() const {
-    return static_cast<RefCountedFragment*>(fragment_.address());
-  }
-
-  // The NodeLinkMemory who ultimately owns this fragment's memory. May be null
-  // if the FragmentRef is unmanaged.
-  Ref<NodeLinkMemory> memory_;
-
-  Fragment fragment_;
-};
-
-}  // namespace internal
-
-// Holds a reference to a RefCountedFragment. When this object is destroyed, the
-// underlying ref count is decreased. If the ref count is decreased to zero, the
-// underlying Fragment is returned to its NodeLinkMemory.
-//
-// Some FragmentRefs may be designated as "unmanaged", meaning that they will
-// never attempt to free the underlying Fragment. These refs are used to
-// preserve type compatibility with other similar (but managed) FragmentRefs
-// when the underlying Fragment isn't dynamically allocated and can't be freed.
-//
-// For example most RouterLinkState fragments are dynamically allocated and
-// managed by FragmentRefs, but some instances are allocated at fixed locations
-// within the NodeLinkMemory and cannot be freed or reused. In both cases, ipcz
-// can refer to these objects using a FragmentRef<RouterLinkState>.
-template <typename T>
-class FragmentRef : public internal::GenericFragmentRef {
- public:
-  static_assert(std::is_base_of<RefCountedFragment, T>::value,
-                "T must inherit RefCountedFragment for FragmentRef<T>");
-
-  constexpr FragmentRef() = default;
-  constexpr FragmentRef(std::nullptr_t) : FragmentRef() {}
-
-  // Adopts an existing ref to the RefCountedFragment located at the beginning
-  // of `fragment`, which is a Fragment owned by `memory.
-  FragmentRef(decltype(RefCountedFragment::kAdoptExistingRef),
-              Ref<NodeLinkMemory> memory,
-              const Fragment& fragment)
-      : GenericFragmentRef(std::move(memory), fragment) {
-    ABSL_ASSERT(memory_);
-    ABSL_ASSERT(fragment_.is_null() || fragment_.size() >= sizeof(T));
-  }
-
-  // Constructs an unmanaged FragmentRef, which references `fragment` and
-  // updates its refcount, but which never attempts to release `fragment` back
-  // to its NodeLinkMemory. This is only safe to use with Fragments which cannot
-  // be freed.
-  FragmentRef(decltype(RefCountedFragment::kUnmanagedRef),
-              const Fragment& fragment)
-      : GenericFragmentRef(nullptr, fragment) {
-    ABSL_ASSERT(fragment_.is_null() || fragment_.size() >= sizeof(T));
-  }
-
-  FragmentRef(const FragmentRef<T>& other)
-      : GenericFragmentRef(other.memory(), other.fragment()) {
-    if (!fragment_.is_null()) {
-      ABSL_ASSERT(fragment_.is_addressable());
-      AsRefCountedFragment()->AddRef();
-    }
-  }
-
-  FragmentRef(FragmentRef<T>&& other) noexcept
-      : GenericFragmentRef(std::move(other.memory_), other.fragment_) {
-    other.release();
-  }
-
-  FragmentRef<T>& operator=(const FragmentRef<T>& other) {
-    reset();
-    memory_ = other.memory();
-    fragment_ = other.fragment();
-    if (!fragment_.is_null()) {
-      ABSL_ASSERT(fragment_.is_addressable());
-      AsRefCountedFragment()->AddRef();
-    }
-    return *this;
-  }
-
-  FragmentRef<T>& operator=(FragmentRef<T>&& other) {
-    reset();
-    memory_ = std::move(other.memory_);
-    fragment_ = other.release();
-    return *this;
-  }
-
-  T* get() const { return static_cast<T*>(fragment_.address()); }
-  T* operator->() const { return get(); }
-  T& operator*() const { return *get(); }
-};
-
-}  // namespace ipcz
-
-#endif  // IPCZ_SRC_IPCZ_FRAGMENT_REF_H_
diff --git a/src/ipcz/node_link_memory.cc b/src/ipcz/node_link_memory.cc
index 012f26c..5a8aba0 100644
--- a/src/ipcz/node_link_memory.cc
+++ b/src/ipcz/node_link_memory.cc
@@ -25,11 +25,12 @@
 // Fixed allocation size for each NodeLink's primary shared buffer.
 constexpr size_t kPrimaryBufferSize = 65536;
 
-// The front of the primary buffer is reserved for special current and future
-// uses which require synchronous availability throughout a link's lifetime.
-constexpr size_t kPrimaryBufferReservedHeaderSize = 256;
+}  // namespace
 
-struct IPCZ_ALIGN(8) PrimaryBufferHeader {
+// This structure always sits at offset 0 in the primary buffer and has a fixed
+// layout according to the NodeLink's agreed upon protocol version. This is the
+// layout for version 0 (currently the only version.)
+struct IPCZ_ALIGN(8) NodeLinkMemory::PrimaryBuffer {
   // Atomic generator for new unique BufferIds to use across the associated
   // NodeLink. This allows each side of a NodeLink to generate new BufferIds
   // spontaneously without synchronization or risk of collisions.
@@ -41,51 +42,6 @@
   std::atomic<uint64_t> next_sublink_id;
 };
 
-static_assert(sizeof(PrimaryBufferHeader) < kPrimaryBufferReservedHeaderSize);
-
-constexpr size_t kPrimaryBufferHeaderPaddingSize =
-    kPrimaryBufferReservedHeaderSize - sizeof(PrimaryBufferHeader);
-
-}  // namespace
-
-// This structure always sits at offset 0 in the primary buffer and has a fixed
-// layout according to the NodeLink's agreed upon protocol version. This is the
-// layout for version 0 (currently the only version.)
-struct IPCZ_ALIGN(8) NodeLinkMemory::PrimaryBuffer {
-  // Header + padding occupies the first 256 bytes.
-  PrimaryBufferHeader header;
-  uint8_t reserved_header_padding[kPrimaryBufferHeaderPaddingSize];
-
-  // Reserved memory for a series of fixed block allocators. Additional
-  // allocators may be adopted by a NodeLinkMemory over its lifetime, but these
-  // ones remain fixed within the primary buffer.
-  std::array<uint8_t, 4096> mem_for_64_byte_blocks;
-  std::array<uint8_t, 12288> mem_for_256_byte_blocks;
-  std::array<uint8_t, 15360> mem_for_512_byte_blocks;
-  std::array<uint8_t, 11264> mem_for_1024_byte_blocks;
-  std::array<uint8_t, 16384> mem_for_2048_byte_blocks;
-
-  BlockAllocator block_allocator_64() {
-    return BlockAllocator(absl::MakeSpan(mem_for_64_byte_blocks), 64);
-  }
-
-  BlockAllocator block_allocator_256() {
-    return BlockAllocator(absl::MakeSpan(mem_for_256_byte_blocks), 256);
-  }
-
-  BlockAllocator block_allocator_512() {
-    return BlockAllocator(absl::MakeSpan(mem_for_512_byte_blocks), 512);
-  }
-
-  BlockAllocator block_allocator_1024() {
-    return BlockAllocator(absl::MakeSpan(mem_for_1024_byte_blocks), 1024);
-  }
-
-  BlockAllocator block_allocator_2048() {
-    return BlockAllocator(absl::MakeSpan(mem_for_2048_byte_blocks), 2048);
-  }
-};
-
 NodeLinkMemory::NodeLinkMemory(Ref<Node> node,
                                DriverMemoryMapping primary_buffer_memory)
     : node_(std::move(node)),
@@ -96,17 +52,8 @@
   static_assert(sizeof(PrimaryBuffer) <= kPrimaryBufferSize,
                 "PrimaryBuffer structure is too large.");
 
-  buffer_pool_.AddBuffer(kPrimaryBufferId, std::move(primary_buffer_memory));
-  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
-                                      primary_buffer_.block_allocator_64());
-  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
-                                      primary_buffer_.block_allocator_256());
-  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
-                                      primary_buffer_.block_allocator_512());
-  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
-                                      primary_buffer_.block_allocator_1024());
-  buffer_pool_.RegisterBlockAllocator(kPrimaryBufferId,
-                                      primary_buffer_.block_allocator_2048());
+  buffer_pool_.AddBuffer(BufferId{kPrimaryBufferId},
+                         std::move(primary_buffer_memory));
 }
 
 NodeLinkMemory::~NodeLinkMemory() = default;
@@ -124,21 +71,15 @@
   PrimaryBuffer& primary_buffer = memory->primary_buffer_;
 
   // The first allocable BufferId is 1, because the primary buffer uses 0.
-  primary_buffer.header.next_buffer_id.store(1, std::memory_order_relaxed);
+  primary_buffer.next_buffer_id.store(1, std::memory_order_relaxed);
 
   // The first allocable SublinkId is kMaxInitialPortals. This way it doesn't
   // matter whether the two ends of a NodeLink initiate their connection with a
   // different initial portal count: neither can request more than
   // kMaxInitialPortals, so neither will be assuming initial ownership of any
   // SublinkIds at or above this value.
-  primary_buffer.header.next_sublink_id.store(kMaxInitialPortals,
-                                              std::memory_order_release);
-
-  primary_buffer.block_allocator_64().InitializeRegion();
-  primary_buffer.block_allocator_256().InitializeRegion();
-  primary_buffer.block_allocator_512().InitializeRegion();
-  primary_buffer.block_allocator_1024().InitializeRegion();
-  primary_buffer.block_allocator_2048().InitializeRegion();
+  primary_buffer.next_sublink_id.store(kMaxInitialPortals,
+                                       std::memory_order_release);
 
   return {
       .node_link_memory = std::move(memory),
@@ -154,12 +95,12 @@
 }
 
 BufferId NodeLinkMemory::AllocateNewBufferId() {
-  return BufferId{primary_buffer_.header.next_buffer_id.fetch_add(
-      1, std::memory_order_relaxed)};
+  return BufferId{
+      primary_buffer_.next_buffer_id.fetch_add(1, std::memory_order_relaxed)};
 }
 
 SublinkId NodeLinkMemory::AllocateSublinkIds(size_t count) {
-  return SublinkId{primary_buffer_.header.next_sublink_id.fetch_add(
+  return SublinkId{primary_buffer_.next_sublink_id.fetch_add(
       count, std::memory_order_relaxed)};
 }
 
diff --git a/src/ipcz/node_link_memory.h b/src/ipcz/node_link_memory.h
index 014a78e..b4d65a6 100644
--- a/src/ipcz/node_link_memory.h
+++ b/src/ipcz/node_link_memory.h
@@ -63,7 +63,7 @@
   // Exposes the underlying BufferPool which owns all shared buffers for this
   // NodeLinkMemory and which facilitates dynamic allocation of the fragments
   // within.
-  BufferPool& buffer_pool() { return buffer_pool_; }
+  BufferPool& buffer_pool();
 
   // Returns a new BufferId which should still be unused by any buffer in this
   // NodeLinkMemory's BufferPool, or that of its peer NodeLinkMemory. When
diff --git a/src/ipcz/ref_counted_fragment.cc b/src/ipcz/ref_counted_fragment.cc
deleted file mode 100644
index 14b21cf..0000000
--- a/src/ipcz/ref_counted_fragment.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ipcz/ref_counted_fragment.h"
-
-#include "third_party/abseil-cpp/absl/base/macros.h"
-
-namespace ipcz {
-
-RefCountedFragment::RefCountedFragment() = default;
-
-RefCountedFragment::~RefCountedFragment() = default;
-
-void RefCountedFragment::AddRef() {
-  ref_count_.fetch_add(1, std::memory_order_relaxed);
-}
-
-int32_t RefCountedFragment::ReleaseRef() {
-  return ref_count_.fetch_sub(1, std::memory_order_acq_rel);
-}
-
-}  // namespace ipcz
diff --git a/src/ipcz/ref_counted_fragment.h b/src/ipcz/ref_counted_fragment.h
deleted file mode 100644
index ff69c45..0000000
--- a/src/ipcz/ref_counted_fragment.h
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef IPCZ_SRC_IPCZ_REF_COUNTED_FRAGMENT_H_
-#define IPCZ_SRC_IPCZ_REF_COUNTED_FRAGMENT_H_
-
-#include <atomic>
-
-#include "ipcz/ipcz.h"
-#include "util/ref_counted.h"
-
-namespace ipcz {
-
-// A RefCountedFragment is an object allocated within a shared Fragment from
-// NodeLinkMemory, and which is automatially freed when its last reference is
-// released. Consumers can hold onto references to RefCountedFragment objects
-// by holding a FragmentRef.
-struct IPCZ_ALIGN(4) RefCountedFragment {
-  enum { kAdoptExistingRef };
-  enum { kUnmanagedRef };
-
-  RefCountedFragment();
-  ~RefCountedFragment();
-
-  int32_t ref_count_for_testing() const { return ref_count_; }
-
-  // Increments the reference count for this object.
-  void AddRef();
-
-  // Releases a reference and returns the previous reference count. If this
-  // returns 1, the underlying Fragment can be safely freed.
-  int32_t ReleaseRef();
-
- private:
-  std::atomic<int32_t> ref_count_{1};
-};
-
-}  // namespace ipcz
-
-#endif  // IPCZ_SRC_IPCZ_REF_COUNTED_FRAGMENT_H_
diff --git a/src/ipcz/ref_counted_fragment_test.cc b/src/ipcz/ref_counted_fragment_test.cc
deleted file mode 100644
index 5bb0db4..0000000
--- a/src/ipcz/ref_counted_fragment_test.cc
+++ /dev/null
@@ -1,179 +0,0 @@
-// Copyright 2022 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "ipcz/ref_counted_fragment.h"
-
-#include <atomic>
-#include <tuple>
-
-#include "ipcz/fragment.h"
-#include "ipcz/fragment_ref.h"
-#include "ipcz/node.h"
-#include "ipcz/node_link_memory.h"
-#include "reference_drivers/sync_reference_driver.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "util/ref_counted.h"
-
-namespace ipcz {
-namespace {
-
-const IpczDriver& kTestDriver = reference_drivers::kSyncReferenceDriver;
-
-using RefCountedFragmentTest = testing::Test;
-
-using TestObject = RefCountedFragment;
-
-TEST_F(RefCountedFragmentTest, NullRef) {
-  FragmentRef<TestObject> ref;
-  EXPECT_TRUE(ref.is_null());
-  EXPECT_FALSE(ref.is_addressable());
-
-  ref.reset();
-  EXPECT_TRUE(ref.is_null());
-  EXPECT_FALSE(ref.is_addressable());
-
-  FragmentRef<TestObject> other1 = ref;
-  EXPECT_TRUE(ref.is_null());
-  EXPECT_FALSE(ref.is_addressable());
-  EXPECT_TRUE(other1.is_null());
-  EXPECT_FALSE(other1.is_addressable());
-
-  FragmentRef<TestObject> other2 = std::move(ref);
-  EXPECT_TRUE(ref.is_null());
-  EXPECT_FALSE(ref.is_addressable());
-  EXPECT_TRUE(other2.is_null());
-  EXPECT_FALSE(other2.is_addressable());
-
-  ref = other1;
-  EXPECT_TRUE(ref.is_null());
-  EXPECT_FALSE(ref.is_addressable());
-  EXPECT_TRUE(other1.is_null());
-  EXPECT_FALSE(other1.is_addressable());
-
-  ref = std::move(other2);
-  EXPECT_TRUE(ref.is_null());
-  EXPECT_FALSE(ref.is_addressable());
-  EXPECT_TRUE(other1.is_null());
-  EXPECT_FALSE(other1.is_addressable());
-}
-
-TEST_F(RefCountedFragmentTest, SimpleRef) {
-  TestObject object;
-
-  FragmentRef<TestObject> ref(
-      RefCountedFragment::kUnmanagedRef,
-      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object));
-  EXPECT_EQ(1, object.ref_count_for_testing());
-  ref.reset();
-  EXPECT_EQ(0, object.ref_count_for_testing());
-}
-
-TEST_F(RefCountedFragmentTest, Copy) {
-  TestObject object1;
-
-  FragmentRef<TestObject> ref1(
-      RefCountedFragment::kUnmanagedRef,
-      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object1));
-  EXPECT_EQ(1, object1.ref_count_for_testing());
-
-  FragmentRef<TestObject> other1 = ref1;
-  EXPECT_EQ(2, object1.ref_count_for_testing());
-  other1.reset();
-  EXPECT_EQ(1, object1.ref_count_for_testing());
-  EXPECT_TRUE(other1.is_null());
-  EXPECT_FALSE(other1.is_addressable());
-
-  TestObject object2;
-  auto ref2 = FragmentRef<TestObject>(
-      RefCountedFragment::kUnmanagedRef,
-      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object2));
-  EXPECT_EQ(1, object1.ref_count_for_testing());
-  EXPECT_EQ(1, object2.ref_count_for_testing());
-  ref2 = ref1;
-  EXPECT_EQ(2, object1.ref_count_for_testing());
-  EXPECT_EQ(0, object2.ref_count_for_testing());
-  EXPECT_FALSE(ref1.is_null());
-  EXPECT_TRUE(ref1.is_addressable());
-  EXPECT_FALSE(ref2.is_null());
-  EXPECT_TRUE(ref2.is_addressable());
-  ref1.reset();
-  EXPECT_EQ(1, object1.ref_count_for_testing());
-  EXPECT_EQ(0, object2.ref_count_for_testing());
-  EXPECT_TRUE(ref1.is_null());
-  EXPECT_FALSE(ref1.is_addressable());
-  ref2.reset();
-  EXPECT_EQ(0, object1.ref_count_for_testing());
-  EXPECT_EQ(0, object2.ref_count_for_testing());
-  EXPECT_TRUE(ref2.is_null());
-  EXPECT_FALSE(ref2.is_addressable());
-}
-
-TEST_F(RefCountedFragmentTest, Move) {
-  TestObject object1;
-
-  FragmentRef<TestObject> ref1(
-      RefCountedFragment::kUnmanagedRef,
-      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object1));
-  EXPECT_EQ(1, ref1.ref_count_for_testing());
-
-  FragmentRef<TestObject> other1 = std::move(ref1);
-  EXPECT_EQ(1, object1.ref_count_for_testing());
-  EXPECT_FALSE(other1.is_null());
-  EXPECT_TRUE(other1.is_addressable());
-  EXPECT_TRUE(ref1.is_null());
-  EXPECT_FALSE(ref1.is_addressable());
-  other1.reset();
-  EXPECT_TRUE(other1.is_null());
-  EXPECT_FALSE(other1.is_addressable());
-  EXPECT_EQ(0, object1.ref_count_for_testing());
-
-  TestObject object2;
-  TestObject object3;
-  FragmentRef<TestObject> ref2(
-      RefCountedFragment::kUnmanagedRef,
-      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object2));
-  FragmentRef<TestObject> ref3(
-      RefCountedFragment::kUnmanagedRef,
-      Fragment(FragmentDescriptor(BufferId(0), 0, 0), &object3));
-
-  EXPECT_FALSE(ref2.is_null());
-  EXPECT_TRUE(ref2.is_addressable());
-  EXPECT_FALSE(ref3.is_null());
-  EXPECT_TRUE(ref3.is_addressable());
-  EXPECT_EQ(1, object2.ref_count_for_testing());
-  EXPECT_EQ(1, object3.ref_count_for_testing());
-  ref3 = std::move(ref2);
-  EXPECT_EQ(1, object2.ref_count_for_testing());
-  EXPECT_EQ(0, object3.ref_count_for_testing());
-  EXPECT_TRUE(ref2.is_null());
-  EXPECT_FALSE(ref2.is_addressable());
-  EXPECT_FALSE(ref3.is_null());
-  EXPECT_TRUE(ref3.is_addressable());
-  ref3.reset();
-  EXPECT_TRUE(ref3.is_null());
-  EXPECT_FALSE(ref3.is_addressable());
-  EXPECT_EQ(0, object2.ref_count_for_testing());
-  EXPECT_EQ(0, object3.ref_count_for_testing());
-}
-
-TEST_F(RefCountedFragmentTest, Free) {
-  auto node = MakeRefCounted<Node>(Node::Type::kNormal, kTestDriver,
-                                   IPCZ_INVALID_DRIVER_HANDLE);
-  auto memory = NodeLinkMemory::Allocate(std::move(node)).node_link_memory;
-
-  // Allocate a ton of fragments and let them be released by FragmentRef on
-  // destruction. If the fragments aren't freed properly, allocations will fail
-  // and so will the test.
-  constexpr size_t kNumAllocations = 100000;
-  for (size_t i = 0; i < kNumAllocations; ++i) {
-    Fragment fragment =
-        memory->buffer_pool().AllocateFragment(sizeof(TestObject));
-    EXPECT_TRUE(fragment.is_addressable());
-    FragmentRef<TestObject> ref(RefCountedFragment::kAdoptExistingRef, memory,
-                                fragment);
-  }
-}
-
-}  // namespace
-}  // namespace ipcz