183 }
184
185 void ZMark::prepare_work() {
186 assert(_nworkers == _workers->nconcurrent(), "Invalid number of workers");
187
188 // Set number of active workers
189 _terminate.reset(_nworkers);
190
191 // Reset flush counters
192 _work_nproactiveflush = _work_nterminateflush = 0;
193 _work_terminateflush = true;
194 }
195
196 void ZMark::finish_work() {
197 // Accumulate proactive/terminate flush counters
198 _nproactiveflush += _work_nproactiveflush;
199 _nterminateflush += _work_nterminateflush;
200 }
201
202 bool ZMark::is_array(uintptr_t addr) const {
203 return ZOop::from_address(addr)->is_objArray();
204 }
205
206 void ZMark::push_partial_array(uintptr_t addr, size_t size, bool finalizable) {
207 assert(is_aligned(addr, ZMarkPartialArrayMinSize), "Address misaligned");
208 ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current());
209 ZMarkStripe* const stripe = _stripes.stripe_for_addr(addr);
210 const uintptr_t offset = ZAddress::offset(addr) >> ZMarkPartialArrayMinSizeShift;
211 const uintptr_t length = size / oopSize;
212 const ZMarkStackEntry entry(offset, length, finalizable);
213
214 log_develop_trace(gc, marking)("Array push partial: " PTR_FORMAT " (" SIZE_FORMAT "), stripe: " SIZE_FORMAT,
215 addr, size, _stripes.stripe_id(stripe));
216
217 stacks->push(&_allocator, &_stripes, stripe, entry, false /* publish */);
218 }
219
220 void ZMark::follow_small_array(uintptr_t addr, size_t size, bool finalizable) {
221 assert(size <= ZMarkPartialArrayMinSize, "Too large, should be split");
222 const size_t length = size / oopSize;
223
330
331 void ZMark::mark_and_follow(ZMarkCache* cache, ZMarkStackEntry entry) {
332 // Decode flags
333 const bool finalizable = entry.finalizable();
334 const bool partial_array = entry.partial_array();
335
336 if (partial_array) {
337 follow_partial_array(entry, finalizable);
338 return;
339 }
340
341 // Decode object address
342 const uintptr_t addr = entry.object_address();
343
344 if (!try_mark_object(cache, addr, finalizable)) {
345 // Already marked
346 return;
347 }
348
349 if (is_array(addr)) {
350 follow_array_object(objArrayOop(ZOop::from_address(addr)), finalizable);
351 } else {
352 follow_object(ZOop::from_address(addr), finalizable);
353 }
354 }
355
356 template <typename T>
357 bool ZMark::drain(ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks, ZMarkCache* cache, T* timeout) {
358 ZMarkStackEntry entry;
359
360 // Drain stripe stacks
361 while (stacks->pop(&_allocator, &_stripes, stripe, entry)) {
362 mark_and_follow(cache, entry);
363
364 // Check timeout
365 if (timeout->has_expired()) {
366 // Timeout
367 return false;
368 }
369 }
370
371 // Success
372 return true;
|
183 }
184
185 void ZMark::prepare_work() {
186 assert(_nworkers == _workers->nconcurrent(), "Invalid number of workers");
187
188 // Set number of active workers
189 _terminate.reset(_nworkers);
190
191 // Reset flush counters
192 _work_nproactiveflush = _work_nterminateflush = 0;
193 _work_terminateflush = true;
194 }
195
196 void ZMark::finish_work() {
197 // Accumulate proactive/terminate flush counters
198 _nproactiveflush += _work_nproactiveflush;
199 _nterminateflush += _work_nterminateflush;
200 }
201
202 bool ZMark::is_array(uintptr_t addr) const {
203 return ZOop::to_oop(addr)->is_objArray();
204 }
205
206 void ZMark::push_partial_array(uintptr_t addr, size_t size, bool finalizable) {
207 assert(is_aligned(addr, ZMarkPartialArrayMinSize), "Address misaligned");
208 ZMarkThreadLocalStacks* const stacks = ZThreadLocalData::stacks(Thread::current());
209 ZMarkStripe* const stripe = _stripes.stripe_for_addr(addr);
210 const uintptr_t offset = ZAddress::offset(addr) >> ZMarkPartialArrayMinSizeShift;
211 const uintptr_t length = size / oopSize;
212 const ZMarkStackEntry entry(offset, length, finalizable);
213
214 log_develop_trace(gc, marking)("Array push partial: " PTR_FORMAT " (" SIZE_FORMAT "), stripe: " SIZE_FORMAT,
215 addr, size, _stripes.stripe_id(stripe));
216
217 stacks->push(&_allocator, &_stripes, stripe, entry, false /* publish */);
218 }
219
220 void ZMark::follow_small_array(uintptr_t addr, size_t size, bool finalizable) {
221 assert(size <= ZMarkPartialArrayMinSize, "Too large, should be split");
222 const size_t length = size / oopSize;
223
330
331 void ZMark::mark_and_follow(ZMarkCache* cache, ZMarkStackEntry entry) {
332 // Decode flags
333 const bool finalizable = entry.finalizable();
334 const bool partial_array = entry.partial_array();
335
336 if (partial_array) {
337 follow_partial_array(entry, finalizable);
338 return;
339 }
340
341 // Decode object address
342 const uintptr_t addr = entry.object_address();
343
344 if (!try_mark_object(cache, addr, finalizable)) {
345 // Already marked
346 return;
347 }
348
349 if (is_array(addr)) {
350 follow_array_object(objArrayOop(ZOop::to_oop(addr)), finalizable);
351 } else {
352 follow_object(ZOop::to_oop(addr), finalizable);
353 }
354 }
355
356 template <typename T>
357 bool ZMark::drain(ZMarkStripe* stripe, ZMarkThreadLocalStacks* stacks, ZMarkCache* cache, T* timeout) {
358 ZMarkStackEntry entry;
359
360 // Drain stripe stacks
361 while (stacks->pop(&_allocator, &_stripes, stripe, entry)) {
362 mark_and_follow(cache, entry);
363
364 // Check timeout
365 if (timeout->has_expired()) {
366 // Timeout
367 return false;
368 }
369 }
370
371 // Success
372 return true;
|