Split space_test into separate checks

Split space_test by space type: dlmalloc, rosalloc and large object space to facilitate parallelized testing.

Bug: 13117676
Change-Id: I152dc03717c26dfcf14e93ba2b39f83612a5f560
diff --git a/build/Android.gtest.mk b/build/Android.gtest.mk
index 3295d86..541b8d3 100644
--- a/build/Android.gtest.mk
+++ b/build/Android.gtest.mk
@@ -49,7 +49,9 @@
 	runtime/exception_test.cc \
 	runtime/gc/accounting/space_bitmap_test.cc \
 	runtime/gc/heap_test.cc \
-	runtime/gc/space/space_test.cc \
+	runtime/gc/space/dlmalloc_space_test.cc \
+	runtime/gc/space/rosalloc_space_test.cc \
+	runtime/gc/space/large_object_space_test.cc \
 	runtime/gtest_test.cc \
 	runtime/indenter_test.cc \
 	runtime/indirect_reference_table_test.cc \
diff --git a/runtime/gc/space/dlmalloc_space_test.cc b/runtime/gc/space/dlmalloc_space_test.cc
new file mode 100644
index 0000000..964c31b
--- /dev/null
+++ b/runtime/gc/space/dlmalloc_space_test.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "space_test.h"
+#include "dlmalloc_space.h"
+
+namespace art {
+namespace gc {
+namespace space {
+
+MallocSpace* CreateDlMallocSpace(const std::string& name, size_t initial_size, size_t growth_limit,
+                                 size_t capacity, byte* requested_begin) {
+  return DlMallocSpace::Create(name, initial_size, growth_limit, capacity, requested_begin);
+}
+
+TEST_SPACE_CREATE_FN(DlMallocSpace, CreateDlMallocSpace)
+
+
+}  // namespace space
+}  // namespace gc
+}  // namespace art
diff --git a/runtime/gc/space/large_object_space_test.cc b/runtime/gc/space/large_object_space_test.cc
new file mode 100644
index 0000000..845b9e3
--- /dev/null
+++ b/runtime/gc/space/large_object_space_test.cc
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "space_test.h"
+#include "large_object_space.h"
+
+namespace art {
+namespace gc {
+namespace space {
+
+class LargeObjectSpaceTest : public SpaceTest {
+ public:
+  void LargeObjectTest();
+};
+
+
+void LargeObjectSpaceTest::LargeObjectTest() {
+  size_t rand_seed = 0;
+  for (size_t i = 0; i < 2; ++i) {
+    LargeObjectSpace* los = nullptr;
+    if (i == 0) {
+      los = space::LargeObjectMapSpace::Create("large object space");
+    } else {
+      los = space::FreeListSpace::Create("large object space", nullptr, 128 * MB);
+    }
+
+    static const size_t num_allocations = 64;
+    static const size_t max_allocation_size = 0x100000;
+    std::vector<std::pair<mirror::Object*, size_t> > requests;
+
+    for (size_t phase = 0; phase < 2; ++phase) {
+      while (requests.size() < num_allocations) {
+        size_t request_size = test_rand(&rand_seed) % max_allocation_size;
+        size_t allocation_size = 0;
+        mirror::Object* obj = los->Alloc(Thread::Current(), request_size, &allocation_size);
+        ASSERT_TRUE(obj != nullptr);
+        ASSERT_EQ(allocation_size, los->AllocationSize(obj));
+        ASSERT_GE(allocation_size, request_size);
+        // Fill in our magic value.
+        byte magic = (request_size & 0xFF) | 1;
+        memset(obj, magic, request_size);
+        requests.push_back(std::make_pair(obj, request_size));
+      }
+
+      // "Randomly" shuffle the requests.
+      for (size_t k = 0; k < 10; ++k) {
+        for (size_t j = 0; j < requests.size(); ++j) {
+          std::swap(requests[j], requests[test_rand(&rand_seed) % requests.size()]);
+        }
+      }
+
+      // Free 1 / 2 the allocations the first phase, and all the second phase.
+      size_t limit = !phase ? requests.size() / 2 : 0;
+      while (requests.size() > limit) {
+        mirror::Object* obj = requests.back().first;
+        size_t request_size = requests.back().second;
+        requests.pop_back();
+        byte magic = (request_size & 0xFF) | 1;
+        for (size_t k = 0; k < request_size; ++k) {
+          ASSERT_EQ(reinterpret_cast<const byte*>(obj)[k], magic);
+        }
+        ASSERT_GE(los->Free(Thread::Current(), obj), request_size);
+      }
+    }
+
+    size_t bytes_allocated = 0;
+    // Checks that the coalescing works.
+    mirror::Object* obj = los->Alloc(Thread::Current(), 100 * MB, &bytes_allocated);
+    EXPECT_TRUE(obj != nullptr);
+    los->Free(Thread::Current(), obj);
+
+    EXPECT_EQ(0U, los->GetBytesAllocated());
+    EXPECT_EQ(0U, los->GetObjectsAllocated());
+    delete los;
+  }
+}
+
+
+TEST_F(LargeObjectSpaceTest, LargeObjectTest) {
+  LargeObjectTest();
+}
+
+}  // namespace space
+}  // namespace gc
+}  // namespace art
diff --git a/runtime/gc/space/rosalloc_space_test.cc b/runtime/gc/space/rosalloc_space_test.cc
new file mode 100644
index 0000000..3eac795
--- /dev/null
+++ b/runtime/gc/space/rosalloc_space_test.cc
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "space_test.h"
+
+namespace art {
+namespace gc {
+namespace space {
+
+MallocSpace* CreateRosAllocSpace(const std::string& name, size_t initial_size, size_t growth_limit,
+                                 size_t capacity, byte* requested_begin) {
+  return RosAllocSpace::Create(name, initial_size, growth_limit, capacity, requested_begin,
+                               Runtime::Current()->GetHeap()->IsLowMemoryMode());
+}
+
+TEST_SPACE_CREATE_FN(RosAllocSpace, CreateRosAllocSpace)
+
+
+}  // namespace space
+}  // namespace gc
+}  // namespace art
diff --git a/runtime/gc/space/space_test.cc b/runtime/gc/space/space_test.h
similarity index 77%
rename from runtime/gc/space/space_test.cc
rename to runtime/gc/space/space_test.h
index 0b9f7ad..d01bf2c 100644
--- a/runtime/gc/space/space_test.cc
+++ b/runtime/gc/space/space_test.h
@@ -14,8 +14,9 @@
  * limitations under the License.
  */
 
