return size;
 }
 
+/* Return the count of regcaches for (TARGET, PTID) in REGCACHES.  */
+
+static int
+regcache_count (process_stratum_target *target, ptid_t ptid)
+{
+  auto ptid_regc_map_it = regcaches.find (target);
+  if (ptid_regc_map_it != regcaches.end ())
+    {
+      auto &ptid_regc_map = ptid_regc_map_it->second;
+      auto range = ptid_regc_map.equal_range (ptid);
+
+      return std::distance (range.first, range.second);
+    }
+
+  return 0;
+};
+
 /* Wrapper around get_thread_arch_aspace_regcache that does some self checks.  */
 
 static void
   SELF_CHECK (regcache->aspace () == aspace);
 }
 
-static void
-regcaches_test ()
+/* The data that the regcaches selftests must hold onto for the duration of the
+   test.  */
+
+struct regcache_test_data
 {
-  /* Ensure the regcaches container is empty at the start.  */
-  registers_changed ();
-  SELF_CHECK (regcaches_size () == 0);
+  regcache_test_data ()
+  {
+    /* Ensure the regcaches container is empty at the start.  */
+    registers_changed ();
+  }
 
-  ptid_t ptid1 (1), ptid2 (2), ptid3 (3);
+  ~regcache_test_data ()
+  {
+    /* Make sure to leave the global regcaches container empty.  */
+    registers_changed ();
+  }
 
   test_target_ops test_target1;
   test_target_ops test_target2;
+};
+
+using regcache_test_data_up = std::unique_ptr<regcache_test_data>;
+
+/* Set up a few regcaches from two different targets, for use in
+   regcache-management tests.
+
+   Return a pointer, because the `regcache_test_data` type is not moveable.  */
+
+static regcache_test_data_up
+populate_regcaches_for_test ()
+{
+  regcache_test_data_up data (new regcache_test_data);
+  size_t expected_regcache_size = 0;
+
+  SELF_CHECK (regcaches_size () == 0);
+
+  /* Populate the regcache container with a few regcaches for the two test
+     targets. */
+  for (int pid : { 1, 2 })
+    {
+      for (long lwp : { 1, 2, 3 })
+       {
+         get_thread_arch_aspace_regcache_and_check
+           (&data->test_target1, ptid_t (pid, lwp));
+         expected_regcache_size++;
+         SELF_CHECK (regcaches_size () == expected_regcache_size);
+
+         get_thread_arch_aspace_regcache_and_check
+           (&data->test_target2, ptid_t (pid, lwp));
+         expected_regcache_size++;
+         SELF_CHECK (regcaches_size () == expected_regcache_size);
+       }
+    }
+
+  return data;
+}
+
+static void
+get_thread_arch_aspace_regcache_test ()
+{
+  /* populate_regcaches_for_test already tests most of the
+     get_thread_arch_aspace_regcache functionality.  */
+  regcache_test_data_up data = populate_regcaches_for_test ();
+  size_t regcaches_size_before = regcaches_size ();
+
+  /* Test that getting an existing regcache doesn't create a new one.  */
+  get_thread_arch_aspace_regcache_and_check (&data->test_target1, ptid_t (2, 2));
+  SELF_CHECK (regcaches_size () == regcaches_size_before);
+}
+
+  /* Test marking all regcaches of all targets as changed.  */
+
+static void
+registers_changed_ptid_all_test ()
+{
+  regcache_test_data_up data = populate_regcaches_for_test ();
 
-  /* Get regcache from (target1,ptid1), a new regcache is added to
-     REGCACHES.  */
-  get_thread_arch_aspace_regcache_and_check (&test_target1, ptid1);
-  SELF_CHECK (regcaches_size () == 1);
-
-  /* Get regcache from (target1,ptid2), a new regcache is added to
-     REGCACHES.  */
-  get_thread_arch_aspace_regcache_and_check (&test_target1, ptid2);
-  SELF_CHECK (regcaches_size () == 2);
-
-  /* Get regcache from (target1,ptid3), a new regcache is added to
-     REGCACHES.  */
-  get_thread_arch_aspace_regcache_and_check (&test_target1, ptid3);
-  SELF_CHECK (regcaches_size () == 3);
-
-  /* Get regcache from (target1,ptid2) again, nothing is added to
-     REGCACHES.  */
-  get_thread_arch_aspace_regcache_and_check (&test_target1, ptid2);
-  SELF_CHECK (regcaches_size () == 3);
-
-  /* Get regcache from (target2,ptid2), a new regcache is added to
-     REGCACHES, since this time we're using a different target.  */
-  get_thread_arch_aspace_regcache_and_check (&test_target2, ptid2);
-  SELF_CHECK (regcaches_size () == 4);
-
-  /* Mark that (target1,ptid2) changed.  The regcache of (target1,
-     ptid2) should be removed from REGCACHES.  */
-  registers_changed_ptid (&test_target1, ptid2);
-  SELF_CHECK (regcaches_size () == 3);
-
-  /* Get the regcache from (target2,ptid2) again, confirming the
-     registers_changed_ptid call above did not delete it.  */
-  get_thread_arch_aspace_regcache_and_check (&test_target2, ptid2);
-  SELF_CHECK (regcaches_size () == 3);
-
-  /* Confirm that marking all regcaches of all targets as changed
-     clears REGCACHES.  */
   registers_changed_ptid (nullptr, minus_one_ptid);
   SELF_CHECK (regcaches_size () == 0);
+}
 
