131 } |
131 } |
132 bool not_acquired() const { return !_acquired; } |
132 bool not_acquired() const { return !_acquired; } |
133 }; |
133 }; |
134 |
134 |
135 static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { |
135 static int64_t write_checkpoint_event_prologue(JfrChunkWriter& cw, u8 type_id) { |
136 const int64_t prev_cp_offset = cw.previous_checkpoint_offset(); |
136 const int64_t last_cp_offset = cw.last_checkpoint_offset(); |
137 const int64_t prev_cp_relative_offset = 0 == prev_cp_offset ? 0 : prev_cp_offset - cw.current_offset(); |
137 const int64_t delta_to_last_checkpoint = 0 == last_cp_offset ? 0 : last_cp_offset - cw.current_offset(); |
138 cw.reserve(sizeof(u4)); |
138 cw.reserve(sizeof(u4)); |
139 cw.write<u8>(EVENT_CHECKPOINT); |
139 cw.write<u8>(EVENT_CHECKPOINT); |
140 cw.write(JfrTicks::now()); |
140 cw.write(JfrTicks::now()); |
141 cw.write((int64_t)0); |
141 cw.write((int64_t)0); // duration |
142 cw.write(prev_cp_relative_offset); // write previous checkpoint offset delta |
142 cw.write(delta_to_last_checkpoint); |
143 cw.write<bool>(false); // flushpoint |
143 cw.write<bool>(false); // flushpoint |
144 cw.write((u4)1); // nof types in this checkpoint |
144 cw.write((u4)1); // nof types in this checkpoint |
145 cw.write(type_id); |
145 cw.write(type_id); |
146 const int64_t number_of_elements_offset = cw.current_offset(); |
146 const int64_t number_of_elements_offset = cw.current_offset(); |
147 cw.reserve(sizeof(u4)); |
147 cw.reserve(sizeof(u4)); |
176 assert(number_of_elements > 0, "invariant"); |
176 assert(number_of_elements > 0, "invariant"); |
177 assert(_cw.current_offset() > num_elements_offset, "invariant"); |
177 assert(_cw.current_offset() > num_elements_offset, "invariant"); |
178 _cw.write_padded_at_offset<u4>(number_of_elements, num_elements_offset); |
178 _cw.write_padded_at_offset<u4>(number_of_elements, num_elements_offset); |
179 _cw.write_padded_at_offset<u4>((u4)_cw.current_offset() - current_cp_offset, current_cp_offset); |
179 _cw.write_padded_at_offset<u4>((u4)_cw.current_offset() - current_cp_offset, current_cp_offset); |
180 // update writer with last checkpoint position |
180 // update writer with last checkpoint position |
181 _cw.set_previous_checkpoint_offset(current_cp_offset); |
181 _cw.set_last_checkpoint_offset(current_cp_offset); |
182 return true; |
182 return true; |
183 } |
183 } |
184 }; |
184 }; |
185 |
185 |
186 template <typename Instance, size_t(Instance::*func)()> |
186 template <typename Instance, size_t(Instance::*func)()> |
315 static bool vm_error = false; |
315 static bool vm_error = false; |
316 if (msgs & MSGBIT(MSG_VM_ERROR)) { |
316 if (msgs & MSGBIT(MSG_VM_ERROR)) { |
317 vm_error = true; |
317 vm_error = true; |
318 prepare_for_vm_error_rotation(); |
318 prepare_for_vm_error_rotation(); |
319 } |
319 } |
|
320 if (!_storage.control().to_disk()) { |
|
321 in_memory_rotation(); |
|
322 } else if (vm_error) { |
|
323 vm_error_rotation(); |
|
324 } else { |
|
325 chunk_rotation(); |
|
326 } |
320 if (msgs & (MSGBIT(MSG_STOP))) { |
327 if (msgs & (MSGBIT(MSG_STOP))) { |
321 stop(); |
328 stop(); |
322 } |
329 } |
323 // action determined by chunkwriter state |
|
324 if (!_chunkwriter.is_valid()) { |
|
325 in_memory_rotation(); |
|
326 return; |
|
327 } |
|
328 if (vm_error) { |
|
329 vm_error_rotation(); |
|
330 return; |
|
331 } |
|
332 chunk_rotation(); |
|
333 } |
330 } |
334 |
331 |
335 void JfrRecorderService::prepare_for_vm_error_rotation() { |
332 void JfrRecorderService::prepare_for_vm_error_rotation() { |
336 if (!_chunkwriter.is_valid()) { |
333 if (!_chunkwriter.is_valid()) { |
337 open_new_chunk(true); |
334 open_new_chunk(true); |
398 static void write_stacktrace_checkpoint(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) { |
395 static void write_stacktrace_checkpoint(JfrStackTraceRepository& stack_trace_repo, JfrChunkWriter& chunkwriter, bool clear) { |
399 WriteStackTraceRepository write_stacktrace_repo(stack_trace_repo, chunkwriter, clear); |
396 WriteStackTraceRepository write_stacktrace_repo(stack_trace_repo, chunkwriter, clear); |
400 WriteStackTraceCheckpoint write_stack_trace_checkpoint(chunkwriter, TYPE_STACKTRACE, write_stacktrace_repo); |
397 WriteStackTraceCheckpoint write_stack_trace_checkpoint(chunkwriter, TYPE_STACKTRACE, write_stacktrace_repo); |
401 write_stack_trace_checkpoint.process(); |
398 write_stack_trace_checkpoint.process(); |
402 } |
399 } |
403 |
|
404 static void write_object_sample_stacktrace(ObjectSampler* sampler, JfrStackTraceRepository& stack_trace_repository) { |
|
405 WriteObjectSampleStacktrace object_sample_stacktrace(sampler, stack_trace_repository); |
|
406 object_sample_stacktrace.process(); |
|
407 } |
|
408 |
|
409 static void write_stringpool_checkpoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) { |
400 static void write_stringpool_checkpoint(JfrStringPool& string_pool, JfrChunkWriter& chunkwriter) { |
410 WriteStringPool write_string_pool(string_pool); |
401 WriteStringPool write_string_pool(string_pool); |
411 WriteStringPoolCheckpoint write_string_pool_checkpoint(chunkwriter, TYPE_STRING, write_string_pool); |
402 WriteStringPoolCheckpoint write_string_pool_checkpoint(chunkwriter, TYPE_STRING, write_string_pool); |
412 write_string_pool_checkpoint.process(); |
403 write_string_pool_checkpoint.process(); |
413 } |
404 } |
438 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false); |
429 write_stacktrace_checkpoint(_stack_trace_repository, _chunkwriter, false); |
439 write_stringpool_checkpoint(_string_pool, _chunkwriter); |
430 write_stringpool_checkpoint(_string_pool, _chunkwriter); |
440 if (LeakProfiler::is_running()) { |
431 if (LeakProfiler::is_running()) { |
441 // Exclusive access to the object sampler instance. |
432 // Exclusive access to the object sampler instance. |
442 // The sampler is released (unlocked) later in post_safepoint_write. |
433 // The sampler is released (unlocked) later in post_safepoint_write. |
443 ObjectSampler* const sampler = ObjectSampler::acquire(); |
434 ObjectSampleCheckpoint::on_rotation(ObjectSampler::acquire(), _stack_trace_repository); |
444 assert(sampler != NULL, "invariant"); |
|
445 write_object_sample_stacktrace(sampler, _stack_trace_repository); |
|
446 } |
435 } |
447 _storage.write(); |
436 _storage.write(); |
448 } |
437 } |
449 |
438 |
450 void JfrRecorderService::invoke_safepoint_write() { |
439 void JfrRecorderService::invoke_safepoint_write() { |