src/share/vm/jfr/recorder/checkpoint/jfrCheckpointWriter.cpp

Tue, 16 Jun 2020 11:03:04 +0800

author
bulasevich
date
Tue, 16 Jun 2020 11:03:04 +0800
changeset 9947
db357034b763
parent 9858
b985cbb00e68
permissions
-rw-r--r--

8217647: JFR: recordings on 32-bit systems unreadable
Reviewed-by: egahlin
Contributed-by: boris.ulasevich@bell-sw.com, markus.gronlund@oracle.com

     1 /*
     2  * Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     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
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "jfr/recorder/checkpoint/jfrCheckpointManager.hpp"
    27 #include "jfr/recorder/checkpoint/jfrCheckpointWriter.hpp"
    28 #include "jfr/writers/jfrBigEndianWriter.hpp"
    30 JfrCheckpointFlush::JfrCheckpointFlush(Type* old, size_t used, size_t requested, Thread* t) :
    31   _result(JfrCheckpointManager::flush(old, used, requested, t)) {}
    33 JfrCheckpointWriter::JfrCheckpointWriter(bool flushpoint, bool header, Thread* thread) :
    34   JfrCheckpointWriterBase(JfrCheckpointManager::lease_buffer(thread), thread),
    35   _time(JfrTicks::now()),
    36   _offset(0),
    37   _count(0),
    38   _flushpoint(flushpoint),
    39   _header(header) {
    40   assert(this->is_acquired(), "invariant");
    41   assert(0 == this->current_offset(), "invariant");
    42   if (_header) {
    43     reserve(sizeof(JfrCheckpointEntry));
    44   }
    45 }
    47 static void write_checkpoint_header(u1* pos, int64_t size, jlong time, bool flushpoint, u4 type_count) {
    48   assert(pos != NULL, "invariant");
    49   JfrBigEndianWriter be_writer(pos, sizeof(JfrCheckpointEntry));
    50   be_writer.write(size);
    51   be_writer.write(time);
    52   be_writer.write(JfrTicks::now().value() - time);
    53   be_writer.write(flushpoint ? (u4)1 : (u4)0);
    54   be_writer.write(type_count);
    55   assert(be_writer.is_valid(), "invariant");
    56 }
    58 JfrCheckpointWriter::~JfrCheckpointWriter() {
    59   assert(this->is_acquired(), "invariant");
    60   if (!this->is_valid() || !_header) {
    61     release();
    62     return;
    63   }
    64   if (0 == count()) {
    65     assert(this->used_size() == sizeof(JfrCheckpointEntry), "invariant");
    66     this->seek(_offset);
    67     release();
    68     return;
    69   }
    70   assert(_header, "invariant");
    71   assert(this->is_valid(), "invariant");
    72   assert(count() > 0, "invariant");
    73   assert(this->used_size() > sizeof(JfrCheckpointEntry), "invariant");
    74   const int64_t size = this->current_offset();
    75   assert(size + this->start_pos() == this->current_pos(), "invariant");
    76   write_checkpoint_header(const_cast<u1*>(this->start_pos()), size, _time, is_flushpoint(), count());
    77   release();
    78 }
    80 void JfrCheckpointWriter::set_flushpoint(bool flushpoint) {
    81   _flushpoint = flushpoint;
    82 }
    84 bool JfrCheckpointWriter::is_flushpoint() const {
    85   return _flushpoint;
    86 }
    88 u4 JfrCheckpointWriter::count() const {
    89   return _count;
    90 }
    92 void JfrCheckpointWriter::set_count(u4 count) {
    93   _count = count;
    94 }
    96 void JfrCheckpointWriter::release() {
    97   assert(this->is_acquired(), "invariant");
    98   if (!this->is_valid() || this->used_size() == 0) {
    99     return;
   100   }
   101   assert(this->used_size() > 0, "invariant");
   102   // write through to backing storage
   103   this->commit();
   104   assert(0 == this->current_offset(), "invariant");
   105 }
   107 void JfrCheckpointWriter::write_type(JfrTypeId type_id) {
   108   assert(type_id < TYPES_END, "invariant");
   109   write<u8>(type_id);
   110   increment();
   111 }
   113 void JfrCheckpointWriter::write_key(u8 key) {
   114   write(key);
   115 }
   117 void JfrCheckpointWriter::increment() {
   118   ++_count;
   119 }
   121 void JfrCheckpointWriter::write_count(u4 nof_entries) {
   122   write(nof_entries);
   123 }
   125 void JfrCheckpointWriter::write_count(u4 nof_entries, int64_t offset) {
   126   write_padded_at_offset(nof_entries, offset);
   127 }
   129 const u1* JfrCheckpointWriter::session_data(size_t* size, const JfrCheckpointContext* ctx /* 0 */) {
   130   assert(this->is_acquired(), "wrong state!");
   131   if (!this->is_valid()) {
   132     *size = 0;
   133     return NULL;
   134   }
   135   if (ctx != NULL) {
   136     const u1* session_start_pos = this->start_pos() + ctx->offset;
   137     *size = this->current_pos() - session_start_pos;
   138     return session_start_pos;
   139   }
   140   *size = this->used_size();
   141   assert(this->start_pos() + *size == this->current_pos(), "invariant");
   142   write_checkpoint_header(const_cast<u1*>(this->start_pos()), this->used_offset(), _time, is_flushpoint(), count());
   143   this->seek(_offset + (_header ? sizeof(JfrCheckpointEntry) : 0));
   144   set_count(0);
   145   return this->start_pos();
   146 }
   148 const JfrCheckpointContext JfrCheckpointWriter::context() const {
   149   JfrCheckpointContext ctx;
   150   ctx.offset = this->current_offset();
   151   ctx.count = this->count();
   152   return ctx;
   153 }
   155 void JfrCheckpointWriter::set_context(const JfrCheckpointContext ctx) {
   156   this->seek(ctx.offset);
   157   set_count(ctx.count);
   158 }
   159 bool JfrCheckpointWriter::has_data() const {
   160   return this->used_size() > sizeof(JfrCheckpointEntry);
   161 }
   163 JfrCheckpointBlobHandle JfrCheckpointWriter::checkpoint_blob() {
   164   size_t size = 0;
   165   const u1* data = session_data(&size);
   166   return JfrCheckpointBlob::make(data, size);
   167 }
   169 JfrCheckpointBlobHandle JfrCheckpointWriter::copy(const JfrCheckpointContext* ctx /* 0 */) {
   170   if (ctx == NULL) {
   171     return checkpoint_blob();
   172   }
   173   size_t size = 0;
   174   const u1* data = session_data(&size, ctx);
   175   return JfrCheckpointBlob::make(data, size);
   176 }
   178 JfrCheckpointBlobHandle JfrCheckpointWriter::move(const JfrCheckpointContext* ctx /* 0 */) {
   179   JfrCheckpointBlobHandle data = copy(ctx);
   180   if (ctx != NULL) {
   181     const_cast<JfrCheckpointContext*>(ctx)->count = 0;
   182     set_context(*ctx);
   183   }
   184   return data;
   185 }

mercurial