28 #include "memory/allocation.hpp" |
28 #include "memory/allocation.hpp" |
29 #include "utilities/globalDefinitions.hpp" |
29 #include "utilities/globalDefinitions.hpp" |
30 |
30 |
31 // Forward decl |
31 // Forward decl |
32 class CardTableEntryClosure; |
32 class CardTableEntryClosure; |
|
33 class G1ConcurrentRefine; |
33 class G1ConcurrentRefineThread; |
34 class G1ConcurrentRefineThread; |
34 class outputStream; |
35 class outputStream; |
35 class ThreadClosure; |
36 class ThreadClosure; |
36 |
37 |
|
38 // Helper class for refinement thread management. Used to start, stop and |
|
39 // iterate over them. |
|
40 class G1ConcurrentRefineThreadControl VALUE_OBJ_CLASS_SPEC { |
|
41 G1ConcurrentRefine* _cr; |
|
42 |
|
43 G1ConcurrentRefineThread** _threads; |
|
44 uint _num_max_threads; |
|
45 |
|
46 // Create the refinement thread for the given worker id. |
|
47 // If initializing is true, ignore InjectGCWorkerCreationFailure. |
|
48 G1ConcurrentRefineThread* create_refinement_thread(uint worker_id, bool initializing); |
|
49 public: |
|
50 G1ConcurrentRefineThreadControl(); |
|
51 ~G1ConcurrentRefineThreadControl(); |
|
52 |
|
53 jint initialize(G1ConcurrentRefine* cr, uint num_max_threads); |
|
54 |
|
55 // If there is a "successor" thread that can be activated given the current id, |
|
56 // activate it. |
|
57 void maybe_activate_next(uint cur_worker_id); |
|
58 |
|
59 void print_on(outputStream* st) const; |
|
60 void worker_threads_do(ThreadClosure* tc); |
|
61 void stop(); |
|
62 }; |
|
63 |
|
64 // Controls refinement threads and their activation based on the number of completed |
|
65 // buffers currently available in the global dirty card queue. |
|
66 // Refinement threads pick work from the queue based on these thresholds. They are activated |
|
67 // gradually based on the amount of work to do. |
|
68 // Refinement thread n activates thread n+1 if the instance of this class determines there |
|
69 // is enough work available. Threads deactivate themselves if the current amount of |
|
70 // completed buffers falls below their individual threshold. |
37 class G1ConcurrentRefine : public CHeapObj<mtGC> { |
71 class G1ConcurrentRefine : public CHeapObj<mtGC> { |
38 G1ConcurrentRefineThread** _threads; |
72 G1ConcurrentRefineThreadControl _thread_control; |
39 uint _n_worker_threads; |
73 /* |
40 /* |
74 * The value of the completed dirty card queue length falls into one of 3 zones: |
41 * The value of the update buffer queue length falls into one of 3 zones: |
75 * green, yellow, red. If the value is in [0, green) nothing is |
42 * green, yellow, red. If the value is in [0, green) nothing is |
76 * done, the buffers are left unprocessed to enable the caching effect of the |
43 * done, the buffers are left unprocessed to enable the caching effect of the |
77 * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement |
44 * dirtied cards. In the yellow zone [green, yellow) the concurrent refinement |
78 * threads are gradually activated. In [yellow, red) all threads are |
45 * threads are gradually activated. In [yellow, red) all threads are |
79 * running. If the length becomes red (max queue length) the mutators start |
46 * running. If the length becomes red (max queue length) the mutators start |
80 * processing the buffers. |
47 * processing the buffers. |
81 * |
48 * |
82 * There are some interesting cases (when G1UseAdaptiveConcRefinement |
49 * There are some interesting cases (when G1UseAdaptiveConcRefinement |
83 * is turned off): |
50 * is turned off): |
84 * 1) green = yellow = red = 0. In this case the mutator will process all |
51 * 1) green = yellow = red = 0. In this case the mutator will process all |
85 * buffers. Except for those that are created by the deferred updates |
52 * buffers. Except for those that are created by the deferred updates |
86 * machinery during a collection. |
53 * machinery during a collection. |
87 * 2) green = 0. Means no caching. Can be a good way to minimize the |
54 * 2) green = 0. Means no caching. Can be a good way to minimize the |
88 * amount of time spent updating remembered sets during a collection. |
55 * amount of time spent updating rsets during a collection. |
89 */ |
56 */ |
|
57 size_t _green_zone; |
90 size_t _green_zone; |
58 size_t _yellow_zone; |
91 size_t _yellow_zone; |
59 size_t _red_zone; |
92 size_t _red_zone; |
60 size_t _min_yellow_zone_size; |
93 size_t _min_yellow_zone_size; |
61 |
94 |
67 // Update green/yellow/red zone values based on how well goals are being met. |
100 // Update green/yellow/red zone values based on how well goals are being met. |
68 void update_zones(double update_rs_time, |
101 void update_zones(double update_rs_time, |
69 size_t update_rs_processed_buffers, |
102 size_t update_rs_processed_buffers, |
70 double goal_ms); |
103 double goal_ms); |
71 |
104 |
72 // Update thread thresholds to account for updated zone values. |
105 static uint worker_id_offset(); |
73 void update_thread_thresholds(); |
106 void maybe_activate_more_threads(uint worker_id, size_t num_cur_buffers); |
74 |
107 |
75 public: |
108 jint initialize(); |
|
109 public: |
76 ~G1ConcurrentRefine(); |
110 ~G1ConcurrentRefine(); |
77 |
111 |
78 // Returns a G1ConcurrentRefine instance if succeeded to create/initialize G1ConcurrentRefine and G1ConcurrentRefineThreads. |
112 // Returns a G1ConcurrentRefine instance if succeeded to create/initialize the |
79 // Otherwise, returns NULL with error code. |
113 // G1ConcurrentRefine instance. Otherwise, returns NULL with error code. |
80 static G1ConcurrentRefine* create(jint* ecode); |
114 static G1ConcurrentRefine* create(jint* ecode); |
81 |
115 |
82 void stop(); |
116 void stop(); |
83 |
117 |
|
118 // Adjust refinement thresholds based on work done during the pause and the goal time. |
84 void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms); |
119 void adjust(double update_rs_time, size_t update_rs_processed_buffers, double goal_ms); |
|
120 |
|
121 size_t activation_threshold(uint worker_id) const; |
|
122 size_t deactivation_threshold(uint worker_id) const; |
|
123 // Perform a single refinement step. Called by the refinement threads when woken up. |
|
124 bool do_refinement_step(uint worker_id); |
85 |
125 |
86 // Iterate over all concurrent refinement threads applying the given closure. |
126 // Iterate over all concurrent refinement threads applying the given closure. |
87 void threads_do(ThreadClosure *tc); |
127 void threads_do(ThreadClosure *tc); |
88 |
128 |
89 static uint thread_num(); |
129 // Maximum number of refinement threads. |
|
130 static uint max_num_threads(); |
90 |
131 |
91 void print_threads_on(outputStream* st) const; |
132 void print_threads_on(outputStream* st) const; |
92 |
133 |
93 size_t green_zone() const { return _green_zone; } |
134 size_t green_zone() const { return _green_zone; } |
94 size_t yellow_zone() const { return _yellow_zone; } |
135 size_t yellow_zone() const { return _yellow_zone; } |