19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #ifndef SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
25 #define SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
26
27 #include "gc/shared/oopStorage.hpp"
28 #include "utilities/macros.hpp"
29
30 //////////////////////////////////////////////////////////////////////////////
31 // Support for parallel and optionally concurrent state iteration.
32 //
33 // Concurrent Iteration
34 //
35 // Iteration involves the _active_array (an ActiveArray), which contains all
36 // of the blocks owned by a storage object.
37 //
38 // A concurrent ParState increments the associated storage's
39 // _concurrent_iteration_active count when the state is constructed, and
40 // decrements it when the state is destroyed. These assignments are made with
41 // _active_mutex locked. Meanwhile, empty block deletion is not done while
42 // _concurrent_iteration_active is non-zero. The counter check and the dependent
43 // removal of a block from the _active_array is performed with _active_mutex
44 // locked. This prevents concurrent iteration and empty block deletion from
45 // interfering with with each other.
46 //
47 // Both allocate() and delete_empty_blocks_concurrent() lock the
48 // _allocation_mutex while performing their respective list and array
49 // manipulations, preventing them from interfering with each other.
50 //
51 // When allocate() creates a new block, it is added to the end of the
52 // _active_array. Then _active_array's _block_count is incremented to account
53 // for the new block. When concurrent iteration is started (by a parallel
54 // worker thread calling the state's iterate() function), the current
55 // _active_array and its _block_count are captured for use by the iteration,
56 // with iteration processing all blocks in that array up to that block count.
57 //
58 // As a result, the sequence over which concurrent iteration operates is
59 // stable. However, once the iteration is started, later allocations may add
60 // blocks to the end of the array that won't be examined by the iteration.
61 // An allocation may even require expansion of the array, so the iteration is
|
19 * or visit www.oracle.com if you need additional information or have any
20 * questions.
21 *
22 */
23
24 #ifndef SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
25 #define SHARE_GC_SHARED_OOPSTORAGEPARSTATE_HPP
26
27 #include "gc/shared/oopStorage.hpp"
28 #include "utilities/macros.hpp"
29
30 //////////////////////////////////////////////////////////////////////////////
31 // Support for parallel and optionally concurrent state iteration.
32 //
33 // Concurrent Iteration
34 //
35 // Iteration involves the _active_array (an ActiveArray), which contains all
36 // of the blocks owned by a storage object.
37 //
38 // A concurrent ParState increments the associated storage's
39 // _concurrent_iteration_count when the state is constructed, and
40 // decrements it when the state is destroyed. These assignments are made with
41 // _active_mutex locked. Meanwhile, empty block deletion is not done while
42 // _concurrent_iteration_count is non-zero. The counter check and the dependent
43 // removal of a block from the _active_array is performed with _active_mutex
44 // locked. This prevents concurrent iteration and empty block deletion from
45 // interfering with with each other.
46 //
47 // Both allocate() and delete_empty_blocks_concurrent() lock the
48 // _allocation_mutex while performing their respective list and array
49 // manipulations, preventing them from interfering with each other.
50 //
51 // When allocate() creates a new block, it is added to the end of the
52 // _active_array. Then _active_array's _block_count is incremented to account
53 // for the new block. When concurrent iteration is started (by a parallel
54 // worker thread calling the state's iterate() function), the current
55 // _active_array and its _block_count are captured for use by the iteration,
56 // with iteration processing all blocks in that array up to that block count.
57 //
58 // As a result, the sequence over which concurrent iteration operates is
59 // stable. However, once the iteration is started, later allocations may add
60 // blocks to the end of the array that won't be examined by the iteration.
61 // An allocation may even require expansion of the array, so the iteration is
|
127 // is convertible to bool.
128 //
129 // If *p == NULL then neither is_alive nor cl will be invoked for p.
130 // If is_alive->do_object_b(*p) is false, then cl will not be
131 // invoked on p.
132
133 class OopStorage::BasicParState {
134 const OopStorage* _storage;
135 ActiveArray* _active_array;
136 size_t _block_count;
137 volatile size_t _next_block;
138 uint _estimated_thread_count;
139 bool _concurrent;
140
141 // Noncopyable.
142 BasicParState(const BasicParState&);
143 BasicParState& operator=(const BasicParState&);
144
145 struct IterationData;
146
147 void update_iteration_state(int value);
148 bool claim_next_segment(IterationData* data);
149 bool finish_iteration(const IterationData* data) const;
150
151 // Wrapper for iteration handler; ignore handler result and return true.
152 template<typename F> class AlwaysTrueFn;
153
154 public:
155 BasicParState(const OopStorage* storage,
156 uint estimated_thread_count,
157 bool concurrent);
158 ~BasicParState();
159
160 template<bool is_const, typename F> void iterate(F f);
161
162 static uint default_estimated_thread_count(bool concurrent);
163 };
164
165 template<bool concurrent, bool is_const>
166 class OopStorage::ParState {
|
127 // is convertible to bool.
128 //
129 // If *p == NULL then neither is_alive nor cl will be invoked for p.
130 // If is_alive->do_object_b(*p) is false, then cl will not be
131 // invoked on p.
132
133 class OopStorage::BasicParState {
134 const OopStorage* _storage;
135 ActiveArray* _active_array;
136 size_t _block_count;
137 volatile size_t _next_block;
138 uint _estimated_thread_count;
139 bool _concurrent;
140
141 // Noncopyable.
142 BasicParState(const BasicParState&);
143 BasicParState& operator=(const BasicParState&);
144
145 struct IterationData;
146
147 void update_concurrent_iteration_count(int value);
148 bool claim_next_segment(IterationData* data);
149 bool finish_iteration(const IterationData* data) const;
150
151 // Wrapper for iteration handler; ignore handler result and return true.
152 template<typename F> class AlwaysTrueFn;
153
154 public:
155 BasicParState(const OopStorage* storage,
156 uint estimated_thread_count,
157 bool concurrent);
158 ~BasicParState();
159
160 template<bool is_const, typename F> void iterate(F f);
161
162 static uint default_estimated_thread_count(bool concurrent);
163 };
164
165 template<bool concurrent, bool is_const>
166 class OopStorage::ParState {
|