-  /* Make sure to leave the global regcaches container empty.  */
-  registers_changed ();
+/* Test marking regcaches of a specific target as changed.  */
+
+static void
+registers_changed_ptid_target_test ()
+{
+  regcache_test_data_up data = populate_regcaches_for_test ();
+
+  registers_changed_ptid (&data->test_target1, minus_one_ptid);
+  SELF_CHECK (regcaches_size () == 6);
+
+  /* Check that we deleted the regcache for the right target.  */
+  SELF_CHECK (regcache_count (&data->test_target1, ptid_t (2, 2)) == 0);
+  SELF_CHECK (regcache_count (&data->test_target2, ptid_t (2, 2)) == 1);
+}
+
+/* Test marking regcaches of a specific (target, ptid) as changed.  */
+
+static void
+registers_changed_ptid_target_ptid_test ()
+{
+  regcache_test_data_up data = populate_regcaches_for_test ();
+
+  registers_changed_ptid (&data->test_target1, ptid_t (2, 2));
+  SELF_CHECK (regcaches_size () == 11);
+
+  /* Check that we deleted the regcache for the right target.  */
+  SELF_CHECK (regcache_count (&data->test_target1, ptid_t (2, 2)) == 0);
+  SELF_CHECK (regcache_count (&data->test_target2, ptid_t (2, 2)) == 1);
 }
 
 class target_ops_no_register : public test_target_ops
   get_thread_arch_aspace_regcache (&target2.mock_target, old_ptid, arch,
                                   nullptr);
 
-  /* Return the count of regcaches for (TARGET, PTID) in REGCACHES.  */
-  auto regcache_count = [] (process_stratum_target *target, ptid_t ptid)
-    -> int
-    {
-      auto ptid_regc_map_it = regcaches.find (target);
-      if (ptid_regc_map_it != regcaches.end ())
-       {
-         auto &ptid_regc_map = ptid_regc_map_it->second;
-         auto range = ptid_regc_map.equal_range (ptid);
-         return std::distance (range.first, range.second);
-       }
-      return 0;
-    };
-
   gdb_assert (regcaches.size () == 2);
   gdb_assert (regcache_count (&target1.mock_target, old_ptid) == 1);
   gdb_assert (regcache_count (&target1.mock_target, new_ptid) == 0);
           _("Force gdb to flush its register cache (maintainer command)."));
 
 #if GDB_SELF_TEST
-  selftests::register_test ("regcaches", selftests::regcaches_test);
+  selftests::register_test ("get_thread_arch_aspace_regcache",
+                           selftests::get_thread_arch_aspace_regcache_test);
+  selftests::register_test ("registers_changed_ptid_all",
+                           selftests::registers_changed_ptid_all_test);
+  selftests::register_test ("registers_changed_ptid_target_ptid",
+                           selftests::registers_changed_ptid_target_ptid_test);
+  selftests::register_test ("registers_changed_ptid_target",
+                           selftests::registers_changed_ptid_target_test);
 
   selftests::register_test_foreach_arch ("regcache::cooked_read_test",
                                         selftests::cooked_read_test);