1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp Mon Aug 12 18:30:40 2019 +0300 1.3 @@ -0,0 +1,185 @@ 1.4 +/* 1.5 + * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.23 + * or visit www.oracle.com if you need additional information or have any 1.24 + * questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +#include "precompiled.hpp" 1.29 +#include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp" 1.30 +#include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp" 1.31 +#include "jfr/writers/jfrBigEndianWriter.hpp" 1.32 + 1.33 +JfrCheckpointFlush::JfrCheckpointFlush(Type* old, size_t used, size_t requested, Thread* t) : 1.34 + _result(JfrCheckpointManager::flush(old, used, requested, t)) {} 1.35 + 1.36 +JfrCheckpointWriter::JfrCheckpointWriter(bool flushpoint, bool header, Thread* thread) : 1.37 + JfrCheckpointWriterBase(JfrCheckpointManager::lease_buffer(thread), thread), 1.38 + _time(JfrTicks::now()), 1.39 + _offset(0), 1.40 + _count(0), 1.41 + _flushpoint(flushpoint), 1.42 + _header(header) { 1.43 + assert(this->is_acquired(), "invariant"); 1.44 + assert(0 == this->current_offset(), "invariant"); 1.45 + if (_header) { 1.46 + reserve(sizeof(JfrCheckpointEntry)); 1.47 + } 1.48 +} 1.49 + 1.50 +static void write_checkpoint_header(u1* pos, jlong size, jlong time, bool flushpoint, juint type_count) { 1.51 + assert(pos != NULL, "invariant"); 1.52 + JfrBigEndianWriter be_writer(pos, sizeof(JfrCheckpointEntry)); 1.53 + be_writer.write(size); 1.54 + be_writer.write(time); 1.55 + be_writer.write(JfrTicks::now().value() - time); 1.56 + be_writer.write(flushpoint ? (juint)1 : (juint)0); 1.57 + be_writer.write(type_count); 1.58 + assert(be_writer.is_valid(), "invariant"); 1.59 +} 1.60 + 1.61 +JfrCheckpointWriter::~JfrCheckpointWriter() { 1.62 + assert(this->is_acquired(), "invariant"); 1.63 + if (!this->is_valid() || !_header) { 1.64 + release(); 1.65 + return; 1.66 + } 1.67 + if (0 == count()) { 1.68 + assert(this->used_size() == sizeof(JfrCheckpointEntry), "invariant"); 1.69 + this->seek(_offset); 1.70 + release(); 1.71 + return; 1.72 + } 1.73 + assert(_header, "invariant"); 1.74 + assert(this->is_valid(), "invariant"); 1.75 + assert(count() > 0, "invariant"); 1.76 + assert(this->used_size() > sizeof(JfrCheckpointEntry), "invariant"); 1.77 + const jlong size = this->current_offset(); 1.78 + assert(size + this->start_pos() == this->current_pos(), "invariant"); 1.79 + write_checkpoint_header(const_cast<u1*>(this->start_pos()), size, _time, is_flushpoint(), count()); 1.80 + release(); 1.81 +} 1.82 + 1.83 +void JfrCheckpointWriter::set_flushpoint(bool flushpoint) { 1.84 + _flushpoint = flushpoint; 1.85 +} 1.86 + 1.87 +bool JfrCheckpointWriter::is_flushpoint() const { 1.88 + return _flushpoint; 1.89 +} 1.90 + 1.91 +juint JfrCheckpointWriter::count() const { 1.92 + return _count; 1.93 +} 1.94 + 1.95 +void JfrCheckpointWriter::set_count(juint count) { 1.96 + _count = count; 1.97 +} 1.98 + 1.99 +void JfrCheckpointWriter::release() { 1.100 + assert(this->is_acquired(), "invariant"); 1.101 + if (!this->is_valid() || this->used_size() == 0) { 1.102 + return; 1.103 + } 1.104 + assert(this->used_size() > 0, "invariant"); 1.105 + // write through to backing storage 1.106 + this->commit(); 1.107 + assert(0 == this->current_offset(), "invariant"); 1.108 +} 1.109 + 1.110 +void JfrCheckpointWriter::write_type(JfrTypeId type_id) { 1.111 + assert(type_id < TYPES_END, "invariant"); 1.112 + write<u8>(type_id); 1.113 + increment(); 1.114 +} 1.115 + 1.116 +void JfrCheckpointWriter::write_key(u8 key) { 1.117 + write<u8>(key); 1.118 +} 1.119 + 1.120 +void JfrCheckpointWriter::increment() { 1.121 + ++_count; 1.122 +} 1.123 + 1.124 +void JfrCheckpointWriter::write_count(u4 nof_entries) { 1.125 + write<u4>((u4)nof_entries); 1.126 +} 1.127 + 1.128 +void JfrCheckpointWriter::write_count(u4 nof_entries, jlong offset) { 1.129 + write_padded_at_offset(nof_entries, offset); 1.130 +} 1.131 + 1.132 +const u1* JfrCheckpointWriter::session_data(size_t* size, const JfrCheckpointContext* ctx /* 0 */) { 1.133 + assert(this->is_acquired(), "wrong state!"); 1.134 + if (!this->is_valid()) { 1.135 + *size = 0; 1.136 + return NULL; 1.137 + } 1.138 + if (ctx != NULL) { 1.139 + const u1* session_start_pos = this->start_pos() + ctx->offset; 1.140 + *size = this->current_pos() - session_start_pos; 1.141 + return session_start_pos; 1.142 + } 1.143 + *size = this->used_size(); 1.144 + assert(this->start_pos() + *size == this->current_pos(), "invariant"); 1.145 + write_checkpoint_header(const_cast<u1*>(this->start_pos()), this->used_offset(), _time, is_flushpoint(), count()); 1.146 + this->seek(_offset + (_header ? sizeof(JfrCheckpointEntry) : 0)); 1.147 + set_count(0); 1.148 + return this->start_pos(); 1.149 +} 1.150 + 1.151 +const JfrCheckpointContext JfrCheckpointWriter::context() const { 1.152 + JfrCheckpointContext ctx; 1.153 + ctx.offset = this->current_offset(); 1.154 + ctx.count = this->count(); 1.155 + return ctx; 1.156 +} 1.157 + 1.158 +void JfrCheckpointWriter::set_context(const JfrCheckpointContext ctx) { 1.159 + this->seek(ctx.offset); 1.160 + set_count(ctx.count); 1.161 +} 1.162 +bool JfrCheckpointWriter::has_data() const { 1.163 + return this->used_size() > sizeof(JfrCheckpointEntry); 1.164 +} 1.165 + 1.166 +JfrCheckpointBlobHandle JfrCheckpointWriter::checkpoint_blob() { 1.167 + size_t size = 0; 1.168 + const u1* data = session_data(&size); 1.169 + return JfrCheckpointBlob::make(data, size); 1.170 +} 1.171 + 1.172 +JfrCheckpointBlobHandle JfrCheckpointWriter::copy(const JfrCheckpointContext* ctx /* 0 */) { 1.173 + if (ctx == NULL) { 1.174 + return checkpoint_blob(); 1.175 + } 1.176 + size_t size = 0; 1.177 + const u1* data = session_data(&size, ctx); 1.178 + return JfrCheckpointBlob::make(data, size); 1.179 +} 1.180 + 1.181 +JfrCheckpointBlobHandle JfrCheckpointWriter::move(const JfrCheckpointContext* ctx /* 0 */) { 1.182 + JfrCheckpointBlobHandle data = copy(ctx); 1.183 + if (ctx != NULL) { 1.184 + const_cast<JfrCheckpointContext*>(ctx)->count = 0; 1.185 + set_context(*ctx); 1.186 + } 1.187 + return data; 1.188 +}