< prev index next >

test/hotspot/gtest/utilities/test_resourceHash.cpp

Print this page

  1 /*
  2  * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */

135       ASSERT_TRUE(rh.remove(as_K(step)));
136       ASSERT_FALSE(rh.contains(as_K(step)));
137       rh.iterate(&et);
138 
139       // Test put_if_absent(key, value)
140       v = rh.put_if_absent(as_K(step), step, &created);
141       ASSERT_EQ(*v, step);
142       ASSERT_TRUE(rh.contains(as_K(step)));
143       ASSERT_TRUE(created);
144 
145       v2 = rh.put_if_absent(as_K(step), step, &created);
146       // Calling this function a second time should yield the same value pointer
147       ASSERT_EQ(v, v2);
148       ASSERT_EQ(*v2, (V)step);
149       ASSERT_FALSE(created);
150 
151       ASSERT_TRUE(rh.remove(as_K(step)));
152       ASSERT_FALSE(rh.contains(as_K(step)));
153       rh.iterate(&et);
154 
155 
156     }
157   };
158 };
159 
160 TEST_VM_F(SmallResourceHashtableTest, default) {
161   ResourceMark rm;
162   Runner<>::test(0x1);
163 }
164 
165 TEST_VM_F(SmallResourceHashtableTest, default_shifted) {
166   ResourceMark rm;
167   Runner<>::test(0x10);
168 }
169 
170 TEST_VM_F(SmallResourceHashtableTest, bad_hash) {
171   ResourceMark rm;
172   Runner<bad_hash>::test(0x1);
173 }
174 
175 TEST_VM_F(SmallResourceHashtableTest, bad_hash_shifted) {

242       }
243 
244       rh.iterate(&et);
245       if (::testing::Test::HasFailure()) {
246         return;
247       }
248       for (uintptr_t i = num_elements; i > 0; --i) {
249         uintptr_t index = i - 1;
250         ASSERT_FALSE(rh.remove(as_K(index)));
251       }
252       rh.iterate(&et);
253 
254       // Add more entries in and then delete one.
255       for (uintptr_t i = 10; i > 0; --i) {
256         uintptr_t index = i - 1;
257         ASSERT_TRUE(rh.put(as_K(index), index));
258       }
259       DeleterTestIter dt(5);
260       rh.unlink(&dt);
261       ASSERT_FALSE(rh.get(as_K(5)));






262     }
263   };
264 };
265 
266 TEST_VM_F(GenericResourceHashtableTest, default) {
267   ResourceMark rm;
268   Runner<>::test();
269 }
270 
271 TEST_VM_F(GenericResourceHashtableTest, bad_hash) {
272   ResourceMark rm;
273   Runner<bad_hash>::test();
274 }
275 
276 TEST_VM_F(GenericResourceHashtableTest, identity_hash) {
277   ResourceMark rm;
278   Runner<identity_hash>::test();
279 }
280 
281 TEST_VM_F(GenericResourceHashtableTest, primitive_hash_no_rm) {

313   ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount should be incremented in table";
314 
315   // Deleting this value from a hashtable
316   _simple_test_table.remove(s);
317   ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be same as start";
318 }
319 
320 TEST_VM_F(SimpleResourceHashtableDeleteTest, simple_delete) {
321   TempNewSymbol t = SymbolTable::new_symbol("abcdefg_simple");
322   Symbol* s = t;
323   int s_orig_count = s->refcount();
324   _simple_test_table.put(s, 66);
325   ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount should be incremented in table";
326 
327   // Use unlink to remove the matching (or all) values from the table.
328   SimpleDeleter deleter;
329   _simple_test_table.unlink(&deleter);
330   ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be same as start";
331 }
332 












333 // More complicated ResourceHashtable with SymbolHandle in the key. Since the *same* Symbol is part
334 // of the value, it's not necessary to manipulate the refcount of the key, but you must in the value.
335 // Luckily SymbolHandle does this.
336 class ResourceHashtableDeleteTest : public ::testing::Test {
337  public:
338     class TestValue : public CHeapObj<mtTest> {
339         SymbolHandle _s;
340       public:
341         // Never have ctors and dtors fix refcounts without copy ctors and assignment operators!
342         // Unless it's declared and used as a CHeapObj with
343         // NONCOPYABLE(TestValue)
344 
345         // Using SymbolHandle deals with refcount manipulation so this class doesn't have to
346         // have dtors, copy ctors and assignment operators to do so.
347         TestValue(Symbol* name) : _s(name) { }
348         // Symbol* s() const { return _s; }  // needed for conversion from TempNewSymbol to SymbolHandle member
349     };
350 
351     // ResourceHashtable whose value is a *copy* of TestValue.
352     ResourceHashtable<Symbol*, TestValue, 107, AnyObj::C_HEAP, mtTest> _test_table;

394   _test_table.remove(s);
395   // Removal should make the refcount be the original refcount.
396   ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be as we started";
397 }
398 
399 TEST_VM_F(ResourceHashtableDeleteTest, value_delete) {
400   TempNewSymbol d = SymbolTable::new_symbol("defghijklmnop");
401   int d_orig_count = d->refcount();
402   {
403     TestValue tv(d);
404     // Same as above, but the do_entry does nothing because the value is deleted when the
405     // hashtable node is deleted.
406     _test_table.put(d, tv);
407     ASSERT_EQ(d->refcount(), d_orig_count + 2) << "refcount incremented by copy";
408   }
409   ASSERT_EQ(d->refcount(), d_orig_count + 1) << "refcount incremented in table";
410   Deleter deleter;
411   _test_table.unlink(&deleter);
412   ASSERT_EQ(d->refcount(), d_orig_count) << "refcount should be as we started";
413 }















