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); |