< prev index next >

src/hotspot/share/gc/shared/oopStorageParState.hpp

v2

8211718: Supporting multiple concurrent OopStorage iterators

13  *                                                                                                                                   
14  * You should have received a copy of the GNU General Public License version                                                         
15  * 2 along with this work; if not, write to the Free Software Foundation,                                                            
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.                                                                     
17  *                                                                                                                                   
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA                                                           
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 // Parallel iteration is for the exclusive use of the GC.  Other iteration                                                           
34 // clients must use serial iteration.                                                                                                
35 //                                                                                                                                   
36 // Concurrent Iteration                                                                                                              
37 //                                                                                                                                   
38 // Iteration involves the _active_array (an ActiveArray), which contains all                                                         
39 // of the blocks owned by a storage object.                                                                                          
40 //                                                                                                                                   
41 // At most one concurrent ParState can exist at a time for a given storage                                                           
42 // object.                                                                                                                           
43 //                                                                                                                                   
44 // A concurrent ParState sets the associated storage's                                                                               
45 // _concurrent_iteration_active flag true when the state is constructed, and                                                         
46 // sets it false when the state is destroyed.  These assignments are made with                                                       
47 // _active_mutex locked.  Meanwhile, empty block deletion is not done while                                                          
48 // _concurrent_iteration_active is true.  The flag check and the dependent                                                           
49 // removal of a block from the _active_array is performed with _active_mutex                                                         
50 // locked.  This prevents concurrent iteration and empty block deletion from                                                         
51 // interfering with with each other.                                                                                                 
52 //                                                                                                                                   
53 // Both allocate() and delete_empty_blocks_concurrent() lock the                                                                     
54 // _allocation_mutex while performing their respective list and array                                                                
55 // manipulations, preventing them from interfering with each other.                                                                  
56 //                                                                                                                                   
57 // When allocate() creates a new block, it is added to the end of the                                                                
58 // _active_array.  Then _active_array's _block_count is incremented to account                                                       
59 // for the new block.  When concurrent iteration is started (by a parallel                                                           
60 // worker thread calling the state's iterate() function), the current                                                                
61 // _active_array and its _block_count are captured for use by the iteration,                                                         
62 // with iteration processing all blocks in that array up to that block count.                                                        
63 //                                                                                                                                   
64 // As a result, the sequence over which concurrent iteration operates is                                                             
65 // stable.  However, once the iteration is started, later allocations may add                                                        
66 // blocks to the end of the array that won't be examined by the iteration.                                                           
67 // An allocation may even require expansion of the array, so the iteration is                                                        
68 // no longer processing the current array, but rather the previous one.                                                              
69 // And while the sequence is stable, concurrent allocate() and release()                                                             
70 // operations may change the set of allocated entries in a block at any time                                                         
71 // during the iteration.                                                                                                             
72 //                                                                                                                                   
73 // As a result, a concurrent iteration handler must accept that some                                                                 
74 // allocations and releases that occur after the iteration started will not be                                                       
75 // seen by the iteration.  Further, some may overlap examination by the                                                              
76 // iteration.  To help with this, allocate() and release() have an invariant                                                         
77 // that an entry's value must be NULL when it is not in use.                                                                         
78 //                                                                                                                                   
79 // An in-progress delete_empty_blocks_concurrent() operation can contend with                                                        
80 // the start of a concurrent iteration over the _active_mutex.  Since both are                                                       
81 // under GC control, that potential contention can be eliminated by never                                                            
82 // scheduling both operations to run at the same time.                                                                               
83 //                                                                                                                                   
84 // ParState<concurrent, is_const>                                                                                                    
85 //   concurrent must be true if iteration is concurrent with the                                                                     
86 //   mutator, false if iteration is at a safepoint.                                                                                  
87 //                                                                                                                                   
88 //   is_const must be true if the iteration is over a constant storage                                                               
89 //   object, false if the iteration may modify the storage object.                                                                   
90 //                                                                                                                                   
91 // ParState([const] OopStorage* storage)                                                                                             
92 //   Construct an object for managing an iteration over storage.  For a                                                              
93 //   concurrent ParState, empty block deletion for the associated storage                                                            
94 //   is inhibited for the life of the ParState.  There can be no more                                                                
95 //   than one live concurrent ParState at a time for a given storage object.                                                         
96 //                                                                                                                                   
97 // template<typename F> void iterate(F f)                                                                                            
98 //   Repeatedly claims a block from the associated storage that has                                                                  
99 //   not been processed by this iteration (possibly by other threads),                                                               
100 //   and applies f to each entry in the claimed block. Assume p is of                                                                
101 //   type const oop* or oop*, according to is_const. Then f(p) must be                                                               
102 //   a valid expression whose value is ignored.  Concurrent uses must                                                                
103 //   be prepared for an entry's value to change at any time, due to                                                                  
104 //   mutator activity.                                                                                                               
105 //                                                                                                                                   
106 // template<typename Closure> void oops_do(Closure* cl)                                                                              
107 //   Wrapper around iterate, providing an adaptation layer allowing                                                                  
108 //   the use of OopClosures and similar objects for iteration.  Assume                                                               
109 //   p is of type const oop* or oop*, according to is_const.  Then                                                                   
110 //   cl->do_oop(p) must be a valid expression whose value is ignored.                                                                
111 //   Concurrent uses must be prepared for the entry's value to change                                                                
112 //   at any time, due to mutator activity.                                                                                           
113 //                                                                                                                                   
114 // Optional operations, provided only if !concurrent && !is_const.                                                                   