414 
415 TEST_VM_F(ResourceHashtableDeleteTest, check_delete_ptr) {
416   TempNewSymbol s = SymbolTable::new_symbol("abcdefg_ptr");
417   int s_orig_count = s->refcount();
418   {
419     TestValue* tv = new TestValue(s);
420     // Again since TestValue contains the pointer to the key Symbol, it will
421     // handle the refcounting.
422     _ptr_test_table.put(s, tv);
423     ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount incremented by allocation";
424   }
425   ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount incremented in table";
426 
427   // Deleting this pointer value from a hashtable must call the destructor in the
428   // do_entry function.
429   PtrDeleter deleter;
430   _ptr_test_table.unlink(&deleter);
431   // Removal should make the refcount be the original refcount.
432   ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be as we started";
433 }

  1 /*
  2  * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  */

135       ASSERT_TRUE(rh.remove(as_K(step)));
136       ASSERT_FALSE(rh.contains(as_K(step)));
137       rh.iterate(&et);
138 
139       // Test put_if_absent(key, value)
140       v = rh.put_if_absent(as_K(step), step, &created);
141       ASSERT_EQ(*v, step);
142       ASSERT_TRUE(rh.contains(as_K(step)));
143       ASSERT_TRUE(created);
144 
145       v2 = rh.put_if_absent(as_K(step), step, &created);
146       // Calling this function a second time should yield the same value pointer
147       ASSERT_EQ(v, v2);
148       ASSERT_EQ(*v2, (V)step);
149       ASSERT_FALSE(created);
150 
151       ASSERT_TRUE(rh.remove(as_K(step)));
152       ASSERT_FALSE(rh.contains(as_K(step)));
153       rh.iterate(&et);
154 
155       rh.unlink_all();
156     }
157   };
158 };
159 
160 TEST_VM_F(SmallResourceHashtableTest, default) {
161   ResourceMark rm;
162   Runner<>::test(0x1);
163 }
164 
165 TEST_VM_F(SmallResourceHashtableTest, default_shifted) {
166   ResourceMark rm;
167   Runner<>::test(0x10);
168 }
169 
170 TEST_VM_F(SmallResourceHashtableTest, bad_hash) {
171   ResourceMark rm;
172   Runner<bad_hash>::test(0x1);
173 }
174 
175 TEST_VM_F(SmallResourceHashtableTest, bad_hash_shifted) {

242       }
243 
244       rh.iterate(&et);
245       if (::testing::Test::HasFailure()) {
246         return;
247       }
248       for (uintptr_t i = num_elements; i > 0; --i) {
249         uintptr_t index = i - 1;
250         ASSERT_FALSE(rh.remove(as_K(index)));
251       }
252       rh.iterate(&et);
253 
254       // Add more entries in and then delete one.
255       for (uintptr_t i = 10; i > 0; --i) {
256         uintptr_t index = i - 1;
257         ASSERT_TRUE(rh.put(as_K(index), index));
258       }
259       DeleterTestIter dt(5);
260       rh.unlink(&dt);
261       ASSERT_FALSE(rh.get(as_K(5)));
262 
263       rh.unlink_all();
264       for (uintptr_t i = 10; i > 0; --i) {
265         uintptr_t index = i - 1;
266         ASSERT_FALSE(rh.get(as_K(index)));
267       }
268     }
269   };
270 };
271 
272 TEST_VM_F(GenericResourceHashtableTest, default) {
273   ResourceMark rm;
274   Runner<>::test();
275 }
276 
277 TEST_VM_F(GenericResourceHashtableTest, bad_hash) {
278   ResourceMark rm;
279   Runner<bad_hash>::test();
280 }
281 
282 TEST_VM_F(GenericResourceHashtableTest, identity_hash) {
283   ResourceMark rm;
284   Runner<identity_hash>::test();
285 }
286 
287 TEST_VM_F(GenericResourceHashtableTest, primitive_hash_no_rm) {

319   ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount should be incremented in table";
320 
321   // Deleting this value from a hashtable
322   _simple_test_table.remove(s);
323   ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be same as start";
324 }
325 
326 TEST_VM_F(SimpleResourceHashtableDeleteTest, simple_delete) {
327   TempNewSymbol t = SymbolTable::new_symbol("abcdefg_simple");
328   Symbol* s = t;
329   int s_orig_count = s->refcount();
330   _simple_test_table.put(s, 66);
331   ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount should be incremented in table";
332 
333   // Use unlink to remove the matching (or all) values from the table.
334   SimpleDeleter deleter;
335   _simple_test_table.unlink(&deleter);
336   ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be same as start";
337 }
338 
339 TEST_VM_F(SimpleResourceHashtableDeleteTest, simle_unlink_all) {
340   TempNewSymbol t = SymbolTable::new_symbol("abcdefg_simple");
341   Symbol* s = t;
342   int s_orig_count = s->refcount();
343   _simple_test_table.put(s, 66);
344   ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount should be incremented in table";
345 
346   // Use unlink_all to remove the matching (or all) values from the table.
347   _simple_test_table.unlink_all();
348   ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be same as start";
349 }
350 
351 // More complicated ResourceHashtable with SymbolHandle in the key. Since the *same* Symbol is part
352 // of the value, it's not necessary to manipulate the refcount of the key, but you must in the value.
353 // Luckily SymbolHandle does this.
354 class ResourceHashtableDeleteTest : public ::testing::Test {
355  public:
356     class TestValue : public CHeapObj<mtTest> {
357         SymbolHandle _s;
358       public:
359         // Never have ctors and dtors fix refcounts without copy ctors and assignment operators!
360         // Unless it's declared and used as a CHeapObj with
361         // NONCOPYABLE(TestValue)
362 
363         // Using SymbolHandle deals with refcount manipulation so this class doesn't have to
364         // have dtors, copy ctors and assignment operators to do so.
365         TestValue(Symbol* name) : _s(name) { }
366         // Symbol* s() const { return _s; }  // needed for conversion from TempNewSymbol to SymbolHandle member
367     };
368 
369     // ResourceHashtable whose value is a *copy* of TestValue.
370     ResourceHashtable<Symbol*, TestValue, 107, AnyObj::C_HEAP, mtTest> _test_table;

412   _test_table.remove(s);
413   // Removal should make the refcount be the original refcount.
414   ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be as we started";
415 }
416 
417 TEST_VM_F(ResourceHashtableDeleteTest, value_delete) {
418   TempNewSymbol d = SymbolTable::new_symbol("defghijklmnop");
419   int d_orig_count = d->refcount();
420   {
421     TestValue tv(d);
422     // Same as above, but the do_entry does nothing because the value is deleted when the
423     // hashtable node is deleted.
424     _test_table.put(d, tv);
425     ASSERT_EQ(d->refcount(), d_orig_count + 2) << "refcount incremented by copy";
426   }
427   ASSERT_EQ(d->refcount(), d_orig_count + 1) << "refcount incremented in table";
428   Deleter deleter;
429   _test_table.unlink(&deleter);
430   ASSERT_EQ(d->refcount(), d_orig_count) << "refcount should be as we started";
431 }
432 
433 TEST_VM_F(ResourceHashtableDeleteTest, value_unlink_all) {
434   TempNewSymbol d = SymbolTable::new_symbol("defghijklmnop");
435   int d_orig_count = d->refcount();
436   {
437     TestValue tv(d);
438     // Same as above, but the do_entry does nothing because the value is deleted when the
439     // hashtable node is deleted.
440     _test_table.put(d, tv);
441     ASSERT_EQ(d->refcount(), d_orig_count + 2) << "refcount incremented by copy";
442   }
443   ASSERT_EQ(d->refcount(), d_orig_count + 1) << "refcount incremented in table";
444   _test_table.unlink_all();
445   ASSERT_EQ(d->refcount(), d_orig_count) << "refcount should be as we started";
446 }
447 
448 TEST_VM_F(ResourceHashtableDeleteTest, check_delete_ptr) {
449   TempNewSymbol s = SymbolTable::new_symbol("abcdefg_ptr");
450   int s_orig_count = s->refcount();
451   {
452     TestValue* tv = new TestValue(s);
453     // Again since TestValue contains the pointer to the key Symbol, it will
454     // handle the refcounting.
455     _ptr_test_table.put(s, tv);
456     ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount incremented by allocation";
457   }
458   ASSERT_EQ(s->refcount(), s_orig_count + 1) << "refcount incremented in table";
459 
460   // Deleting this pointer value from a hashtable must call the destructor in the
461   // do_entry function.
462   PtrDeleter deleter;
463   _ptr_test_table.unlink(&deleter);
464   // Removal should make the refcount be the original refcount.
465   ASSERT_EQ(s->refcount(), s_orig_count) << "refcount should be as we started";
466 }
< prev index next >