src/hotspot/share/jfr/recorder/repository/jfrChunkWriter.cpp
branchJEP-349-branch
changeset 58073 76d4428af8b6
parent 58068 22dab580786c
child 58082 0c9dd7f5d23a
equal deleted inserted replaced
58068:22dab580786c 58073:76d4428af8b6
   150     write_capabilities();
   150     write_capabilities();
   151     DEBUG_ONLY(assert_writer_position(_writer, HEADER_SIZE);)
   151     DEBUG_ONLY(assert_writer_position(_writer, HEADER_SIZE);)
   152     _writer->flush();
   152     _writer->flush();
   153   }
   153   }
   154 
   154 
   155   JfrChunkHeadWriter(JfrChunkWriter* writer, int64_t offset, bool head = true) : _writer(writer), _chunk(writer->_chunk) {
   155   JfrChunkHeadWriter(JfrChunkWriter* writer, int64_t offset, bool guard = true) : _writer(writer), _chunk(writer->_chunk) {
   156     assert(_writer != NULL, "invariant");
   156     assert(_writer != NULL, "invariant");
   157     assert(_writer->is_valid(), "invariant");
   157     assert(_writer->is_valid(), "invariant");
   158     assert(_chunk != NULL, "invariant");
   158     assert(_chunk != NULL, "invariant");
   159     if (0 == _writer->current_offset()) {
   159     if (0 == _writer->current_offset()) {
   160       assert(HEADER_SIZE == offset, "invariant");
   160       assert(HEADER_SIZE == offset, "invariant");
   161       initialize();
   161       initialize();
   162     } else {
   162     } else {
   163       if (head) {
   163       if (guard) {
   164         _writer->seek(GENERATION_OFFSET);
   164         _writer->seek(GENERATION_OFFSET);
   165         write_guard();
   165         write_guard();
   166         _writer->seek(offset);
   166         _writer->seek(offset);
   167       }
   167       }
   168     }
   168     }
   169     DEBUG_ONLY(assert_writer_position(_writer, offset);)
   169     DEBUG_ONLY(assert_writer_position(_writer, offset);)
   170   }
   170   }
   171 };
   171 };
   172 
   172 
   173 static void write_checkpoint_header(JfrChunkWriter& cw, int64_t event_offset, bool flushpoint) {
   173 static int64_t prepare_chunk_header_constant_pool(JfrChunkWriter& cw, int64_t event_offset, bool flushpoint) {
   174   const int64_t delta = cw.last_checkpoint_offset() == 0 ? 0 : cw.last_checkpoint_offset() - event_offset;
   174   const int64_t delta = cw.last_checkpoint_offset() == 0 ? 0 : cw.last_checkpoint_offset() - event_offset;
   175   const u4 checkpoint_type = flushpoint ? (u4)(FLUSH | HEADER) : (u4)HEADER;
   175   const u4 checkpoint_type = flushpoint ? (u4)(FLUSH | HEADER) : (u4)HEADER;
   176   cw.reserve(sizeof(u4));
   176   cw.reserve(sizeof(u4));
   177   cw.write<u8>(EVENT_CHECKPOINT);
   177   cw.write<u8>(EVENT_CHECKPOINT);
   178   cw.write<u8>(JfrTicks::now().value());
   178   cw.write<u8>(JfrTicks::now().value());
   182   cw.write<u4>(1); // pool count
   182   cw.write<u4>(1); // pool count
   183   cw.write<u8>(TYPE_CHUNKHEADER);
   183   cw.write<u8>(TYPE_CHUNKHEADER);
   184   cw.write<u4>(1); // count
   184   cw.write<u4>(1); // count
   185   cw.write<u8>(1); // key
   185   cw.write<u8>(1); // key
   186   cw.write<u4>(HEADER_SIZE); // length of byte array
   186   cw.write<u4>(HEADER_SIZE); // length of byte array
       
   187   return cw.current_offset();
   187 }
   188 }
   188 
   189 
   189 int64_t JfrChunkWriter::write_chunk_header_checkpoint(bool flushpoint) {
   190 int64_t JfrChunkWriter::write_chunk_header_checkpoint(bool flushpoint) {
   190   assert(this->has_valid_fd(), "invariant");
   191   assert(this->has_valid_fd(), "invariant");
   191   const int64_t event_size_offset = current_offset();
   192   const int64_t event_size_offset = current_offset();
   192   write_checkpoint_header(*this, event_size_offset, flushpoint);
   193   const int64_t header_content_pos = prepare_chunk_header_constant_pool(*this, event_size_offset, flushpoint);
   193   const int64_t start_offset = current_offset();
   194   JfrChunkHeadWriter head(this, header_content_pos, false);
   194   JfrChunkHeadWriter head(this, start_offset, false);
       
   195   head.write_magic();
   195   head.write_magic();
   196   head.write_version();
   196   head.write_version();
   197   const int64_t size_offset = reserve(sizeof(int64_t));
   197   const int64_t chunk_size_offset = reserve(sizeof(int64_t)); // size to be decided when we are done
   198   be_write(event_size_offset); // last checkpoint offset will be this checkpoint
   198   be_write(event_size_offset); // last checkpoint offset will be this checkpoint
   199   head.write_metadata();
   199   head.write_metadata();
   200   head.write_time(false);
   200   head.write_time(false);
   201   head.write_cpu_frequency();
   201   head.write_cpu_frequency();
   202   head.write_next_generation();
   202   head.write_next_generation();
   203   head.write_capabilities();
   203   head.write_capabilities();
   204   assert(current_offset() - start_offset == HEADER_SIZE, "invariant");
   204   assert(current_offset() - header_content_pos == HEADER_SIZE, "invariant");
   205   const u4 checkpoint_size = current_offset() - event_size_offset;
   205   const u4 checkpoint_size = current_offset() - event_size_offset;
   206   write_padded_at_offset<u4>(checkpoint_size, event_size_offset);
   206   write_padded_at_offset<u4>(checkpoint_size, event_size_offset);
   207   set_last_checkpoint_offset(event_size_offset);
   207   set_last_checkpoint_offset(event_size_offset);
   208   const size_t sz_written = size_written();
   208   const size_t sz_written = size_written();
   209   write_be_at_offset(sz_written, size_offset);
   209   write_be_at_offset(sz_written, chunk_size_offset);
   210   return sz_written;
   210   return sz_written;
   211 }
   211 }
   212 
   212 
   213 int64_t JfrChunkWriter::flushpoint(bool flushpoint) {
   213 int64_t JfrChunkWriter::flush_chunk(bool flushpoint) {
   214   assert(_chunk != NULL, "invariant");
   214   assert(_chunk != NULL, "invariant");
   215   if (flushpoint) {
   215   if (flushpoint) {
   216     _chunk->update();
   216     _chunk->update_current_time();
   217   }
   217   }
   218   const int64_t sz_written = write_chunk_header_checkpoint(flushpoint);
   218   const int64_t sz_written = write_chunk_header_checkpoint(flushpoint);
   219   assert(size_written() == sz_written, "invariant");
   219   assert(size_written() == sz_written, "invariant");
   220   JfrChunkHeadWriter head(this, SIZE_OFFSET);
   220   JfrChunkHeadWriter head(this, SIZE_OFFSET);
   221   head.flush(sz_written, !flushpoint);
   221   head.flush(sz_written, !flushpoint);
   280   return is_open;
   280   return is_open;
   281 }
   281 }
   282 
   282 
   283 int64_t JfrChunkWriter::close() {
   283 int64_t JfrChunkWriter::close() {
   284   assert(this->has_valid_fd(), "invariant");
   284   assert(this->has_valid_fd(), "invariant");
   285   const int64_t size_written = flushpoint(false);
   285   const int64_t size_written = flush_chunk(false);
   286   this->close_fd();
   286   this->close_fd();
   287   assert(!this->is_valid(), "invariant");
   287   assert(!this->is_valid(), "invariant");
   288   return size_written;
   288   return size_written;
   289 }
   289 }