-#include "dlmalloc_space.h"
-#include "large_object_space.h"
+#ifndef ART_RUNTIME_GC_SPACE_SPACE_TEST_H_
+#define ART_RUNTIME_GC_SPACE_SPACE_TEST_H_
+
 #include "zygote_space.h"
 
 #include "common_test.h"
@@ -58,16 +59,6 @@
     return mirror::Array::DataOffset(Primitive::ComponentSize(Primitive::kPrimByte)).Uint32Value();
   }
 
-  static MallocSpace* CreateDlMallocSpace(const std::string& name, size_t initial_size, size_t growth_limit,
-                                          size_t capacity, byte* requested_begin) {
-    return DlMallocSpace::Create(name, initial_size, growth_limit, capacity, requested_begin);
-  }
-  static MallocSpace* CreateRosAllocSpace(const std::string& name, size_t initial_size, size_t growth_limit,
-                                          size_t capacity, byte* requested_begin) {
-    return RosAllocSpace::Create(name, initial_size, growth_limit, capacity, requested_begin,
-                                 Runtime::Current()->GetHeap()->IsLowMemoryMode());
-  }
-
   typedef MallocSpace* (*CreateSpaceFn)(const std::string& name, size_t initial_size, size_t growth_limit,
                                         size_t capacity, byte* requested_begin);
   void InitTestBody(CreateSpaceFn create_space);
@@ -123,13 +114,6 @@
   }
 }
 
-TEST_F(SpaceTest, Init_DlMallocSpace) {
-  InitTestBody(SpaceTest::CreateDlMallocSpace);
-}
-TEST_F(SpaceTest, Init_RosAllocSpace) {
-  InitTestBody(SpaceTest::CreateRosAllocSpace);
-}
-
 // TODO: This test is not very good, we should improve it.
 // The test should do more allocations before the creation of the ZygoteSpace, and then do
 // allocations after the ZygoteSpace is created. The test should also do some GCs to ensure that
@@ -221,14 +205,6 @@
   EXPECT_LE(1U * MB, free1);
 }
 
-TEST_F(SpaceTest, ZygoteSpace_DlMallocSpace) {
-  ZygoteSpaceTestBody(SpaceTest::CreateDlMallocSpace);
-}
-
-TEST_F(SpaceTest, ZygoteSpace_RosAllocSpace) {
-  ZygoteSpaceTestBody(SpaceTest::CreateRosAllocSpace);
-}
-
 void SpaceTest::AllocAndFreeTestBody(CreateSpaceFn create_space) {
   size_t dummy = 0;
   MallocSpace* space(create_space("test", 4 * MB, 16 * MB, 16 * MB, nullptr));
@@ -280,74 +256,6 @@
   EXPECT_LE(1U * MB, free1);
 }
 