13  *
14  * You should have received a copy of the GNU General Public License version
15  * 2 along with this work; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
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 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
62 // no longer processing the current array, but rather the previous one.
63 // And while the sequence is stable, concurrent allocate() and release()
64 // operations may change the set of allocated entries in a block at any time
65 // during the iteration.
66 //
67 // As a result, a concurrent iteration handler must accept that some
68 // allocations and releases that occur after the iteration started will not be
69 // seen by the iteration.  Further, some may overlap examination by the
70 // iteration.  To help with this, allocate() and release() have an invariant
71 // that an entry's value must be NULL when it is not in use.
72 //
73 // An in-progress delete_empty_blocks_concurrent() operation can contend with
74 // the start of a concurrent iteration over the _active_mutex.  Since both are
75 // under GC control, that potential contention can be eliminated by never
76 // scheduling both operations to run at the same time.
77 //
78 // ParState<concurrent, is_const>
79 //   concurrent must be true if iteration may be concurrent with the
80 //   mutators.
81 //
82 //   is_const must be true if the iteration is over a constant storage
83 //   object, false if the iteration may modify the storage object.
84 //
85 // ParState([const] OopStorage* storage)
86 //   Construct an object for managing an iteration over storage.  For a
87 //   concurrent ParState, empty block deletion for the associated storage
88 //   is inhibited for the life of the ParState.

89 //
90 // template<typename F> void iterate(F f)
91 //   Repeatedly claims a block from the associated storage that has
92 //   not been processed by this iteration (possibly by other threads),
93 //   and applies f to each entry in the claimed block. Assume p is of
94 //   type const oop* or oop*, according to is_const. Then f(p) must be
95 //   a valid expression whose value is ignored.  Concurrent uses must
96 //   be prepared for an entry's value to change at any time, due to
97 //   mutator activity.
98 //
99 // template<typename Closure> void oops_do(Closure* cl)
100 //   Wrapper around iterate, providing an adaptation layer allowing
101 //   the use of OopClosures and similar objects for iteration.  Assume
102 //   p is of type const oop* or oop*, according to is_const.  Then
103 //   cl->do_oop(p) must be a valid expression whose value is ignored.
104 //   Concurrent uses must be prepared for the entry's value to change
105 //   at any time, due to mutator activity.
106 //
107 // Optional operations, provided only if !concurrent && !is_const.

134 //   is convertible to bool.                                                                                                         
135 //                                                                                                                                   
136 //   If *p == NULL then neither is_alive nor cl will be invoked for p.                                                               
137 //   If is_alive->do_object_b(*p) is false, then cl will not be                                                                      
138 //   invoked on p.                                                                                                                   
139 
140 class OopStorage::BasicParState {                                                                                                    
141   const OopStorage* _storage;                                                                                                        
142   ActiveArray* _active_array;                                                                                                        
143   size_t _block_count;                                                                                                               
144   volatile size_t _next_block;                                                                                                       
145   uint _estimated_thread_count;                                                                                                      
146   bool _concurrent;                                                                                                                  
147 
148   // Noncopyable.                                                                                                                    
149   BasicParState(const BasicParState&);                                                                                               
150   BasicParState& operator=(const BasicParState&);                                                                                    
151 
152   struct IterationData;                                                                                                              
153 
154   void update_iteration_state(bool value);                                                                                           
155   bool claim_next_segment(IterationData* data);                                                                                      
156   bool finish_iteration(const IterationData* data) const;                                                                            
157 
158   // Wrapper for iteration handler; ignore handler result and return true.                                                           
159   template<typename F> class AlwaysTrueFn;                                                                                           
160 
161 public:                                                                                                                              
162   BasicParState(const OopStorage* storage,                                                                                           
163                 uint estimated_thread_count,                                                                                         
164                 bool concurrent);                                                                                                    
165   ~BasicParState();                                                                                                                  
166 
167   template<bool is_const, typename F> void iterate(F f);                                                                             
168 
169   static uint default_estimated_thread_count(bool concurrent);                                                                       
170 };                                                                                                                                   
171 
172 template<bool concurrent, bool is_const>                                                                                             
173 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 {
< prev index next >