251 if (unflushed_size == 0) { |
252 if (unflushed_size == 0) { |
252 buffer->concurrent_reinitialization(); |
253 buffer->concurrent_reinitialization(); |
253 assert(buffer->empty(), "invariant"); |
254 assert(buffer->empty(), "invariant"); |
254 return true; |
255 return true; |
255 } |
256 } |
|
257 |
|
258 if (buffer->excluded()) { |
|
259 const bool thread_is_excluded = thread->jfr_thread_local()->is_excluded(); |
|
260 buffer->reinitialize(thread_is_excluded); |
|
261 assert(buffer->empty(), "invariant"); |
|
262 if (!thread_is_excluded) { |
|
263 // state change from exclusion to inclusion requires a thread checkpoint |
|
264 JfrCheckpointManager::write_thread_checkpoint(thread); |
|
265 } |
|
266 return true; |
|
267 } |
|
268 |
256 BufferPtr const promotion_buffer = get_promotion_buffer(unflushed_size, _global_mspace, *this, promotion_retry, thread); |
269 BufferPtr const promotion_buffer = get_promotion_buffer(unflushed_size, _global_mspace, *this, promotion_retry, thread); |
257 if (promotion_buffer == NULL) { |
270 if (promotion_buffer == NULL) { |
258 write_data_loss(buffer, thread); |
271 write_data_loss(buffer, thread); |
259 return false; |
272 return false; |
260 } |
273 } |
468 |
481 |
469 static void assert_flush_large_precondition(ConstBufferPtr cur, const u1* const cur_pos, size_t used, size_t req, bool native, Thread* t) { |
482 static void assert_flush_large_precondition(ConstBufferPtr cur, const u1* const cur_pos, size_t used, size_t req, bool native, Thread* t) { |
470 assert(t != NULL, "invariant"); |
483 assert(t != NULL, "invariant"); |
471 assert(cur != NULL, "invariant"); |
484 assert(cur != NULL, "invariant"); |
472 assert(cur->lease(), "invariant"); |
485 assert(cur->lease(), "invariant"); |
|
486 assert(!cur->excluded(), "invariant"); |
473 assert(cur_pos != NULL, "invariant"); |
487 assert(cur_pos != NULL, "invariant"); |
474 assert(native ? t->jfr_thread_local()->native_buffer() == cur : t->jfr_thread_local()->java_buffer() == cur, "invariant"); |
488 assert(native ? t->jfr_thread_local()->native_buffer() == cur : t->jfr_thread_local()->java_buffer() == cur, "invariant"); |
475 assert(t->jfr_thread_local()->shelved_buffer() != NULL, "invariant"); |
489 assert(t->jfr_thread_local()->shelved_buffer() != NULL, "invariant"); |
476 assert(req >= used, "invariant"); |
490 assert(req >= used, "invariant"); |
477 assert(cur != t->jfr_thread_local()->shelved_buffer(), "invariant"); |
491 assert(cur != t->jfr_thread_local()->shelved_buffer(), "invariant"); |
582 } |
599 } |
583 |
600 |
584 typedef UnBufferedWriteToChunk<JfrBuffer> WriteOperation; |
601 typedef UnBufferedWriteToChunk<JfrBuffer> WriteOperation; |
585 typedef MutexedWriteOp<WriteOperation> MutexedWriteOperation; |
602 typedef MutexedWriteOp<WriteOperation> MutexedWriteOperation; |
586 typedef ConcurrentWriteOp<WriteOperation> ConcurrentWriteOperation; |
603 typedef ConcurrentWriteOp<WriteOperation> ConcurrentWriteOperation; |
587 typedef ConcurrentWriteOpExcludeRetired<WriteOperation> ThreadLocalConcurrentWriteOperation; |
604 |
|
605 typedef Retired<JfrBuffer, true> NonRetired; |
|
606 typedef Excluded<JfrBuffer, true> NonExcluded; |
|
607 typedef CompositeOperation<NonRetired, NonExcluded> BufferPredicate; |
|
608 typedef PredicatedMutexedWriteOp<WriteOperation, BufferPredicate> ThreadLocalMutexedWriteOperation; |
|
609 typedef PredicatedConcurrentWriteOp<WriteOperation, BufferPredicate> ThreadLocalConcurrentWriteOperation; |
588 |
610 |
589 size_t JfrStorage::write() { |
611 size_t JfrStorage::write() { |
590 const size_t full_size_processed = write_full(); |
612 const size_t full_elements = write_full(); |
591 WriteOperation wo(_chunkwriter); |
613 WriteOperation wo(_chunkwriter); |
592 ThreadLocalConcurrentWriteOperation tlwo(wo); |
614 NonRetired nr; |
|
615 NonExcluded ne; |
|
616 BufferPredicate bp(&nr, &ne); |
|
617 ThreadLocalConcurrentWriteOperation tlwo(wo, bp); |
593 process_full_list(tlwo, _thread_local_mspace); |
618 process_full_list(tlwo, _thread_local_mspace); |
594 ConcurrentWriteOperation cwo(wo); |
619 ConcurrentWriteOperation cwo(wo); |
595 process_free_list(cwo, _global_mspace); |
620 process_free_list(cwo, _global_mspace); |
596 return full_size_processed + wo.processed(); |
621 return full_elements + wo.elements(); |
597 } |
622 } |
598 |
623 |
599 size_t JfrStorage::write_at_safepoint() { |
624 size_t JfrStorage::write_at_safepoint() { |
600 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
625 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
601 WriteOperation wo(_chunkwriter); |
626 WriteOperation wo(_chunkwriter); |
602 MutexedWriteOperation writer(wo); // mutexed write mode |
627 MutexedWriteOperation writer(wo); // mutexed write mode |
603 process_full_list(writer, _thread_local_mspace); |
628 NonRetired nr; |
|
629 NonExcluded ne; |
|
630 BufferPredicate bp(&nr, &ne); |
|
631 ThreadLocalMutexedWriteOperation tlmwo(wo, bp); |
|
632 process_full_list(tlmwo, _thread_local_mspace); |
604 assert(_transient_mspace->is_free_empty(), "invariant"); |
633 assert(_transient_mspace->is_free_empty(), "invariant"); |
605 process_full_list(writer, _transient_mspace); |
634 process_full_list(writer, _transient_mspace); |
606 assert(_global_mspace->is_full_empty(), "invariant"); |
635 assert(_global_mspace->is_full_empty(), "invariant"); |
607 process_free_list(writer, _global_mspace); |
636 process_free_list(writer, _global_mspace); |
608 return wo.processed(); |
637 return wo.elements(); |
609 } |
638 } |
610 |
639 |
611 typedef DiscardOp<DefaultDiscarder<JfrStorage::Buffer> > DiscardOperation; |
640 typedef DiscardOp<DefaultDiscarder<JfrStorage::Buffer> > DiscardOperation; |
612 typedef ReleaseOp<JfrStorageMspace> ReleaseOperation; |
641 typedef ReleaseOp<JfrStorageMspace> ReleaseOperation; |
613 typedef CompositeOperation<MutexedWriteOperation, ReleaseOperation> FullOperation; |
642 typedef CompositeOperation<MutexedWriteOperation, ReleaseOperation> FullOperation; |
614 |
643 |
615 size_t JfrStorage::clear() { |
644 size_t JfrStorage::clear() { |
616 const size_t full_size_processed = clear_full(); |
645 const size_t full_elements = clear_full(); |
617 DiscardOperation discarder(concurrent); // concurrent discard mode |
646 DiscardOperation discarder(concurrent); // concurrent discard mode |
618 process_full_list(discarder, _thread_local_mspace); |
647 process_full_list(discarder, _thread_local_mspace); |
619 assert(_transient_mspace->is_free_empty(), "invariant"); |
648 assert(_transient_mspace->is_free_empty(), "invariant"); |
620 process_full_list(discarder, _transient_mspace); |
649 process_full_list(discarder, _transient_mspace); |
621 assert(_global_mspace->is_full_empty(), "invariant"); |
650 assert(_global_mspace->is_full_empty(), "invariant"); |
622 process_free_list(discarder, _global_mspace); |
651 process_free_list(discarder, _global_mspace); |
623 return full_size_processed + discarder.processed(); |
652 return full_elements + discarder.elements(); |
624 } |
653 } |
625 |
654 |
626 static void insert_free_age_nodes(JfrStorageAgeMspace* age_mspace, JfrAgeNode* head, JfrAgeNode* tail, size_t count) { |
655 static void insert_free_age_nodes(JfrStorageAgeMspace* age_mspace, JfrAgeNode* head, JfrAgeNode* tail, size_t count) { |
627 if (tail != NULL) { |
656 if (tail != NULL) { |
628 assert(tail->next() == NULL, "invariant"); |
657 assert(tail->next() == NULL, "invariant"); |
709 WriteOperation wo(_chunkwriter); |
738 WriteOperation wo(_chunkwriter); |
710 MutexedWriteOperation writer(wo); // a retired buffer implies mutexed access |
739 MutexedWriteOperation writer(wo); // a retired buffer implies mutexed access |
711 ReleaseOperation ro(_transient_mspace, thread); |
740 ReleaseOperation ro(_transient_mspace, thread); |
712 FullOperation cmd(&writer, &ro); |
741 FullOperation cmd(&writer, &ro); |
713 const size_t count = process_full(cmd, control(), _age_mspace); |
742 const size_t count = process_full(cmd, control(), _age_mspace); |
714 log(count, writer.processed()); |
743 if (0 == count) { |
715 return writer.processed(); |
744 assert(0 == writer.elements(), "invariant"); |
|
745 return 0; |
|
746 } |
|
747 const size_t size = writer.size(); |
|
748 log(count, size); |
|
749 return count; |
716 } |
750 } |
717 |
751 |
718 size_t JfrStorage::clear_full() { |
752 size_t JfrStorage::clear_full() { |
719 DiscardOperation discarder(mutexed); // a retired buffer implies mutexed access |
753 DiscardOperation discarder(mutexed); // a retired buffer implies mutexed access |
720 const size_t count = process_full(discarder, control(), _age_mspace); |
754 const size_t count = process_full(discarder, control(), _age_mspace); |
721 log(count, discarder.processed(), true); |
755 if (0 == count) { |
722 return discarder.processed(); |
756 assert(0 == discarder.elements(), "invariant"); |
|
757 return 0; |
|
758 } |
|
759 const size_t size = discarder.size(); |
|
760 log(count, size, true); |
|
761 return count; |
723 } |
762 } |
724 |
763 |
725 static void scavenge_log(size_t count, size_t amount, size_t current) { |
764 static void scavenge_log(size_t count, size_t amount, size_t current) { |
726 if (count > 0) { |
765 if (count > 0) { |
727 if (log_is_enabled(Debug, jfr, system)) { |
766 if (log_is_enabled(Debug, jfr, system)) { |