-TEST_F(SpaceTest, AllocAndFree_DlMallocSpace) {
-  AllocAndFreeTestBody(SpaceTest::CreateDlMallocSpace);
-}
-TEST_F(SpaceTest, AllocAndFree_RosAllocSpace) {
-  AllocAndFreeTestBody(SpaceTest::CreateRosAllocSpace);
-}
-
-TEST_F(SpaceTest, LargeObjectTest) {
-  size_t rand_seed = 0;
-  for (size_t i = 0; i < 2; ++i) {
-    LargeObjectSpace* los = nullptr;
-    if (i == 0) {
-      los = space::LargeObjectMapSpace::Create("large object space");
-    } else {
-      los = space::FreeListSpace::Create("large object space", nullptr, 128 * MB);
-    }
-
-    static const size_t num_allocations = 64;
-    static const size_t max_allocation_size = 0x100000;
-    std::vector<std::pair<mirror::Object*, size_t> > requests;
-
-    for (size_t phase = 0; phase < 2; ++phase) {
-      while (requests.size() < num_allocations) {
-        size_t request_size = test_rand(&rand_seed) % max_allocation_size;
-        size_t allocation_size = 0;
-        mirror::Object* obj = los->Alloc(Thread::Current(), request_size, &allocation_size);
-        ASSERT_TRUE(obj != nullptr);
-        ASSERT_EQ(allocation_size, los->AllocationSize(obj));
-        ASSERT_GE(allocation_size, request_size);
-        // Fill in our magic value.
-        byte magic = (request_size & 0xFF) | 1;
-        memset(obj, magic, request_size);
-        requests.push_back(std::make_pair(obj, request_size));
-      }
-
-      // "Randomly" shuffle the requests.
-      for (size_t k = 0; k < 10; ++k) {
-        for (size_t j = 0; j < requests.size(); ++j) {
-          std::swap(requests[j], requests[test_rand(&rand_seed) % requests.size()]);
-        }
-      }
-
-      // Free 1 / 2 the allocations the first phase, and all the second phase.
-      size_t limit = !phase ? requests.size() / 2 : 0;
-      while (requests.size() > limit) {
-        mirror::Object* obj = requests.back().first;
-        size_t request_size = requests.back().second;
-        requests.pop_back();
-        byte magic = (request_size & 0xFF) | 1;
-        for (size_t k = 0; k < request_size; ++k) {
-          ASSERT_EQ(reinterpret_cast<const byte*>(obj)[k], magic);
-        }
-        ASSERT_GE(los->Free(Thread::Current(), obj), request_size);
-      }
-    }
-
-    size_t bytes_allocated = 0;
-    // Checks that the coalescing works.
-    mirror::Object* obj = los->Alloc(Thread::Current(), 100 * MB, &bytes_allocated);
-    EXPECT_TRUE(obj != nullptr);
-    los->Free(Thread::Current(), obj);
-
-    EXPECT_EQ(0U, los->GetBytesAllocated());
-    EXPECT_EQ(0U, los->GetObjectsAllocated());
-    delete los;
-  }
-}
-
 void SpaceTest::AllocAndFreeListTestBody(CreateSpaceFn create_space) {
   MallocSpace* space(create_space("test", 4 * MB, 16 * MB, 16 * MB, nullptr));
   ASSERT_TRUE(space != nullptr);
@@ -395,13 +303,6 @@
   }
 }
 
