1 /*
  2  * Copyright (c) 2018, 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_WEAKPROCESSORPHASES_HPP
 26 #define SHARE_GC_SHARED_WEAKPROCESSORPHASES_HPP
 27 
 28 #include "gc/shared/oopStorageSet.hpp"
 29 #include "memory/allocation.hpp"
 30 #include "utilities/globalDefinitions.hpp"
 31 #include "utilities/macros.hpp"
 32 
 33 class BoolObjectClosure;
 34 class OopClosure;
 35 class OopStorage;
 36 
 37 class WeakProcessorPhases : AllStatic {
 38 public:
 39   class Iterator;
 40 
 41   typedef void (*Processor)(BoolObjectClosure*, OopClosure*);
 42 
 43   enum Phase {
 44     // Serial phases.
 45     JVMTI_ONLY(jvmti JFR_ONLY(COMMA))
 46     JFR_ONLY(jfr)
 47 
 48     // Additional implicit phase values follow for oopstorages.
 49   };
 50 
 51   static const uint serial_phase_start = 0;
 52   static const uint serial_phase_count = 0 JVMTI_ONLY(+ 1) JFR_ONLY(+ 1);
 53   static const uint oopstorage_phase_start = serial_phase_count;
 54   static const uint oopstorage_phase_count = OopStorageSet::weak_count;
 55   static const uint phase_count = serial_phase_count + oopstorage_phase_count;
 56 
 57   // Precondition: value < serial_phase_count
 58   static Phase serial_phase(uint value);
 59 
 60   // Precondition: value < oopstorage_phase_count
 61   static Phase oopstorage_phase(uint value);
 62 
 63   // Indexes relative to the corresponding phase_start constant.
 64   // Precondition: is_serial(phase) or is_oopstorage(phase) accordingly
 65   static uint serial_index(Phase phase);
 66   static uint oopstorage_index(Phase phase);
 67 
 68   static bool is_serial(Phase phase);
 69   static bool is_oopstorage(Phase phase);
 70 
 71   static Iterator serial_iterator();
 72   static Iterator oopstorage_iterator();
 73 
 74   // Precondition: is_serial(phase)
 75   static const char* description(Phase phase);
 76 
 77   // Precondition: is_serial(phase)
 78   static Processor processor(Phase phase);
 79 };
 80 
 81 typedef WeakProcessorPhases::Phase WeakProcessorPhase;
 82 
 83 class WeakProcessorPhases::Iterator {
 84   friend class WeakProcessorPhases;
 85 
 86   uint _index;
 87   uint _limit;
 88 
 89   Iterator(uint index, uint limit) : _index(index), _limit(limit) {}
 90 
 91   static const uint singular_value = UINT_MAX;
 92   void verify_nonsingular() const NOT_DEBUG_RETURN;
 93   void verify_category_match(const Iterator& other) const NOT_DEBUG_RETURN;
 94   void verify_dereferenceable() const NOT_DEBUG_RETURN;
 95 
 96 public:
 97   // Construct a singular iterator for later assignment.  The only valid
 98   // operations are destruction and assignment.
 99   Iterator() : _index(singular_value), _limit(singular_value) {}
100 
101   bool is_end() const {
102     verify_nonsingular();
103     return _index == _limit;
104   }
105 
106   bool operator==(const Iterator& other) const {
107     verify_category_match(other);
108     return _index == other._index;
109   }
110 
111   bool operator!=(const Iterator& other) const {
112     return !operator==(other);
113   }
114 
115   Phase operator*() const {
116     verify_dereferenceable();
117     return static_cast<Phase>(_index);
118   }
119 
120   // Phase doesn't have members, so no operator->().
121 
122   Iterator& operator++() {
123     verify_dereferenceable();
124     ++_index;
125     return *this;
126   }
127 
128   Iterator operator++(int) {
129     verify_dereferenceable();
130     return Iterator(_index++, _limit);
131   }
132 
133   Iterator begin() const {
134     verify_nonsingular();
135     return *this;
136   }
137 
138   Iterator end() const {
139     verify_nonsingular();
140     return Iterator(_limit, _limit);
141   }
142 };
143 
144 inline WeakProcessorPhases::Iterator WeakProcessorPhases::serial_iterator() {
145   return Iterator(serial_phase_start, serial_phase_start + serial_phase_count);
146 }
147 
148 inline WeakProcessorPhases::Iterator WeakProcessorPhases::oopstorage_iterator() {
149   return Iterator(oopstorage_phase_start, oopstorage_phase_start + oopstorage_phase_count);
150 }
151 
152 #endif // SHARE_GC_SHARED_WEAKPROCESSORPHASES_HPP