1 /* |
1 /* |
2 * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
108 assert(_thread == rotation_thread, "invariant"); |
108 assert(_thread == rotation_thread, "invariant"); |
109 return; |
109 return; |
110 } |
110 } |
111 if (_thread->is_Java_thread()) { |
111 if (_thread->is_Java_thread()) { |
112 // in order to allow the system to move to a safepoint |
112 // in order to allow the system to move to a safepoint |
113 MutexLockerEx msg_lock(JfrMsg_lock); |
113 MutexLocker msg_lock(JfrMsg_lock); |
114 JfrMsg_lock->wait(false, rotation_retry_sleep_millis); |
114 JfrMsg_lock->wait(rotation_retry_sleep_millis); |
115 } |
115 } |
116 else { |
116 else { |
117 os::naked_short_sleep(rotation_retry_sleep_millis); |
117 os::naked_short_sleep(rotation_retry_sleep_millis); |
118 } |
118 } |
119 } |
119 } |
339 |
339 |
340 void JfrRecorderService::open_new_chunk(bool vm_error) { |
340 void JfrRecorderService::open_new_chunk(bool vm_error) { |
341 assert(!_chunkwriter.is_valid(), "invariant"); |
341 assert(!_chunkwriter.is_valid(), "invariant"); |
342 assert(!JfrStream_lock->owned_by_self(), "invariant"); |
342 assert(!JfrStream_lock->owned_by_self(), "invariant"); |
343 JfrChunkRotation::on_rotation(); |
343 JfrChunkRotation::on_rotation(); |
344 MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
344 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
345 if (!_repository.open_chunk(vm_error)) { |
345 if (!_repository.open_chunk(vm_error)) { |
346 assert(!_chunkwriter.is_valid(), "invariant"); |
346 assert(!_chunkwriter.is_valid(), "invariant"); |
347 _storage.control().set_to_disk(false); |
347 _storage.control().set_to_disk(false); |
348 return; |
348 return; |
349 } |
349 } |
361 } |
361 } |
362 } |
362 } |
363 |
363 |
364 void JfrRecorderService::serialize_storage_from_in_memory_recording() { |
364 void JfrRecorderService::serialize_storage_from_in_memory_recording() { |
365 assert(!JfrStream_lock->owned_by_self(), "not holding stream lock!"); |
365 assert(!JfrStream_lock->owned_by_self(), "not holding stream lock!"); |
366 MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
366 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
367 _storage.write(); |
367 _storage.write(); |
368 } |
368 } |
369 |
369 |
370 void JfrRecorderService::chunk_rotation() { |
370 void JfrRecorderService::chunk_rotation() { |
371 finalize_current_chunk(); |
371 finalize_current_chunk(); |
420 // write string pool checkpoint -> |
420 // write string pool checkpoint -> |
421 // write storage -> |
421 // write storage -> |
422 // release stream lock |
422 // release stream lock |
423 // |
423 // |
424 void JfrRecorderService::pre_safepoint_write() { |
424 void JfrRecorderService::pre_safepoint_write() { |
425 MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
425 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
426 assert(_chunkwriter.is_valid(), "invariant"); |
426 assert(_chunkwriter.is_valid(), "invariant"); |
427 _checkpoint_manager.write_types(); |
427 _checkpoint_manager.write_types(); |
428 _checkpoint_manager.write_epoch_transition_mspace(); |
428 _checkpoint_manager.write_epoch_transition_mspace(); |
429 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false); |
429 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false); |
430 write_stringpool_checkpoint(_string_pool, _chunkwriter); |
430 write_stringpool_checkpoint(_string_pool, _chunkwriter); |
455 // lock metadata descriptor -> |
455 // lock metadata descriptor -> |
456 // release stream lock |
456 // release stream lock |
457 // |
457 // |
458 void JfrRecorderService::safepoint_write() { |
458 void JfrRecorderService::safepoint_write() { |
459 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
459 assert(SafepointSynchronize::is_at_safepoint(), "invariant"); |
460 MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
460 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
461 write_object_sample_stacktrace(_stack_trace_repository); |
461 write_object_sample_stacktrace(_stack_trace_repository); |
462 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true); |
462 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, true); |
463 write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter); |
463 write_stringpool_checkpoint_safepoint(_string_pool, _chunkwriter); |
464 _checkpoint_manager.write_safepoint_types(); |
464 _checkpoint_manager.write_safepoint_types(); |
465 _storage.write_at_safepoint(); |
465 _storage.write_at_safepoint(); |
491 // During the safepoint tasks just completed, the system transitioned to a new epoch. |
491 // During the safepoint tasks just completed, the system transitioned to a new epoch. |
492 // Type tagging is epoch relative which entails we are able to write out the |
492 // Type tagging is epoch relative which entails we are able to write out the |
493 // already tagged artifacts for the previous epoch. We can accomplish this concurrently |
493 // already tagged artifacts for the previous epoch. We can accomplish this concurrently |
494 // with threads now tagging artifacts in relation to the new, now updated, epoch and remain outside of a safepoint. |
494 // with threads now tagging artifacts in relation to the new, now updated, epoch and remain outside of a safepoint. |
495 _checkpoint_manager.write_type_set(); |
495 _checkpoint_manager.write_type_set(); |
496 MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
496 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
497 // serialize any outstanding checkpoint memory |
497 // serialize any outstanding checkpoint memory |
498 _checkpoint_manager.write(); |
498 _checkpoint_manager.write(); |
499 // serialize the metadata descriptor event and close out the chunk |
499 // serialize the metadata descriptor event and close out the chunk |
500 _repository.close_chunk(write_metadata_event(_chunkwriter)); |
500 _repository.close_chunk(write_metadata_event(_chunkwriter)); |
501 assert(!_chunkwriter.is_valid(), "invariant"); |
501 assert(!_chunkwriter.is_valid(), "invariant"); |
524 } |
524 } |
525 |
525 |
526 void JfrRecorderService::process_full_buffers() { |
526 void JfrRecorderService::process_full_buffers() { |
527 if (_chunkwriter.is_valid()) { |
527 if (_chunkwriter.is_valid()) { |
528 assert(!JfrStream_lock->owned_by_self(), "invariant"); |
528 assert(!JfrStream_lock->owned_by_self(), "invariant"); |
529 MutexLockerEx stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
529 MutexLocker stream_lock(JfrStream_lock, Mutex::_no_safepoint_check_flag); |
530 _storage.write_full(); |
530 _storage.write_full(); |
531 } |
531 } |
532 } |
532 } |
533 |
533 |
534 void JfrRecorderService::scavenge() { |
534 void JfrRecorderService::scavenge() { |