-TEST_F(SpaceTest, AllocAndFreeList_DlMallocSpace) {
-  AllocAndFreeListTestBody(SpaceTest::CreateDlMallocSpace);
-}
-TEST_F(SpaceTest, AllocAndFreeList_RosAllocSpace) {
-  AllocAndFreeListTestBody(SpaceTest::CreateRosAllocSpace);
-}
-
 void SpaceTest::SizeFootPrintGrowthLimitAndTrimBody(MallocSpace* space, intptr_t object_size,
                                                     int round, size_t growth_limit) {
   if (((object_size > 0 && object_size >= static_cast<intptr_t>(growth_limit))) ||
@@ -596,38 +497,46 @@
   SizeFootPrintGrowthLimitAndTrimBody(space, object_size, 3, capacity);
 }
 
-#define TEST_SizeFootPrintGrowthLimitAndTrim(name, size) \
-  TEST_F(SpaceTest, SizeFootPrintGrowthLimitAndTrim_AllocationsOf_##name##_DlMallocSpace) { \
-    SizeFootPrintGrowthLimitAndTrimDriver(size, SpaceTest::CreateDlMallocSpace); \
+#define TEST_SizeFootPrintGrowthLimitAndTrim(name, spaceName, spaceFn, size) \
+  TEST_F(spaceName##Test, SizeFootPrintGrowthLimitAndTrim_AllocationsOf_##name) { \
+    SizeFootPrintGrowthLimitAndTrimDriver(size, spaceFn); \
   } \
-  TEST_F(SpaceTest, SizeFootPrintGrowthLimitAndTrim_RandomAllocationsWithMax_##name##_DlMallocSpace) { \
-    SizeFootPrintGrowthLimitAndTrimDriver(-size, SpaceTest::CreateDlMallocSpace); \
-  } \
-  TEST_F(SpaceTest, SizeFootPrintGrowthLimitAndTrim_AllocationsOf_##name##_RosAllocSpace) { \
-    SizeFootPrintGrowthLimitAndTrimDriver(size, SpaceTest::CreateRosAllocSpace); \
-  } \
-  TEST_F(SpaceTest, SizeFootPrintGrowthLimitAndTrim_RandomAllocationsWithMax_##name##_RosAllocSpace) { \
-    SizeFootPrintGrowthLimitAndTrimDriver(-size, SpaceTest::CreateRosAllocSpace); \
+  TEST_F(spaceName##Test, SizeFootPrintGrowthLimitAndTrim_RandomAllocationsWithMax_##name) { \
+    SizeFootPrintGrowthLimitAndTrimDriver(-size, spaceFn); \
   }
 
-// Each size test is its own test so that we get a fresh heap each time
-TEST_F(SpaceTest, SizeFootPrintGrowthLimitAndTrim_AllocationsOf_12B_DlMallocSpace) {
-  SizeFootPrintGrowthLimitAndTrimDriver(12, SpaceTest::CreateDlMallocSpace);
-}
-TEST_F(SpaceTest, SizeFootPrintGrowthLimitAndTrim_AllocationsOf_12B_RosAllocSpace) {
-  SizeFootPrintGrowthLimitAndTrimDriver(12, SpaceTest::CreateRosAllocSpace);
-}
-TEST_SizeFootPrintGrowthLimitAndTrim(16B, 16)
-TEST_SizeFootPrintGrowthLimitAndTrim(24B, 24)
-TEST_SizeFootPrintGrowthLimitAndTrim(32B, 32)
-TEST_SizeFootPrintGrowthLimitAndTrim(64B, 64)
-TEST_SizeFootPrintGrowthLimitAndTrim(128B, 128)
-TEST_SizeFootPrintGrowthLimitAndTrim(1KB, 1 * KB)
-TEST_SizeFootPrintGrowthLimitAndTrim(4KB, 4 * KB)
-TEST_SizeFootPrintGrowthLimitAndTrim(1MB, 1 * MB)
-TEST_SizeFootPrintGrowthLimitAndTrim(4MB, 4 * MB)
-TEST_SizeFootPrintGrowthLimitAndTrim(8MB, 8 * MB)
+#define TEST_SPACE_CREATE_FN(spaceName, spaceFn) \
+  class spaceName##Test : public SpaceTest { \
+  }; \
+  \
+  TEST_F(spaceName##Test, Init) { \
+    InitTestBody(spaceFn); \
+  } \
+  TEST_F(spaceName##Test, ZygoteSpace) { \
+    ZygoteSpaceTestBody(spaceFn); \
+  } \
+  TEST_F(spaceName##Test, AllocAndFree) { \
+    AllocAndFreeTestBody(spaceFn); \
+  } \
+  TEST_F(spaceName##Test, AllocAndFreeList) { \
+    AllocAndFreeListTestBody(spaceFn); \
+  } \
+  TEST_F(spaceName##Test, SizeFootPrintGrowthLimitAndTrim_AllocationsOf_12B) { \
+    SizeFootPrintGrowthLimitAndTrimDriver(12, spaceFn); \
+  } \
+  TEST_SizeFootPrintGrowthLimitAndTrim(16B, spaceName, spaceFn, 16) \
+  TEST_SizeFootPrintGrowthLimitAndTrim(24B, spaceName, spaceFn, 24) \
+  TEST_SizeFootPrintGrowthLimitAndTrim(32B, spaceName, spaceFn, 32) \
+  TEST_SizeFootPrintGrowthLimitAndTrim(64B, spaceName, spaceFn, 64) \
+  TEST_SizeFootPrintGrowthLimitAndTrim(128B, spaceName, spaceFn, 128) \
+  TEST_SizeFootPrintGrowthLimitAndTrim(1KB, spaceName, spaceFn, 1 * KB) \
+  TEST_SizeFootPrintGrowthLimitAndTrim(4KB, spaceName, spaceFn, 4 * KB) \
+  TEST_SizeFootPrintGrowthLimitAndTrim(1MB, spaceName, spaceFn, 1 * MB) \
+  TEST_SizeFootPrintGrowthLimitAndTrim(4MB, spaceName, spaceFn, 4 * MB) \
+  TEST_SizeFootPrintGrowthLimitAndTrim(8MB, spaceName, spaceFn, 8 * MB)
 
 }  // namespace space
 }  // namespace gc
 }  // namespace art
+
+#endif  // ART_RUNTIME_GC_SPACE_SPACE_TEST_H_