67 // into cache pressure (which is already high during marking), and
68 // too many atomic updates. size_t/jint is too large, jbyte is too small.
69 jushort** _liveness_local;
70
71 private:
72 template <class T, bool COUNT_LIVENESS>
73 inline void do_task(SCMObjToScanQueue* q, T* cl, jushort* live_data, SCMTask* task);
74
75 template <class T>
76 inline void do_chunked_array_start(SCMObjToScanQueue* q, T* cl, oop array);
77
78 template <class T>
79 inline void do_chunked_array(SCMObjToScanQueue* q, T* cl, oop array, int chunk, int pow);
80
81 inline void count_liveness(jushort* live_data, oop obj);
82
83 // Actual mark loop with closures set up
84 template <class T, bool CANCELLABLE, bool DRAIN_SATB, bool COUNT_LIVENESS>
85 void mark_loop_work(T* cl, jushort* live_data, uint worker_id, ParallelTaskTerminator *t);
86
87 template <bool CANCELLABLE, bool DRAIN_SATB, bool COUNT_LIVENESS, bool CLASS_UNLOAD, bool UPDATE_REFS>
88 void mark_loop_prework(uint worker_id, ParallelTaskTerminator *terminator, ReferenceProcessor *rp);
89
90 // ------------------------ Currying dynamic arguments to template args ----------------------------
91
92 template <bool B1, bool B2, bool B3, bool B4>
93 void mark_loop_4(uint w, ParallelTaskTerminator* t, ReferenceProcessor* rp, bool b5) {
94 if (b5) {
95 mark_loop_prework<B1, B2, B3, B4, true>(w, t, rp);
96 } else {
97 mark_loop_prework<B1, B2, B3, B4, false>(w, t, rp);
98 }
99 };
100
101 template <bool B1, bool B2, bool B3>
102 void mark_loop_3(uint w, ParallelTaskTerminator* t, ReferenceProcessor* rp, bool b4, bool b5) {
103 if (b4) {
104 mark_loop_4<B1, B2, B3, true>(w, t, rp, b5);
105 } else {
106 mark_loop_4<B1, B2, B3, false>(w, t, rp, b5);
107 }
108 };
109
110 template <bool B1, bool B2>
111 void mark_loop_2(uint w, ParallelTaskTerminator* t, ReferenceProcessor* rp, bool b3, bool b4, bool b5) {
112 if (b3) {
113 mark_loop_3<B1, B2, true>(w, t, rp, b4, b5);
114 } else {
115 mark_loop_3<B1, B2, false>(w, t, rp, b4, b5);
116 }
117 };
118
119 template <bool B1>
120 void mark_loop_1(uint w, ParallelTaskTerminator* t, ReferenceProcessor* rp, bool b2, bool b3, bool b4, bool b5) {
121 if (b2) {
122 mark_loop_2<B1, true>(w, t, rp, b3, b4, b5);
123 } else {
124 mark_loop_2<B1, false>(w, t, rp, b3, b4, b5);
125 }
126 };
127
128 // ------------------------ END: Currying dynamic arguments to template args ----------------------------
129
130 public:
131 // We need to do this later when the heap is already created.
132 void initialize(uint workers);
133
134 void set_process_references(bool pr);
135 bool process_references() const;
136
137 void set_unload_classes(bool uc);
138 bool unload_classes() const;
139
140 bool claim_codecache();
141 void clear_claim_codecache();
142
143 template<class T, UpdateRefsMode UPDATE_REFS>
144 static inline void mark_through_ref(T* p, ShenandoahHeap* heap, SCMObjToScanQueue* q);
145
146 void mark_from_roots();
147
148 // Prepares unmarked root objects by marking them and putting
149 // them into the marking task queue.
150 void init_mark_roots();
151 void mark_roots();
152 void update_roots();
153 void final_update_roots();
154
155 void shared_finish_mark_from_roots(bool full_gc);
156 void finish_mark_from_roots();
157 // Those are only needed public because they're called from closures.
158
159 // Mark loop entry.
160 // Translates dynamic arguments to template parameters with progressive currying.
161 void mark_loop(uint worker_id, ParallelTaskTerminator* terminator, ReferenceProcessor *rp,
162 bool cancellable, bool drain_satb, bool count_liveness, bool class_unload, bool update_refs) {
163 if (cancellable) {
164 mark_loop_1<true>(worker_id, terminator, rp, drain_satb, count_liveness, class_unload, update_refs);
165 } else {
166 mark_loop_1<false>(worker_id, terminator, rp, drain_satb, count_liveness, class_unload, update_refs);
167 }
168 }
169
170 inline bool try_queue(SCMObjToScanQueue* q, SCMTask &task);
171
172 SCMObjToScanQueue* get_queue(uint worker_id);
173 void clear_queue(SCMObjToScanQueue *q);
174
175 inline bool try_draining_satb_buffer(SCMObjToScanQueue *q, SCMTask &task);
176 void drain_satb_buffers(uint worker_id, bool remark = false);
177 SCMObjToScanQueueSet* task_queues() { return _task_queues;}
178
179 jushort* get_liveness(uint worker_id);
180
181 void cancel();
182
183 private:
184
185 #ifdef ASSERT
186 void verify_roots();
|
67 // into cache pressure (which is already high during marking), and
68 // too many atomic updates. size_t/jint is too large, jbyte is too small.
69 jushort** _liveness_local;
70
71 private:
72 template <class T, bool COUNT_LIVENESS>
73 inline void do_task(SCMObjToScanQueue* q, T* cl, jushort* live_data, SCMTask* task);
74
75 template <class T>
76 inline void do_chunked_array_start(SCMObjToScanQueue* q, T* cl, oop array);
77
78 template <class T>
79 inline void do_chunked_array(SCMObjToScanQueue* q, T* cl, oop array, int chunk, int pow);
80
81 inline void count_liveness(jushort* live_data, oop obj);
82
83 // Actual mark loop with closures set up
84 template <class T, bool CANCELLABLE, bool DRAIN_SATB, bool COUNT_LIVENESS>
85 void mark_loop_work(T* cl, jushort* live_data, uint worker_id, ParallelTaskTerminator *t);
86
87 template <bool CANCELLABLE, bool DRAIN_SATB, bool COUNT_LIVENESS, bool CLASS_UNLOAD, bool UPDATE_REFS, bool UPDATE_MATRIX>
88 void mark_loop_prework(uint worker_id, ParallelTaskTerminator *terminator, ReferenceProcessor *rp);
89
90 // ------------------------ Currying dynamic arguments to template args ----------------------------
91
92 template <bool B1, bool B2, bool B3, bool B4, bool B5>
93 void mark_loop_5(uint w, ParallelTaskTerminator* t, ReferenceProcessor* rp, bool b6) {
94 if (b6) {
95 mark_loop_prework<B1, B2, B3, B4, B5, true>(w, t, rp);
96 } else {
97 mark_loop_prework<B1, B2, B3, B4, B5, false>(w, t, rp);
98 }
99 };
100
101 template <bool B1, bool B2, bool B3, bool B4>
102 void mark_loop_4(uint w, ParallelTaskTerminator* t, ReferenceProcessor* rp, bool b5, bool b6) {
103 if (b5) {
104 mark_loop_5<B1, B2, B3, B4, true>(w, t, rp, b6);
105 } else {
106 mark_loop_5<B1, B2, B3, B4, false>(w, t, rp, b6);
107 }
108 };
109
110 template <bool B1, bool B2, bool B3>
111 void mark_loop_3(uint w, ParallelTaskTerminator* t, ReferenceProcessor* rp, bool b4, bool b5, bool b6) {
112 if (b4) {
113 mark_loop_4<B1, B2, B3, true>(w, t, rp, b5, b6);
114 } else {
115 mark_loop_4<B1, B2, B3, false>(w, t, rp, b5, b6);
116 }
117 };
118
119 template <bool B1, bool B2>
120 void mark_loop_2(uint w, ParallelTaskTerminator* t, ReferenceProcessor* rp, bool b3, bool b4, bool b5, bool b6) {
121 if (b3) {
122 mark_loop_3<B1, B2, true>(w, t, rp, b4, b5, b6);
123 } else {
124 mark_loop_3<B1, B2, false>(w, t, rp, b4, b5, b6);
125 }
126 };
127
128 template <bool B1>
129 void mark_loop_1(uint w, ParallelTaskTerminator* t, ReferenceProcessor* rp, bool b2, bool b3, bool b4, bool b5, bool b6) {
130 if (b2) {
131 mark_loop_2<B1, true>(w, t, rp, b3, b4, b5, b6);
132 } else {
133 mark_loop_2<B1, false>(w, t, rp, b3, b4, b5, b6);
134 }
135 };
136
137 // ------------------------ END: Currying dynamic arguments to template args ----------------------------
138
139 public:
140 // We need to do this later when the heap is already created.
141 void initialize(uint workers);
142
143 void set_process_references(bool pr);
144 bool process_references() const;
145
146 void set_unload_classes(bool uc);
147 bool unload_classes() const;
148
149 bool claim_codecache();
150 void clear_claim_codecache();
151
152 template<class T, UpdateRefsMode UPDATE_REFS, bool UPDATE_MATRIX>
153 static inline void mark_through_ref(T* p, ShenandoahHeap* heap, SCMObjToScanQueue* q, ShenandoahConnectionMatrix* conn_matrix);
154
155 void mark_from_roots();
156
157 // Prepares unmarked root objects by marking them and putting
158 // them into the marking task queue.
159 void init_mark_roots();
160 void mark_roots();
161 void update_roots();
162 void final_update_roots();
163
164 void shared_finish_mark_from_roots(bool full_gc);
165 void finish_mark_from_roots();
166 // Those are only needed public because they're called from closures.
167
168 // Mark loop entry.
169 // Translates dynamic arguments to template parameters with progressive currying.
170 void mark_loop(uint worker_id, ParallelTaskTerminator* terminator, ReferenceProcessor *rp,
171 bool cancellable, bool drain_satb, bool count_liveness, bool class_unload,
172 bool update_refs, bool update_matrix) {
173 if (cancellable) {
174 mark_loop_1<true>(worker_id, terminator, rp, drain_satb, count_liveness, class_unload, update_refs, update_matrix);
175 } else {
176 mark_loop_1<false>(worker_id, terminator, rp, drain_satb, count_liveness, class_unload, update_refs, update_matrix);
177 }
178 }
179
180 inline bool try_queue(SCMObjToScanQueue* q, SCMTask &task);
181
182 SCMObjToScanQueue* get_queue(uint worker_id);
183 void clear_queue(SCMObjToScanQueue *q);
184
185 inline bool try_draining_satb_buffer(SCMObjToScanQueue *q, SCMTask &task);
186 void drain_satb_buffers(uint worker_id, bool remark = false);
187 SCMObjToScanQueueSet* task_queues() { return _task_queues;}
188
189 jushort* get_liveness(uint worker_id);
190
191 void cancel();
192
193 private:
194
195 #ifdef ASSERT
196 void verify_roots();
|