src/share/vm/utilities/resourceHash.cpp

Thu, 27 Feb 2020 06:41:35 +0000

author
andrew
date
Thu, 27 Feb 2020 06:41:35 +0000
changeset 9845
68172de2a0d7
permissions
-rw-r--r--

8055283: Expand ResourceHashtable with C_HEAP allocation, removal and some unit tests
Reviewed-by: phh

     1 /*
     2  * Copyright (c) 2015 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  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "memory/allocation.hpp"
    27 #include "memory/resourceArea.hpp"
    28 #include "utilities/debug.hpp"
    29 #include "utilities/resourceHash.hpp"
    31 #ifndef PRODUCT
    33 /////////////// Unit tests ///////////////
    35 class TestResourceHashtable : public AllStatic {
    36   typedef void* K;
    37   typedef int V;
    39   static unsigned identity_hash(const K& k) {
    40     return (unsigned)(uintptr_t)k;
    41   }
    43   static unsigned bad_hash(const K& k) {
    44     return 1;
    45   }
    47   class EqualityTestIter {
    48    public:
    49     bool do_entry(K const& k, V const& v) {
    50       assert((uintptr_t)k == (uintptr_t)v, "");
    51       return true; // continue iteration
    52     }
    53   };
    55   template<
    56   unsigned (*HASH)  (K const&)           = primitive_hash<K>,
    57   bool     (*EQUALS)(K const&, K const&) = primitive_equals<K>,
    58   unsigned SIZE = 256,
    59   ResourceObj::allocation_type ALLOC_TYPE = ResourceObj::RESOURCE_AREA,
    60   MEMFLAGS MEM_TYPE = mtInternal
    61   >
    62   class Runner : public AllStatic {
    63     static void* as_K(uintptr_t val) { return (void*)val; }
    65    public:
    66     static void test_small() {
    67       EqualityTestIter et;
    68       ResourceHashtable<K, V, HASH, EQUALS, SIZE, ALLOC_TYPE, MEM_TYPE> rh;
    70       assert(!rh.contains(as_K(0x1)), "");
    72       assert(rh.put(as_K(0x1), 0x1), "");
    73       assert(rh.contains(as_K(0x1)), "");
    75       assert(!rh.put(as_K(0x1), 0x1), "");
    77       assert(rh.put(as_K(0x2), 0x2), "");
    78       assert(rh.put(as_K(0x3), 0x3), "");
    79       assert(rh.put(as_K(0x4), 0x4), "");
    80       assert(rh.put(as_K(0x5), 0x5), "");
    82       assert(!rh.remove(as_K(0x0)), "");
    83       rh.iterate(&et);
    85       assert(rh.remove(as_K(0x1)), "");
    86       rh.iterate(&et);
    88     }
    90     // We use keys with the low bits cleared since the default hash will do some shifting
    91     static void test_small_shifted() {
    92       EqualityTestIter et;
    93       ResourceHashtable<K, V, HASH, EQUALS, SIZE, ALLOC_TYPE, MEM_TYPE> rh;
    95       assert(!rh.contains(as_K(0x10)), "");
    97       assert(rh.put(as_K(0x10), 0x10), "");
    98       assert(rh.contains(as_K(0x10)), "");
   100       assert(!rh.put(as_K(0x10), 0x10), "");
   102       assert(rh.put(as_K(0x20), 0x20), "");
   103       assert(rh.put(as_K(0x30), 0x30), "");
   104       assert(rh.put(as_K(0x40), 0x40), "");
   105       assert(rh.put(as_K(0x50), 0x50), "");
   107       assert(!rh.remove(as_K(0x00)), "");
   109       assert(rh.remove(as_K(0x10)), "");
   111       rh.iterate(&et);
   112     }
   114     static void test(unsigned num_elements = SIZE) {
   115       EqualityTestIter et;
   116       ResourceHashtable<K, V, HASH, EQUALS, SIZE, ALLOC_TYPE, MEM_TYPE> rh;
   118       for (uintptr_t i = 0; i < num_elements; ++i) {
   119         assert(rh.put(as_K(i), i), "");
   120       }
   122       rh.iterate(&et);
   124       for (uintptr_t i = num_elements; i > 0; --i) {
   125         uintptr_t index = i - 1;
   126         assert(rh.remove(as_K(index)), "");
   127       }
   128       rh.iterate(&et);
   129       for (uintptr_t i = num_elements; i > 0; --i) {
   130         uintptr_t index = i - 1;
   131         assert(!rh.remove(as_K(index)), "");
   132       }
   133       rh.iterate(&et);
   134     }
   135   };
   137  public:
   138   static void run_tests() {
   139     {
   140       ResourceMark rm;
   141       Runner<>::test_small();
   142       Runner<>::test_small_shifted();
   143       Runner<>::test();
   144     }
   146     {
   147       ResourceMark rm;
   148       Runner<identity_hash>::test_small();
   149       Runner<identity_hash>::test_small_shifted();
   150       Runner<identity_hash>::test();
   151     }
   153     {
   154       ResourceMark rm;
   155       Runner<bad_hash>::test_small();
   156       Runner<bad_hash>::test_small_shifted();
   157       Runner<bad_hash>::test();
   158     }
   161     assert(Thread::current()->resource_area()->nesting() == 0, "this code depends on not having an active ResourceMark");
   162     // The following test calls will cause an assert if resource allocations occur since we don't have an active mark
   163     Runner<primitive_hash<K>, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test_small();
   164     Runner<primitive_hash<K>, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test_small_shifted();
   165     Runner<primitive_hash<K>, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test();
   167     Runner<bad_hash, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test_small();
   168     Runner<bad_hash, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test_small_shifted();
   169     Runner<bad_hash, primitive_equals<K>, 512, ResourceObj::C_HEAP>::test();
   171     Runner<identity_hash, primitive_equals<K>, 1, ResourceObj::C_HEAP>::test_small();
   172     Runner<identity_hash, primitive_equals<K>, 1, ResourceObj::C_HEAP>::test_small_shifted();
   173     Runner<identity_hash, primitive_equals<K>, 1, ResourceObj::C_HEAP>::test(512);
   174   }
   175 };
   177 void TestResourcehash_test() {
   178   TestResourceHashtable::run_tests();
   179 }
   181 #endif // not PRODUCT

mercurial