1 /*
   2  * Copyright (c) 2019, 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  */
  24 
  25 #ifndef SHARE_GC_SHARED_OOPSTORAGESET_HPP
  26 #define SHARE_GC_SHARED_OOPSTORAGESET_HPP
  27 
  28 #include "memory/allocation.hpp"
  29 #include "utilities/debug.hpp"
  30 #include "utilities/globalDefinitions.hpp"
  31 #include "utilities/macros.hpp"
  32 
  33 class OopStorage;
  34 
  35 class OopStorageSet : public AllStatic {
  36 private:
  37   friend void oopstorage_init();
  38 
  39   enum {
  40     singular_index,             // For singular iterator.
  41 
  42     all_start,
  43 
  44     // Strong
  45     strong_start = all_start,
  46     jni_global_index = strong_start,
  47     vm_global_index,
  48     strong_end,
  49 
  50     // Weak
  51     weak_start = strong_end,
  52     jni_weak_index = weak_start,
  53     vm_weak_index,
  54     string_table_weak_index,
  55     resolved_method_table_weak_index,
  56     weak_end,
  57 
  58     all_end = weak_end
  59   };
  60 
  61   static OopStorage* storages[all_end];
  62 
  63   static void verify_initialized(uint index) NOT_DEBUG_RETURN;
  64 
  65   static OopStorage* storage(uint index) {
  66     verify_initialized(index);
  67     return storages[index];
  68   }
  69 
  70   static void initialize();
  71 
  72 public:
  73   class Iterator;
  74 
  75   static const uint strong_count = (strong_end - strong_start);
  76   static const uint weak_count = (weak_end - weak_start);
  77   static const uint all_count = (all_end - all_start);
  78 
  79   static Iterator strong_iterator();
  80   static Iterator weak_iterator();
  81   static Iterator all_iterator();
  82 
  83   // Strong
  84   static OopStorage* jni_global() { return storage(jni_global_index); }
  85   static OopStorage* vm_global()  { return storage(vm_global_index); }
  86 
  87   // Weak
  88   static OopStorage* jni_weak()   { return storage(jni_weak_index); }
  89   static OopStorage* vm_weak()    { return storage(vm_weak_index); }
  90 
  91   static OopStorage* string_table_weak() {
  92     return storage(string_table_weak_index);
  93   }
  94 
  95   static OopStorage* resolved_method_table_weak() {
  96     return storage(resolved_method_table_weak_index);
  97   }
  98 
  99   template <typename Closure>
 100   static void strong_oops_do(Closure* cl);
 101 };
 102 
 103 class OopStorageSet::Iterator {
 104   friend class OopStorageSet;
 105 
 106   enum Category { singular, strong, weak, all };
 107 
 108   uint _index;
 109   uint _limit;
 110   DEBUG_ONLY(Category _category;)
 111 
 112   Iterator(uint index, uint limit, Category category) :
 113     _index(index), _limit(limit) DEBUG_ONLY(COMMA _category(category)) {}
 114 
 115   void verify_nonsingular() const NOT_DEBUG_RETURN;
 116   void verify_category_match(const Iterator& other) const NOT_DEBUG_RETURN;
 117   void verify_dereferenceable() const NOT_DEBUG_RETURN;
 118 
 119 public:
 120   // Construct a singular iterator for later assignment.  The only valid
 121   // operations are destruction and assignment.
 122   Iterator() :
 123     _index(singular_index),
 124     _limit(singular_index)
 125     DEBUG_ONLY(COMMA _category(singular)) {}
 126 
 127   bool is_end() const {
 128     verify_nonsingular();
 129     return _index == _limit;
 130   }
 131 
 132   bool operator==(const Iterator& other) const {
 133     verify_category_match(other);
 134     return _index == other._index;
 135   }
 136 
 137   bool operator!=(const Iterator& other) const {
 138     return !operator==(other);
 139   }
 140 
 141   OopStorage* operator*() const {
 142     verify_dereferenceable();
 143     return storage(_index);
 144   }
 145 
 146   OopStorage* operator->() const {
 147     return operator*();
 148   }
 149 
 150   Iterator& operator++() {
 151     verify_dereferenceable();
 152     ++_index;
 153     return *this;
 154   }
 155 
 156   Iterator operator++(int) {
 157     Iterator result = *this;
 158     operator++();
 159     return result;
 160   }
 161 
 162   Iterator begin() const {
 163     verify_nonsingular();
 164     return *this;
 165   }
 166 
 167   Iterator end() const {
 168     verify_nonsingular();
 169     Iterator result = *this;
 170     result._index = _limit;
 171     return result;
 172   }
 173 };
 174 
 175 inline OopStorageSet::Iterator OopStorageSet::strong_iterator() {
 176   return Iterator(strong_start, strong_end, Iterator::strong);
 177 }
 178 
 179 inline OopStorageSet::Iterator OopStorageSet::weak_iterator() {
 180   return Iterator(weak_start, weak_end, Iterator::weak);
 181 }
 182 
 183 inline OopStorageSet::Iterator OopStorageSet::all_iterator() {
 184   return Iterator(all_start, all_end, Iterator::all);
 185 }
 186 
 187 #endif // SHARE_GC_SHARED_OOPSTORAGESET_HPP