test/hotspot/gtest/gc/shared/test_oopStorage.cpp
changeset 49977 9f758f0bb058
parent 49711 4a7addb5762c
child 50209 2fdce199fcb9
equal deleted inserted replaced
49976:19829b375d08 49977:9f758f0bb058
    51 // Access storage internals.
    51 // Access storage internals.
    52 class OopStorage::TestAccess : public AllStatic {
    52 class OopStorage::TestAccess : public AllStatic {
    53 public:
    53 public:
    54   typedef OopStorage::Block Block;
    54   typedef OopStorage::Block Block;
    55   typedef OopStorage::BlockList BlockList;
    55   typedef OopStorage::BlockList BlockList;
    56 
    56   typedef OopStorage::BlockArray BlockArray;
    57   static BlockList& active_list(OopStorage& storage) {
    57 
    58     return storage._active_list;
    58   static BlockArray& active_array(const OopStorage& storage) {
       
    59     return *storage._active_array;
    59   }
    60   }
    60 
    61 
    61   static BlockList& allocate_list(OopStorage& storage) {
    62   static BlockList& allocate_list(OopStorage& storage) {
    62     return storage._allocate_list;
    63     return storage._allocate_list;
    63   }
    64   }
    94   }
    95   }
    95 
    96 
    96   static size_t memory_per_block() {
    97   static size_t memory_per_block() {
    97     return Block::allocation_size();
    98     return Block::allocation_size();
    98   }
    99   }
       
   100 
       
   101   static void block_array_set_block_count(BlockArray* blocks, size_t count) {
       
   102     blocks->_block_count = count;
       
   103   }
    99 };
   104 };
   100 
   105 
   101 typedef OopStorage::TestAccess TestAccess;
   106 typedef OopStorage::TestAccess TestAccess;
   102 // --- FIXME: Should be just Block, but that collides with opto Block
   107 
   103 //     when building with precompiled headers.  There really should be
   108 // The "Oop" prefix is to avoid collision with similar opto names when
   104 //     an opto namespace.
   109 // building with precompiled headers, or for consistency with that
       
   110 // workaround.  There really should be an opto namespace.
   105 typedef TestAccess::Block OopBlock;
   111 typedef TestAccess::Block OopBlock;
   106 // --- FIXME: Similarly, this typedef collides with opto BlockList.
   112 typedef TestAccess::BlockList OopBlockList;
   107 // typedef TestAccess::BlockList BlockList;
   113 typedef TestAccess::BlockArray OopBlockArray;
   108 
   114 
   109 // Using EXPECT_EQ can't use NULL directly. Otherwise AIX build breaks.
   115 // Using EXPECT_EQ can't use NULL directly. Otherwise AIX build breaks.
   110 const OopBlock* const NULL_BLOCK = NULL;
   116 const OopBlock* const NULL_BLOCK = NULL;
   111 
   117 
   112 static size_t list_length(const TestAccess::BlockList& list) {
   118 static size_t list_length(const OopBlockList& list) {
   113   size_t result = 0;
   119   size_t result = 0;
   114   for (const OopBlock* block = list.chead();
   120   for (const OopBlock* block = list.chead();
   115        block != NULL;
   121        block != NULL;
   116        block = list.next(*block)) {
   122        block = list.next(*block)) {
   117     ++result;
   123     ++result;
   118   }
   124   }
   119   return result;
   125   return result;
   120 }
   126 }
   121 
   127 
   122 static void clear_list(TestAccess::BlockList& list) {
   128 static void clear_list(OopBlockList& list) {
   123   OopBlock* next;
   129   OopBlock* next;
   124   for (OopBlock* block = list.head(); block != NULL; block = next) {
   130   for (OopBlock* block = list.head(); block != NULL; block = next) {
   125     next = list.next(*block);
   131     next = list.next(*block);
   126     list.unlink(*block);
   132     list.unlink(*block);
   127   }
   133   }
   128 }
   134 }
   129 
   135 
   130 static bool is_list_empty(const TestAccess::BlockList& list) {
   136 static bool is_list_empty(const OopBlockList& list) {
   131   return list.chead() == NULL;
   137   return list.chead() == NULL;
   132 }
   138 }
   133 
   139 
   134 static bool process_deferred_updates(OopStorage& storage) {
   140 static bool process_deferred_updates(OopStorage& storage) {
   135   MutexLockerEx ml(TestAccess::allocate_mutex(storage), Mutex::_no_safepoint_check_flag);
   141   MutexLockerEx ml(TestAccess::allocate_mutex(storage), Mutex::_no_safepoint_check_flag);
   147     process_deferred_updates(storage);
   153     process_deferred_updates(storage);
   148   }
   154   }
   149 }
   155 }
   150 
   156 
   151 static size_t empty_block_count(const OopStorage& storage) {
   157 static size_t empty_block_count(const OopStorage& storage) {
   152   const TestAccess::BlockList& list = TestAccess::allocate_list(storage);
   158   const OopBlockList& list = TestAccess::allocate_list(storage);
   153   size_t count = 0;
   159   size_t count = 0;
   154   for (const OopBlock* block = list.ctail();
   160   for (const OopBlock* block = list.ctail();
   155        (block != NULL) && block->is_empty();
   161        (block != NULL) && block->is_empty();
   156        ++count, block = list.prev(*block))
   162        ++count, block = list.prev(*block))
   157   {}
   163   {}
   158   return count;
   164   return count;
       
   165 }
       
   166 
       
   167 static size_t active_count(const OopStorage& storage) {
       
   168   return TestAccess::active_array(storage).block_count();
       
   169 }
       
   170 
       
   171 static OopBlock* active_head(const OopStorage& storage) {
       
   172   OopBlockArray& ba = TestAccess::active_array(storage);
       
   173   size_t count = ba.block_count();
       
   174   if (count == 0) {
       
   175     return NULL;
       
   176   } else {
       
   177     return ba.at(count - 1);
       
   178   }
   159 }
   179 }
   160 
   180 
   161 class OopStorageTest : public ::testing::Test {
   181 class OopStorageTest : public ::testing::Test {
   162 public:
   182 public:
   163   OopStorageTest();
   183   OopStorageTest();
   186   _storage("Test Storage", &_allocate_mutex, &_active_mutex)
   206   _storage("Test Storage", &_allocate_mutex, &_active_mutex)
   187 { }
   207 { }
   188 
   208 
   189 OopStorageTest::~OopStorageTest() {
   209 OopStorageTest::~OopStorageTest() {
   190   clear_list(TestAccess::allocate_list(_storage));
   210   clear_list(TestAccess::allocate_list(_storage));
   191   clear_list(TestAccess::active_list(_storage));
       
   192 }
   211 }
   193 
   212 
   194 class OopStorageTestWithAllocation : public OopStorageTest {
   213 class OopStorageTestWithAllocation : public OopStorageTest {
   195 public:
   214 public:
   196   OopStorageTestWithAllocation();
   215   OopStorageTestWithAllocation();
   225 };
   244 };
   226 
   245 
   227 static bool is_allocate_list_sorted(const OopStorage& storage) {
   246 static bool is_allocate_list_sorted(const OopStorage& storage) {
   228   // The allocate_list isn't strictly sorted.  Rather, all empty
   247   // The allocate_list isn't strictly sorted.  Rather, all empty
   229   // blocks are segregated to the end of the list.
   248   // blocks are segregated to the end of the list.
   230   const TestAccess::BlockList& list = TestAccess::allocate_list(storage);
   249   const OopBlockList& list = TestAccess::allocate_list(storage);
   231   const OopBlock* block = list.ctail();
   250   const OopBlock* block = list.ctail();
   232   for ( ; (block != NULL) && block->is_empty(); block = list.prev(*block)) {}
   251   for ( ; (block != NULL) && block->is_empty(); block = list.prev(*block)) {}
   233   for ( ; block != NULL; block = list.prev(*block)) {
   252   for ( ; block != NULL; block = list.prev(*block)) {
   234     if (block->is_empty()) {
   253     if (block->is_empty()) {
   235       return false;
   254       return false;
   236     }
   255     }
   237   }
   256   }
   238   return true;
   257   return true;
   239 }
   258 }
   240 
   259 
   241 static size_t total_allocation_count(const TestAccess::BlockList& list) {
   260 static size_t total_allocation_count(const OopStorage& storage) {
   242   size_t total_count = 0;
   261   size_t total_count = 0;
   243   for (const OopBlock* block = list.chead();
   262   const OopBlockArray& ba = TestAccess::active_array(storage);
   244        block != NULL;
   263   size_t limit = active_count(storage);
   245        block = list.next(*block)) {
   264   for (size_t i = 0; i < limit; ++i) {
   246     total_count += TestAccess::block_allocation_count(*block);
   265     total_count += TestAccess::block_allocation_count(*ba.at(i));
   247   }
   266   }
   248   return total_count;
   267   return total_count;
   249 }
   268 }
   250 
   269 
   251 TEST_VM_F(OopStorageTest, allocate_one) {
   270 TEST_VM_F(OopStorageTest, allocate_one) {
   252   EXPECT_TRUE(is_list_empty(TestAccess::active_list(_storage)));
   271   EXPECT_EQ(0u, active_count(_storage));
   253   EXPECT_TRUE(is_list_empty(TestAccess::allocate_list(_storage)));
   272   EXPECT_TRUE(is_list_empty(TestAccess::allocate_list(_storage)));
   254 
   273 
   255   oop* ptr = _storage.allocate();
   274   oop* ptr = _storage.allocate();
   256   EXPECT_TRUE(ptr != NULL);
   275   EXPECT_TRUE(ptr != NULL);
   257   EXPECT_EQ(1u, _storage.allocation_count());
   276   EXPECT_EQ(1u, _storage.allocation_count());
   258 
   277 
   259   EXPECT_EQ(1u, list_length(TestAccess::active_list(_storage)));
   278   EXPECT_EQ(1u, active_count(_storage));
   260   EXPECT_EQ(1u, _storage.block_count());
   279   EXPECT_EQ(1u, _storage.block_count());
   261   EXPECT_EQ(1u, list_length(TestAccess::allocate_list(_storage)));
   280   EXPECT_EQ(1u, list_length(TestAccess::allocate_list(_storage)));
   262 
   281 
   263   EXPECT_EQ(0u, empty_block_count(_storage));
   282   EXPECT_EQ(0u, empty_block_count(_storage));
   264 
   283 
   265   const OopBlock* block = TestAccess::allocate_list(_storage).chead();
   284   const OopBlock* block = TestAccess::allocate_list(_storage).chead();
   266   EXPECT_NE(block, (OopBlock*)NULL);
   285   EXPECT_NE(block, (OopBlock*)NULL);
   267   EXPECT_EQ(block, (TestAccess::active_list(_storage).chead()));
   286   EXPECT_EQ(block, active_head(_storage));
   268   EXPECT_FALSE(TestAccess::block_is_empty(*block));
   287   EXPECT_FALSE(TestAccess::block_is_empty(*block));
   269   EXPECT_FALSE(TestAccess::block_is_full(*block));
   288   EXPECT_FALSE(TestAccess::block_is_full(*block));
   270   EXPECT_EQ(1u, TestAccess::block_allocation_count(*block));
   289   EXPECT_EQ(1u, TestAccess::block_allocation_count(*block));
   271 
   290 
   272   release_entry(_storage, ptr);
   291   release_entry(_storage, ptr);
   273   EXPECT_EQ(0u, _storage.allocation_count());
   292   EXPECT_EQ(0u, _storage.allocation_count());
   274 
   293 
   275   EXPECT_EQ(1u, list_length(TestAccess::active_list(_storage)));
   294   EXPECT_EQ(1u, active_count(_storage));
   276   EXPECT_EQ(1u, _storage.block_count());
   295   EXPECT_EQ(1u, _storage.block_count());
   277   EXPECT_EQ(1u, list_length(TestAccess::allocate_list(_storage)));
   296   EXPECT_EQ(1u, list_length(TestAccess::allocate_list(_storage)));
   278 
   297 
   279   EXPECT_EQ(1u, empty_block_count(_storage));
   298   EXPECT_EQ(1u, empty_block_count(_storage));
   280 
   299 
   281   const OopBlock* new_block = TestAccess::allocate_list(_storage).chead();
   300   const OopBlock* new_block = TestAccess::allocate_list(_storage).chead();
   282   EXPECT_EQ(block, new_block);
   301   EXPECT_EQ(block, new_block);
   283   EXPECT_EQ(block, (TestAccess::active_list(_storage).chead()));
   302   EXPECT_EQ(block, active_head(_storage));
   284   EXPECT_TRUE(TestAccess::block_is_empty(*block));
   303   EXPECT_TRUE(TestAccess::block_is_empty(*block));
   285   EXPECT_FALSE(TestAccess::block_is_full(*block));
   304   EXPECT_FALSE(TestAccess::block_is_full(*block));
   286   EXPECT_EQ(0u, TestAccess::block_allocation_count(*block));
   305   EXPECT_EQ(0u, TestAccess::block_allocation_count(*block));
   287 }
   306 }
   288 
   307 
   289 TEST_VM_F(OopStorageTest, allocation_count) {
   308 TEST_VM_F(OopStorageTest, allocation_count) {
   290   static const size_t max_entries = 1000;
   309   static const size_t max_entries = 1000;
   291   oop* entries[max_entries];
   310   oop* entries[max_entries];
   292 
   311 
   293   TestAccess::BlockList& active_list = TestAccess::active_list(_storage);
   312   OopBlockList& allocate_list = TestAccess::allocate_list(_storage);
   294   TestAccess::BlockList& allocate_list = TestAccess::allocate_list(_storage);
   313 
   295 
   314   EXPECT_EQ(0u, active_count(_storage));
   296   EXPECT_TRUE(is_list_empty(active_list));
       
   297   EXPECT_EQ(0u, _storage.block_count());
   315   EXPECT_EQ(0u, _storage.block_count());
   298   EXPECT_TRUE(is_list_empty(allocate_list));
   316   EXPECT_TRUE(is_list_empty(allocate_list));
   299 
   317 
   300   size_t allocated = 0;
   318   size_t allocated = 0;
   301   for ( ; allocated < max_entries; ++allocated) {
   319   for ( ; allocated < max_entries; ++allocated) {
   302     EXPECT_EQ(allocated, _storage.allocation_count());
   320     EXPECT_EQ(allocated, _storage.allocation_count());
   303     if (!is_list_empty(active_list)) {
   321     if (active_count(_storage) != 0) {
   304       EXPECT_EQ(1u, list_length(active_list));
   322       EXPECT_EQ(1u, active_count(_storage));
   305       EXPECT_EQ(1u, _storage.block_count());
   323       EXPECT_EQ(1u, _storage.block_count());
   306       const OopBlock& block = *active_list.chead();
   324       const OopBlock& block = *TestAccess::active_array(_storage).at(0);
   307       EXPECT_EQ(allocated, TestAccess::block_allocation_count(block));
   325       EXPECT_EQ(allocated, TestAccess::block_allocation_count(block));
   308       if (TestAccess::block_is_full(block)) {
   326       if (TestAccess::block_is_full(block)) {
   309         break;
   327         break;
   310       } else {
   328       } else {
   311         EXPECT_FALSE(is_list_empty(allocate_list));
   329         EXPECT_FALSE(is_list_empty(allocate_list));
   314     }
   332     }
   315     entries[allocated] = _storage.allocate();
   333     entries[allocated] = _storage.allocate();
   316   }
   334   }
   317 
   335 
   318   EXPECT_EQ(allocated, _storage.allocation_count());
   336   EXPECT_EQ(allocated, _storage.allocation_count());
   319   EXPECT_EQ(1u, list_length(active_list));
   337   EXPECT_EQ(1u, active_count(_storage));
   320   EXPECT_EQ(1u, _storage.block_count());
   338   EXPECT_EQ(1u, _storage.block_count());
   321   EXPECT_TRUE(is_list_empty(allocate_list));
   339   EXPECT_TRUE(is_list_empty(allocate_list));
   322   const OopBlock& block = *active_list.chead();
   340   const OopBlock& block = *TestAccess::active_array(_storage).at(0);
   323   EXPECT_TRUE(TestAccess::block_is_full(block));
   341   EXPECT_TRUE(TestAccess::block_is_full(block));
   324   EXPECT_EQ(allocated, TestAccess::block_allocation_count(block));
   342   EXPECT_EQ(allocated, TestAccess::block_allocation_count(block));
   325 
   343 
   326   for (size_t i = 0; i < allocated; ++i) {
   344   for (size_t i = 0; i < allocated; ++i) {
   327     release_entry(_storage, entries[i]);
   345     release_entry(_storage, entries[i]);
   334 
   352 
   335 TEST_VM_F(OopStorageTest, allocate_many) {
   353 TEST_VM_F(OopStorageTest, allocate_many) {
   336   static const size_t max_entries = 1000;
   354   static const size_t max_entries = 1000;
   337   oop* entries[max_entries];
   355   oop* entries[max_entries];
   338 
   356 
   339   TestAccess::BlockList& active_list = TestAccess::active_list(_storage);
   357   OopBlockList& allocate_list = TestAccess::allocate_list(_storage);
   340   TestAccess::BlockList& allocate_list = TestAccess::allocate_list(_storage);
       
   341 
   358 
   342   EXPECT_EQ(0u, empty_block_count(_storage));
   359   EXPECT_EQ(0u, empty_block_count(_storage));
   343 
   360 
   344   entries[0] = _storage.allocate();
   361   entries[0] = _storage.allocate();
   345   ASSERT_TRUE(entries[0] != NULL);
   362   ASSERT_TRUE(entries[0] != NULL);
   346   EXPECT_EQ(1u, list_length(active_list));
   363   EXPECT_EQ(1u, active_count(_storage));
   347   EXPECT_EQ(1u, _storage.block_count());
   364   EXPECT_EQ(1u, _storage.block_count());
   348   EXPECT_EQ(1u, list_length(allocate_list));
   365   EXPECT_EQ(1u, list_length(allocate_list));
   349   EXPECT_EQ(0u, empty_block_count(_storage));
   366   EXPECT_EQ(0u, empty_block_count(_storage));
   350 
   367 
   351   const OopBlock* block = active_list.chead();
   368   const OopBlock* block = TestAccess::active_array(_storage).at(0);
   352   EXPECT_EQ(1u, TestAccess::block_allocation_count(*block));
   369   EXPECT_EQ(1u, TestAccess::block_allocation_count(*block));
   353   EXPECT_EQ(block, allocate_list.chead());
   370   EXPECT_EQ(block, allocate_list.chead());
   354 
   371 
   355   for (size_t i = 1; i < max_entries; ++i) {
   372   for (size_t i = 1; i < max_entries; ++i) {
   356     entries[i] = _storage.allocate();
   373     entries[i] = _storage.allocate();
   361     if (block == NULL) {
   378     if (block == NULL) {
   362       ASSERT_FALSE(is_list_empty(allocate_list));
   379       ASSERT_FALSE(is_list_empty(allocate_list));
   363       EXPECT_EQ(1u, list_length(allocate_list));
   380       EXPECT_EQ(1u, list_length(allocate_list));
   364       block = allocate_list.chead();
   381       block = allocate_list.chead();
   365       EXPECT_EQ(1u, TestAccess::block_allocation_count(*block));
   382       EXPECT_EQ(1u, TestAccess::block_allocation_count(*block));
   366       EXPECT_EQ(block, active_list.chead());
   383       EXPECT_EQ(block, active_head(_storage));
   367     } else if (TestAccess::block_is_full(*block)) {
   384     } else if (TestAccess::block_is_full(*block)) {
   368       EXPECT_TRUE(is_list_empty(allocate_list));
   385       EXPECT_TRUE(is_list_empty(allocate_list));
   369       block = NULL;
   386       block = NULL;
   370     } else {
   387     } else {
   371       EXPECT_FALSE(is_list_empty(allocate_list));
   388       EXPECT_FALSE(is_list_empty(allocate_list));
   372       EXPECT_EQ(block, allocate_list.chead());
   389       EXPECT_EQ(block, allocate_list.chead());
   373       EXPECT_EQ(block, active_list.chead());
   390       EXPECT_EQ(block, active_head(_storage));
   374     }
   391     }
   375   }
   392   }
   376 
   393 
   377   if (block != NULL) {
   394   if (block != NULL) {
   378     EXPECT_NE(0u, TestAccess::block_allocation_count(*block));
   395     EXPECT_NE(0u, TestAccess::block_allocation_count(*block));
   379     EXPECT_FALSE(is_list_empty(allocate_list));
   396     EXPECT_FALSE(is_list_empty(allocate_list));
   380     EXPECT_EQ(block, allocate_list.chead());
   397     EXPECT_EQ(block, allocate_list.chead());
   381     EXPECT_EQ(block, active_list.chead());
   398     EXPECT_EQ(block, active_head(_storage));
   382   }
   399   }
   383 
       
   384   size_t active_count = list_length(active_list);
       
   385 
   400 
   386   for (size_t i = 0; i < max_entries; ++i) {
   401   for (size_t i = 0; i < max_entries; ++i) {
   387     release_entry(_storage, entries[i]);
   402     release_entry(_storage, entries[i]);
   388     EXPECT_TRUE(is_allocate_list_sorted(_storage));
   403     EXPECT_TRUE(is_allocate_list_sorted(_storage));
   389     EXPECT_EQ(max_entries - (i + 1), total_allocation_count(active_list));
   404     EXPECT_EQ(max_entries - (i + 1), total_allocation_count(_storage));
   390   }
   405   }
   391 
   406 
   392   EXPECT_EQ(list_length(active_list), list_length(allocate_list));
   407   EXPECT_EQ(active_count(_storage), list_length(allocate_list));
   393   EXPECT_EQ(list_length(active_list), _storage.block_count());
   408   EXPECT_EQ(active_count(_storage), _storage.block_count());
   394   EXPECT_EQ(list_length(active_list), empty_block_count(_storage));
   409   EXPECT_EQ(active_count(_storage), empty_block_count(_storage));
   395   for (const OopBlock* block = allocate_list.chead();
   410   for (const OopBlock* block = allocate_list.chead();
   396        block != NULL;
   411        block != NULL;
   397        block = allocate_list.next(*block)) {
   412        block = allocate_list.next(*block)) {
   398     EXPECT_TRUE(TestAccess::block_is_empty(*block));
   413     EXPECT_TRUE(TestAccess::block_is_empty(*block));
   399   }
   414   }
   403   static const size_t step = 11;
   418   static const size_t step = 11;
   404   ASSERT_NE(0u, _max_entries % step); // max_entries and step are mutually prime
   419   ASSERT_NE(0u, _max_entries % step); // max_entries and step are mutually prime
   405 
   420 
   406   EXPECT_EQ(0u, empty_block_count(_storage));
   421   EXPECT_EQ(0u, empty_block_count(_storage));
   407 
   422 
   408   TestAccess::BlockList& active_list = TestAccess::active_list(_storage);
   423   OopBlockList& allocate_list = TestAccess::allocate_list(_storage);
   409   TestAccess::BlockList& allocate_list = TestAccess::allocate_list(_storage);
   424 
   410 
   425   EXPECT_EQ(_max_entries, total_allocation_count(_storage));
   411   EXPECT_EQ(_max_entries, total_allocation_count(active_list));
       
   412   EXPECT_GE(1u, list_length(allocate_list));
   426   EXPECT_GE(1u, list_length(allocate_list));
   413 
   427 
   414   // Release all entries in "random" order.
   428   // Release all entries in "random" order.
   415   size_t released = 0;
   429   size_t released = 0;
   416   for (size_t i = 0; released < _max_entries; i = (i + step) % _max_entries) {
   430   for (size_t i = 0; released < _max_entries; i = (i + step) % _max_entries) {
   417     if (_entries[i] != NULL) {
   431     if (_entries[i] != NULL) {
   418       release_entry(_storage, _entries[i]);
   432       release_entry(_storage, _entries[i]);
   419       _entries[i] = NULL;
   433       _entries[i] = NULL;
   420       ++released;
   434       ++released;
   421       EXPECT_EQ(_max_entries - released, total_allocation_count(active_list));
   435       EXPECT_EQ(_max_entries - released, total_allocation_count(_storage));
   422       EXPECT_TRUE(is_allocate_list_sorted(_storage));
   436       EXPECT_TRUE(is_allocate_list_sorted(_storage));
   423     }
   437     }
   424   }
   438   }
   425 
   439 
   426   EXPECT_EQ(list_length(active_list), list_length(allocate_list));
   440   EXPECT_EQ(active_count(_storage), list_length(allocate_list));
   427   EXPECT_EQ(list_length(active_list), _storage.block_count());
   441   EXPECT_EQ(active_count(_storage), _storage.block_count());
   428   EXPECT_EQ(0u, total_allocation_count(active_list));
   442   EXPECT_EQ(0u, total_allocation_count(_storage));
   429   EXPECT_EQ(list_length(allocate_list), empty_block_count(_storage));
   443   EXPECT_EQ(list_length(allocate_list), empty_block_count(_storage));
   430 }
   444 }
   431 
   445 
   432 TEST_VM_F(OopStorageTestWithAllocation, random_allocate_release) {
   446 TEST_VM_F(OopStorageTestWithAllocation, random_allocate_release) {
   433   static const size_t release_step = 11;
   447   static const size_t release_step = 11;
   434   static const size_t allocate_step = 5;
   448   static const size_t allocate_step = 5;
   435   ASSERT_NE(0u, _max_entries % release_step); // max_entries and step are mutually prime
   449   ASSERT_NE(0u, _max_entries % release_step); // max_entries and step are mutually prime
   436 
   450 
   437   EXPECT_EQ(0u, empty_block_count(_storage));
   451   EXPECT_EQ(0u, empty_block_count(_storage));
   438 
   452 
   439   TestAccess::BlockList& active_list = TestAccess::active_list(_storage);
   453   OopBlockList& allocate_list = TestAccess::allocate_list(_storage);
   440   TestAccess::BlockList& allocate_list = TestAccess::allocate_list(_storage);
   454 
   441 
   455   EXPECT_EQ(_max_entries, total_allocation_count(_storage));
   442   EXPECT_EQ(_max_entries, total_allocation_count(active_list));
       
   443   EXPECT_GE(1u, list_length(allocate_list));
   456   EXPECT_GE(1u, list_length(allocate_list));
   444 
   457 
   445   // Release all entries in "random" order, "randomly" interspersed
   458   // Release all entries in "random" order, "randomly" interspersed
   446   // with additional allocations.
   459   // with additional allocations.
   447   size_t released = 0;
   460   size_t released = 0;
   450     if (_entries[i] != NULL) {
   463     if (_entries[i] != NULL) {
   451       release_entry(_storage, _entries[i]);
   464       release_entry(_storage, _entries[i]);
   452       _entries[i] = NULL;
   465       _entries[i] = NULL;
   453       ++released;
   466       ++released;
   454       ++total_released;
   467       ++total_released;
   455       EXPECT_EQ(_max_entries - released, total_allocation_count(active_list));
   468       EXPECT_EQ(_max_entries - released, total_allocation_count(_storage));
   456       EXPECT_TRUE(is_allocate_list_sorted(_storage));
   469       EXPECT_TRUE(is_allocate_list_sorted(_storage));
   457       if (total_released % allocate_step == 0) {
   470       if (total_released % allocate_step == 0) {
   458         _entries[i] = _storage.allocate();
   471         _entries[i] = _storage.allocate();
   459         --released;
   472         --released;
   460         EXPECT_EQ(_max_entries - released, total_allocation_count(active_list));
   473         EXPECT_EQ(_max_entries - released, total_allocation_count(_storage));
   461         EXPECT_TRUE(is_allocate_list_sorted(_storage));
   474         EXPECT_TRUE(is_allocate_list_sorted(_storage));
   462       }
   475       }
   463     }
   476     }
   464   }
   477   }
   465 
   478 
   466   EXPECT_EQ(list_length(active_list), list_length(allocate_list));
   479   EXPECT_EQ(active_count(_storage), list_length(allocate_list));
   467   EXPECT_EQ(list_length(active_list), _storage.block_count());
   480   EXPECT_EQ(active_count(_storage), _storage.block_count());
   468   EXPECT_EQ(0u, total_allocation_count(active_list));
   481   EXPECT_EQ(0u, total_allocation_count(_storage));
   469   EXPECT_EQ(list_length(allocate_list), empty_block_count(_storage));
   482   EXPECT_EQ(list_length(allocate_list), empty_block_count(_storage));
   470 }
   483 }
   471 
   484 
   472 template<bool sorted>
   485 template<bool sorted>
   473 class OopStorageTestBlockRelease : public OopStorageTestWithAllocation {
   486 class OopStorageTestBlockRelease : public OopStorageTestWithAllocation {
  1013   workers()->run_task(&task);
  1026   workers()->run_task(&task);
  1014   vstate.check();
  1027   vstate.check();
  1015 }
  1028 }
  1016 
  1029 
  1017 TEST_VM_F(OopStorageTestWithAllocation, delete_empty_blocks_safepoint) {
  1030 TEST_VM_F(OopStorageTestWithAllocation, delete_empty_blocks_safepoint) {
  1018   TestAccess::BlockList& active_list = TestAccess::active_list(_storage);
  1031   size_t initial_active_size = active_count(_storage);
  1019 
       
  1020   size_t initial_active_size = list_length(active_list);
       
  1021   EXPECT_EQ(initial_active_size, _storage.block_count());
  1032   EXPECT_EQ(initial_active_size, _storage.block_count());
  1022   ASSERT_LE(3u, initial_active_size); // Need at least 3 blocks for test
  1033   ASSERT_LE(3u, initial_active_size); // Need at least 3 blocks for test
  1023 
  1034 
  1024   for (size_t i = 0; empty_block_count(_storage) < 3; ++i) {
  1035   for (size_t i = 0; empty_block_count(_storage) < 3; ++i) {
  1025     ASSERT_GT(_max_entries, i);
  1036     ASSERT_GT(_max_entries, i);
  1026     release_entry(_storage, _entries[i]);
  1037     release_entry(_storage, _entries[i]);
  1027   }
  1038   }
  1028 
  1039 
  1029   EXPECT_EQ(initial_active_size, list_length(active_list));
  1040   EXPECT_EQ(initial_active_size, active_count(_storage));
  1030   EXPECT_EQ(initial_active_size, _storage.block_count());
  1041   EXPECT_EQ(initial_active_size, _storage.block_count());
  1031   EXPECT_EQ(3u, empty_block_count(_storage));
  1042   EXPECT_EQ(3u, empty_block_count(_storage));
  1032 
  1043 
  1033   {
  1044   {
  1034     ThreadInVMfromNative invm(JavaThread::current());
  1045     ThreadInVMfromNative invm(JavaThread::current());
  1035     VM_DeleteBlocksAtSafepoint op(&_storage);
  1046     VM_DeleteBlocksAtSafepoint op(&_storage);
  1036     VMThread::execute(&op);
  1047     VMThread::execute(&op);
  1037   }
  1048   }
  1038   EXPECT_EQ(0u, empty_block_count(_storage));
  1049   EXPECT_EQ(0u, empty_block_count(_storage));
  1039   EXPECT_EQ(initial_active_size - 3, list_length(active_list));
  1050   EXPECT_EQ(initial_active_size - 3, active_count(_storage));
  1040   EXPECT_EQ(initial_active_size - 3, _storage.block_count());
  1051   EXPECT_EQ(initial_active_size - 3, _storage.block_count());
  1041 }
  1052 }
  1042 
  1053 
  1043 TEST_VM_F(OopStorageTestWithAllocation, delete_empty_blocks_concurrent) {
  1054 TEST_VM_F(OopStorageTestWithAllocation, delete_empty_blocks_concurrent) {
  1044   TestAccess::BlockList& active_list = TestAccess::active_list(_storage);
  1055   size_t initial_active_size = active_count(_storage);
  1045 
       
  1046   size_t initial_active_size = list_length(active_list);
       
  1047   EXPECT_EQ(initial_active_size, _storage.block_count());
  1056   EXPECT_EQ(initial_active_size, _storage.block_count());
  1048   ASSERT_LE(3u, initial_active_size); // Need at least 3 blocks for test
  1057   ASSERT_LE(3u, initial_active_size); // Need at least 3 blocks for test
  1049 
  1058 
  1050   for (size_t i = 0; empty_block_count(_storage) < 3; ++i) {
  1059   for (size_t i = 0; empty_block_count(_storage) < 3; ++i) {
  1051     ASSERT_GT(_max_entries, i);
  1060     ASSERT_GT(_max_entries, i);
  1052     release_entry(_storage, _entries[i]);
  1061     release_entry(_storage, _entries[i]);
  1053   }
  1062   }
  1054 
  1063 
  1055   EXPECT_EQ(initial_active_size, list_length(active_list));
  1064   EXPECT_EQ(initial_active_size, active_count(_storage));
  1056   EXPECT_EQ(initial_active_size, _storage.block_count());
  1065   EXPECT_EQ(initial_active_size, _storage.block_count());
  1057   EXPECT_EQ(3u, empty_block_count(_storage));
  1066   EXPECT_EQ(3u, empty_block_count(_storage));
  1058 
  1067 
  1059   _storage.delete_empty_blocks_concurrent();
  1068   _storage.delete_empty_blocks_concurrent();
  1060   EXPECT_EQ(0u, empty_block_count(_storage));
  1069   EXPECT_EQ(0u, empty_block_count(_storage));
  1061   EXPECT_EQ(initial_active_size - 3, list_length(active_list));
  1070   EXPECT_EQ(initial_active_size - 3, active_count(_storage));
  1062   EXPECT_EQ(initial_active_size - 3, _storage.block_count());
  1071   EXPECT_EQ(initial_active_size - 3, _storage.block_count());
  1063 }
  1072 }
  1064 
  1073 
  1065 TEST_VM_F(OopStorageTestWithAllocation, allocation_status) {
  1074 TEST_VM_F(OopStorageTestWithAllocation, allocation_status) {
  1066   oop* retained = _entries[200];
  1075   oop* retained = _entries[200];
  1159   }
  1168   }
  1160 }
  1169 }
  1161 
  1170 
  1162 #endif // !PRODUCT
  1171 #endif // !PRODUCT
  1163 
  1172 
  1164 //////////////////////////////////////////////////////////////////////////////
  1173 class OopStorageBlockCollectionTest : public ::testing::Test {
  1165 // Unit tests for block lists
  1174 protected:
  1166 
  1175   OopStorageBlockCollectionTest() {
  1167 class OopStorageBlockListTest : public ::testing::Test {
       
  1168 public:
       
  1169   OopStorageBlockListTest() {
       
  1170     for (size_t i = 0; i < nvalues; ++i) {
  1176     for (size_t i = 0; i < nvalues; ++i) {
  1171       values[i] = OopBlock::new_block(pseudo_owner());
  1177       values[i] = OopBlock::new_block(pseudo_owner());
  1172     }
  1178     }
  1173   }
  1179   }
  1174 
  1180 
  1175   ~OopStorageBlockListTest() {
  1181   ~OopStorageBlockCollectionTest() {
  1176     for (size_t i = 0; i < nvalues; ++i) {
  1182     for (size_t i = 0; i < nvalues; ++i) {
  1177       OopBlock::delete_block(*values[i]);
  1183       OopBlock::delete_block(*values[i]);
  1178     }
  1184     }
  1179   }
  1185   }
  1180 
  1186 
       
  1187 public:
  1181   static const size_t nvalues = 10;
  1188   static const size_t nvalues = 10;
  1182   OopBlock* values[nvalues];
  1189   OopBlock* values[nvalues];
  1183 
  1190 
  1184 private:
  1191 private:
  1185   // The only thing we actually care about is the address of the owner.
  1192   // The only thing we actually care about is the address of the owner.
  1188   static const OopStorage* pseudo_owner() {
  1195   static const OopStorage* pseudo_owner() {
  1189     return reinterpret_cast<const OopStorage*>(&_pseudo_owner);
  1196     return reinterpret_cast<const OopStorage*>(&_pseudo_owner);
  1190   }
  1197   }
  1191 };
  1198 };
  1192 
  1199 
  1193 const size_t OopStorageBlockListTest::nvalues;
  1200 const size_t OopStorageBlockCollectionTest::nvalues;
  1194 const void* const OopStorageBlockListTest::_pseudo_owner[] = {};
  1201 const void* const OopStorageBlockCollectionTest::_pseudo_owner[] = {};
       
  1202 
       
  1203 class OopStorageBlockListTest : public OopStorageBlockCollectionTest {};
  1195 
  1204 
  1196 TEST_F(OopStorageBlockListTest, empty_list) {
  1205 TEST_F(OopStorageBlockListTest, empty_list) {
  1197   TestAccess::BlockList list(&OopBlock::get_active_entry);
  1206   OopBlockList list(&OopBlock::get_allocate_entry);
  1198 
  1207 
  1199   EXPECT_TRUE(is_list_empty(list));
  1208   EXPECT_TRUE(is_list_empty(list));
  1200   EXPECT_EQ(NULL_BLOCK, list.head());
  1209   EXPECT_EQ(NULL_BLOCK, list.head());
  1201   EXPECT_EQ(NULL_BLOCK, list.chead());
  1210   EXPECT_EQ(NULL_BLOCK, list.chead());
  1202   EXPECT_EQ(NULL_BLOCK, list.ctail());
  1211   EXPECT_EQ(NULL_BLOCK, list.ctail());
  1203 }
  1212 }
  1204 
  1213 
  1205 TEST_F(OopStorageBlockListTest, push_back) {
  1214 TEST_F(OopStorageBlockListTest, push_back) {
  1206   TestAccess::BlockList list(&OopBlock::get_active_entry);
  1215   OopBlockList list(&OopBlock::get_allocate_entry);
  1207 
  1216 
  1208   for (size_t i = 0; i < nvalues; ++i) {
  1217   for (size_t i = 0; i < nvalues; ++i) {
  1209     list.push_back(*values[i]);
  1218     list.push_back(*values[i]);
  1210     EXPECT_FALSE(is_list_empty(list));
  1219     EXPECT_FALSE(is_list_empty(list));
  1211     EXPECT_EQ(list.ctail(), values[i]);
  1220     EXPECT_EQ(list.ctail(), values[i]);
  1231 
  1240 
  1232   clear_list(list);
  1241   clear_list(list);
  1233 }
  1242 }
  1234 
  1243 
  1235 TEST_F(OopStorageBlockListTest, push_front) {
  1244 TEST_F(OopStorageBlockListTest, push_front) {
  1236   TestAccess::BlockList list(&OopBlock::get_active_entry);
  1245   OopBlockList list(&OopBlock::get_allocate_entry);
  1237 
  1246 
  1238   for (size_t i = 0; i < nvalues; ++i) {
  1247   for (size_t i = 0; i < nvalues; ++i) {
  1239     list.push_front(*values[i]);
  1248     list.push_front(*values[i]);
  1240     EXPECT_FALSE(is_list_empty(list));
  1249     EXPECT_FALSE(is_list_empty(list));
  1241     EXPECT_EQ(list.head(), values[i]);
  1250     EXPECT_EQ(list.head(), values[i]);
  1262   clear_list(list);
  1271   clear_list(list);
  1263 }
  1272 }
  1264 
  1273 
  1265 class OopStorageBlockListTestWithList : public OopStorageBlockListTest {
  1274 class OopStorageBlockListTestWithList : public OopStorageBlockListTest {
  1266 public:
  1275 public:
  1267   OopStorageBlockListTestWithList() : list(&OopBlock::get_active_entry) {
  1276   OopStorageBlockListTestWithList() : list(&OopBlock::get_allocate_entry) {
  1268     for (size_t i = 0; i < nvalues; ++i) {
  1277     for (size_t i = 0; i < nvalues; ++i) {
  1269       list.push_back(*values[i]);
  1278       list.push_back(*values[i]);
  1270     }
  1279     }
  1271   }
  1280   }
  1272 
  1281 
  1273   ~OopStorageBlockListTestWithList() {
  1282   ~OopStorageBlockListTestWithList() {
  1274     clear_list(list);
  1283     clear_list(list);
  1275   }
  1284   }
  1276 
  1285 
  1277   TestAccess::BlockList list;
  1286   OopBlockList list;
  1278 };
  1287 };
  1279 
  1288 
  1280 TEST_F(OopStorageBlockListTestWithList, unlink_front) {
  1289 TEST_F(OopStorageBlockListTestWithList, unlink_front) {
  1281   EXPECT_EQ(list.chead(), values[0]);
  1290   EXPECT_EQ(list.chead(), values[0]);
  1282   EXPECT_EQ(list.ctail(), values[nvalues - 1]);
  1291   EXPECT_EQ(list.ctail(), values[nvalues - 1]);
  1334   }
  1343   }
  1335   EXPECT_EQ(NULL_BLOCK, block);
  1344   EXPECT_EQ(NULL_BLOCK, block);
  1336 }
  1345 }
  1337 
  1346 
  1338 TEST_F(OopStorageBlockListTest, single) {
  1347 TEST_F(OopStorageBlockListTest, single) {
  1339   TestAccess::BlockList list(&OopBlock::get_active_entry);
  1348   OopBlockList list(&OopBlock::get_allocate_entry);
  1340 
  1349 
  1341   list.push_back(*values[0]);
  1350   list.push_back(*values[0]);
  1342   EXPECT_EQ(NULL_BLOCK, list.next(*values[0]));
  1351   EXPECT_EQ(NULL_BLOCK, list.next(*values[0]));
  1343   EXPECT_EQ(NULL_BLOCK, list.prev(*values[0]));
  1352   EXPECT_EQ(NULL_BLOCK, list.prev(*values[0]));
  1344   EXPECT_EQ(list.chead(), values[0]);
  1353   EXPECT_EQ(list.chead(), values[0]);
  1349   EXPECT_EQ(NULL_BLOCK, list.prev(*values[0]));
  1358   EXPECT_EQ(NULL_BLOCK, list.prev(*values[0]));
  1350   EXPECT_EQ(NULL_BLOCK, list.chead());
  1359   EXPECT_EQ(NULL_BLOCK, list.chead());
  1351   EXPECT_EQ(NULL_BLOCK, list.ctail());
  1360   EXPECT_EQ(NULL_BLOCK, list.ctail());
  1352 }
  1361 }
  1353 
  1362 
  1354 TEST_F(OopStorageBlockListTestWithList, two_lists) {
  1363 class OopStorageBlockArrayTest : public OopStorageBlockCollectionTest {};
  1355   TestAccess::BlockList list2(&OopBlock::get_allocate_entry);
  1364 
  1356   for (size_t i = 0; i < nvalues; ++i) {
  1365 TEST_F(OopStorageBlockArrayTest, empty_array) {
  1357     list2.push_front(*values[i]);
  1366   OopBlockArray* a = OopBlockArray::create(nvalues);
  1358   }
  1367 
  1359 
  1368   EXPECT_EQ(nvalues, a->size());
  1360   const OopBlock* active_block = list.chead();
  1369   EXPECT_EQ(0u, a->block_count_acquire());
  1361   const OopBlock* allocate_block = list2.ctail();
  1370   TestAccess::block_array_set_block_count(a, 2);
  1362   for (size_t i = 0; i < nvalues; ++i) {
  1371   EXPECT_EQ(2u, a->block_count_acquire());
  1363     EXPECT_EQ(active_block, allocate_block);
  1372   TestAccess::block_array_set_block_count(a, 0);
  1364     active_block = list.next(*active_block);
  1373   a->increment_refcount();
  1365     allocate_block = list2.prev(*allocate_block);
  1374   a->increment_refcount();
  1366   }
  1375   EXPECT_FALSE(a->decrement_refcount());
  1367   EXPECT_EQ(NULL_BLOCK, active_block);
  1376   EXPECT_TRUE(a->decrement_refcount());
  1368   EXPECT_EQ(NULL_BLOCK, allocate_block);
  1377 
  1369 
  1378   OopBlockArray::destroy(a);
  1370   for (size_t i = 0; i < nvalues; ++i) {
  1379 }
  1371     list2.unlink(*values[i]);
  1380 
  1372   }
  1381 TEST_F(OopStorageBlockArrayTest, push) {
  1373   EXPECT_TRUE(is_list_empty(list2));
  1382   OopBlockArray* a = OopBlockArray::create(nvalues - 1);
  1374 
  1383 
  1375   active_block = list.chead();
  1384   for (size_t i = 0; i < nvalues - 1; ++i) {
  1376   for (size_t i = 0; i < nvalues; ++i) {
  1385     EXPECT_TRUE(a->push(values[i]));
  1377     EXPECT_EQ(active_block, values[i]);
  1386     EXPECT_EQ(i + 1, a->block_count_acquire());
  1378     active_block = list.next(*active_block);
  1387     EXPECT_EQ(values[i], a->at(i));
  1379   }
  1388   }
  1380   EXPECT_EQ(NULL_BLOCK, active_block);
  1389   EXPECT_FALSE(a->push(values[nvalues - 1]));
  1381 }
  1390 
       
  1391   TestAccess::block_array_set_block_count(a, 0);
       
  1392   OopBlockArray::destroy(a);
       
  1393 }
       
  1394 
       
  1395 class OopStorageBlockArrayTestWithArray : public OopStorageBlockArrayTest {
       
  1396 public:
       
  1397   OopStorageBlockArrayTestWithArray() : a(OopBlockArray::create(nvalues)) {
       
  1398     for (size_t i = 0; i < nvalues; ++i) {
       
  1399       a->push(values[i]);
       
  1400     }
       
  1401   }
       
  1402 
       
  1403   ~OopStorageBlockArrayTestWithArray() {
       
  1404     TestAccess::block_array_set_block_count(a, 0);
       
  1405     OopBlockArray::destroy(a);
       
  1406   }
       
  1407 
       
  1408   OopBlockArray* a;
       
  1409 };
       
  1410 
       
  1411 TEST_F(OopStorageBlockArrayTestWithArray, remove0) {
       
  1412   a->remove(values[0]);
       
  1413   EXPECT_EQ(nvalues - 1, a->block_count_acquire());
       
  1414   EXPECT_EQ(values[nvalues - 1], a->at(0));
       
  1415   for (size_t i = 1; i < nvalues - 1; ++i) {
       
  1416     EXPECT_EQ(values[i], a->at(i));
       
  1417   }
       
  1418 }
       
  1419 
       
  1420 TEST_F(OopStorageBlockArrayTestWithArray, remove3) {
       
  1421   a->remove(values[3]);
       
  1422   EXPECT_EQ(nvalues - 1, a->block_count_acquire());
       
  1423   for (size_t i = 0; i < 3; ++i) {
       
  1424     EXPECT_EQ(values[i], a->at(i));
       
  1425   }
       
  1426   EXPECT_EQ(values[nvalues - 1], a->at(3));
       
  1427   for (size_t i = 4; i < nvalues - 1; ++i) {
       
  1428     EXPECT_EQ(values[i], a->at(i));
       
  1429   }
       
  1430 }
       
  1431 
       
  1432 TEST_F(OopStorageBlockArrayTestWithArray, remove_last) {
       
  1433   a->remove(values[nvalues - 1]);
       
  1434   EXPECT_EQ(nvalues - 1, a->block_count_acquire());
       
  1435   for (size_t i = 0; i < nvalues - 1; ++i) {
       
  1436     EXPECT_EQ(values[i], a->at(i));
       
  1437   }
       
  1438 }