src/share/vm/jfr/writers/jfrWriterHost.inline.hpp

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

author
bulasevich
date
Tue, 16 Jun 2020 11:03:04 +0800
changeset 9947
db357034b763
parent 9941
45c8de52649c
child 10007
cb1e375e88a9
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 #ifndef SHARE_VM_JFR_WRITERS_JFRWRITERHOST_INLINE_HPP
    26 #define SHARE_VM_JFR_WRITERS_JFRWRITERHOST_INLINE_HPP
    28 #include "classfile/javaClasses.hpp"
    29 #include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"
    30 #include "jfr/recorder/service/jfrOptionSet.hpp"
    31 #include "jfr/writers/jfrEncoding.hpp"
    32 #include "jfr/writers/jfrWriterHost.hpp"
    33 #include "memory/resourceArea.hpp"
    34 #include "oops/oop.hpp"
    35 #include "oops/symbol.hpp"
    37 inline bool compressed_integers() {
    38   static const bool comp_integers = JfrOptionSet::compressed_integers();
    39   return comp_integers;
    40 }
    42 template <typename BE, typename IE, typename WriterPolicyImpl >
    43 template <typename T>
    44 inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded(T value) {
    45   write_padded(&value, 1);
    46 }
    48 template <typename BE, typename IE, typename WriterPolicyImpl >
    49 template <typename T>
    50 inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded(const T* value, size_t len) {
    51   assert(value != NULL, "invariant");
    52   assert(len > 0, "invariant");
    53   u1* const pos = ensure_size(sizeof(T) * len);
    54   if (pos) {
    55     this->set_current_pos(write_padded(value, len, pos));
    56   }
    57 }
    59 template <typename BE, typename IE, typename WriterPolicyImpl >
    60 template <typename T>
    61 inline u1* WriterHost<BE, IE, WriterPolicyImpl>::write_padded(const T* value, size_t len, u1* pos) {
    62   assert(value != NULL, "invariant");
    63   assert(len > 0, "invariant");
    64   assert(pos != NULL, "invariant");
    65   return _compressed_integers ? IE::write_padded(value, len, pos) : BE::write_padded(value, len, pos);
    66 }
    68 template <typename BE, typename IE, typename WriterPolicyImpl >
    69 template <typename T>
    70 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(const T* value, size_t len) {
    71   assert(value != NULL, "invariant");
    72   assert(len > 0, "invariant");
    73   u1* const pos = ensure_size(sizeof(T) * len);
    74   if (pos) {
    75     this->set_current_pos(write(value, len, pos));
    76   }
    77 }
    79 template <typename BE, typename IE, typename WriterPolicyImpl >
    80 template <typename T>
    81 inline u1* WriterHost<BE, IE, WriterPolicyImpl>::write(const T* value, size_t len, u1* pos) {
    82   assert(value != NULL, "invariant");
    83   assert(len > 0, "invariant");
    84   assert(pos != NULL, "invariant");
    85   return _compressed_integers ? IE::write(value, len, pos) : BE::write(value, len, pos);
    86 }
    88 template <typename BE, typename IE, typename WriterPolicyImpl>
    89 void WriterHost<BE, IE, WriterPolicyImpl>::write_utf8(const char* value) {
    90   if (NULL == value) {
    91     // only write encoding byte indicating NULL string
    92     write<u1>(NULL_STRING);
    93     return;
    94   }
    95   write<u1>(UTF8); // designate encoding
    96   const jint len = MIN2<jint>(max_jint, (jint)strlen(value));
    97   write(len);
    98   if (len > 0) {
    99     be_write(value, len);
   100   }
   101 }
   103 template <typename BE, typename IE, typename WriterPolicyImpl>
   104 void WriterHost<BE, IE, WriterPolicyImpl>::write_utf16(const jchar* value, jint len) {
   105   assert(value != NULL, "invariant");
   106   write((u1)UTF16); // designate encoding
   107   write(len);
   108   if (len > 0) {
   109     write(value, len);
   110   }
   111 }
   113 template <typename BE, typename IE, typename WriterPolicyImpl >
   114 template <typename T>
   115 inline void WriterHost<BE, IE, WriterPolicyImpl>::be_write(T value) {
   116   u1* const pos = ensure_size(sizeof(T));
   117   if (pos) {
   118     this->set_current_pos(BE::be_write(&value, 1, pos));
   119   }
   120 }
   122 template <typename BE, typename IE, typename WriterPolicyImpl >
   123 template <typename T>
   124 inline void WriterHost<BE, IE, WriterPolicyImpl>::be_write(const T* value, size_t len) {
   125   assert(value != NULL, "invariant");
   126   assert(len > 0, "invariant");
   127   u1* const pos = ensure_size(sizeof(T) * len);
   128   if (pos) {
   129     this->set_current_pos(BE::be_write(value, len, pos));
   130   }
   131 }
   133 template <typename BE, typename IE, typename WriterPolicyImpl >
   134 template <typename StorageType>
   135 inline WriterHost<BE, IE, WriterPolicyImpl>::WriterHost(StorageType* storage, Thread* thread) :
   136   WriterPolicyImpl(storage, thread),
   137   _compressed_integers(compressed_integers()) {
   138 }
   140 template <typename BE, typename IE, typename WriterPolicyImpl >
   141 template <typename StorageType>
   142 inline WriterHost<BE, IE, WriterPolicyImpl>::WriterHost(StorageType* storage, size_t size) :
   143   WriterPolicyImpl(storage, size),
   144   _compressed_integers(compressed_integers()) {
   145 }
   147 template <typename BE, typename IE, typename WriterPolicyImpl >
   148 inline WriterHost<BE, IE, WriterPolicyImpl>::WriterHost(Thread* thread) :
   149   WriterPolicyImpl(thread),
   150   _compressed_integers(compressed_integers()) {
   151 }
   153 // Extra size added as a safety cushion when dimensioning memory.
   154 // With varint encoding, the worst case is
   155 // associated with writing negative values.
   156 // For example, writing a negative s1 (-1)
   157 // will encode as 0xff 0x0f (2 bytes).
   158 // In this example, the sizeof(T) == 1 and length == 1,
   159 // but the implementation will need to dimension
   160 // 2 bytes for the encoding.
   161 // Hopefully, negative values should be relatively rare.
   162 static const size_t size_safety_cushion = 1;
   164 template <typename BE, typename IE, typename WriterPolicyImpl>
   165 inline u1* WriterHost<BE, IE, WriterPolicyImpl>::ensure_size(size_t requested) {
   166   if (!this->is_valid()) {
   167     // cancelled
   168     return NULL;
   169   }
   170   if (this->available_size() < requested + size_safety_cushion) {
   171     if (!this->accommodate(this->used_size(), requested + size_safety_cushion)) {
   172       this->cancel();
   173       return NULL;
   174     }
   175   }
   176   assert(requested + size_safety_cushion <= this->available_size(), "invariant");
   177   return this->current_pos();
   178 }
   180 template <typename BE, typename IE, typename WriterPolicyImpl>
   181 template <typename T>
   182 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(T value) {
   183   write(&value, 1);
   184 }
   186 template <typename BE, typename IE, typename WriterPolicyImpl>
   187 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(bool value) {
   188   be_write((u1)value);
   189 }
   191 template <typename BE, typename IE, typename WriterPolicyImpl>
   192 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(float value) {
   193   be_write(*(u4*)&(value));
   194 }
   196 template <typename BE, typename IE, typename WriterPolicyImpl>
   197 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(double value) {
   198   be_write(*(u8*)&(value));
   199 }
   201 template <typename BE, typename IE, typename WriterPolicyImpl>
   202 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(const char* value) {
   203   // UTF-8, max_jint len
   204   write_utf8(value);
   205 }
   207 template <typename BE, typename IE, typename WriterPolicyImpl>
   208 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(char* value) {
   209   write(const_cast<const char*>(value));
   210 }
   212 template <typename BE, typename IE, typename WriterPolicyImpl>
   213 inline void WriterHost<BE, IE, WriterPolicyImpl>::write(jstring string) {
   214   if (string == NULL) {
   215     write<u1>(NULL_STRING);
   216     return;
   217   }
   218   const oop string_oop = JNIHandles::resolve_external_guard(string);
   219   assert(string_oop != NULL, "invariant");
   220   const size_t length = (size_t)java_lang_String::length(string_oop);
   221   if (0 == length) {
   222     write<u1>(EMPTY_STRING);
   223     return;
   224   }
   225   const bool is_latin1_encoded = false;
   226   const typeArrayOop value = java_lang_String::value(string_oop);
   227   assert(value != NULL, "invariant");
   228   if (is_latin1_encoded) {
   229     write<u1>(LATIN1);
   230     write<u4>((u4)length);
   231     be_write(value->byte_at_addr(0), length);
   232   } else {
   233     write<u1>(UTF16);
   234     write<u4>((u4)length);
   235     write(value->char_at_addr(0), length);
   236   }
   237 }
   239 template <typename Writer, typename T>
   240 inline void tag_write(Writer* w, const T* t) {
   241   assert(w != NULL, "invariant");
   242   const traceid id = t == NULL ? 0 : JfrTraceId::use(t);
   243   w->write(id);
   244 }
   246 template <typename BE, typename IE, typename WriterPolicyImpl>
   247 void WriterHost<BE, IE, WriterPolicyImpl>::write(const ClassLoaderData* cld) {
   248   tag_write(this, cld);
   249 }
   251 template <typename BE, typename IE, typename WriterPolicyImpl>
   252 void WriterHost<BE, IE, WriterPolicyImpl>::write(const Klass* klass) {
   253   tag_write(this, klass);
   254 }
   256 template <typename BE, typename IE, typename WriterPolicyImpl>
   257 void WriterHost<BE, IE, WriterPolicyImpl>::write(const Method* method) {
   258   tag_write(this, method);
   259 }
   261 template <typename BE, typename IE, typename WriterPolicyImpl>
   262 void WriterHost<BE, IE, WriterPolicyImpl>::write(const Symbol* symbol) {
   263   ResourceMark rm;
   264   write_utf8(symbol != NULL ? symbol->as_C_string() : NULL);
   265 }
   267 template <typename BE, typename IE, typename WriterPolicyImpl>
   268 void WriterHost<BE, IE, WriterPolicyImpl>::write(const Ticks& time) {
   269   write((u8)JfrTime::is_ft_enabled() ? time.ft_value() : time.value());
   270 }
   272 template <typename BE, typename IE, typename WriterPolicyImpl>
   273 void WriterHost<BE, IE, WriterPolicyImpl>::write(const Tickspan& time) {
   274   write((u8)JfrTime::is_ft_enabled() ? time.ft_value() : time.value());
   275 }
   277 template <typename BE, typename IE, typename WriterPolicyImpl>
   278 void WriterHost<BE, IE, WriterPolicyImpl>::write(const JfrTicks& time) {
   279   write((u8)time.value());
   280 }
   282 template <typename BE, typename IE, typename WriterPolicyImpl>
   283 void WriterHost<BE, IE, WriterPolicyImpl>::write(const JfrTickspan& time) {
   284   write((u8)time.value());
   285 }
   287 template <typename BE, typename IE, typename WriterPolicyImpl>
   288 void WriterHost<BE, IE, WriterPolicyImpl>::bytes(const void* buf, size_t len) {
   289   u1* const pos = this->ensure_size(len);
   290   if (pos != NULL) {
   291     WriterPolicyImpl::bytes(pos, buf, len); // WriterPolicyImpl responsible for position update
   292   }
   293 }
   295 // UTF-8 for use with classfile/bytecodes
   296 template <typename BE, typename IE, typename WriterPolicyImpl>
   297 inline void WriterHost<BE, IE, WriterPolicyImpl>::write_utf8_u2_len(const char* value) {
   298   u2 len = 0;
   299   if (value != NULL) {
   300     len = MIN2<u2>(max_jushort, (u2)strlen(value));
   301   }
   302   write(len);
   303   if (len > 0) {
   304     be_write(value, len);
   305   }
   306 }
   308 template <typename BE, typename IE, typename WriterPolicyImpl>
   309 inline int64_t WriterHost<BE, IE, WriterPolicyImpl>::reserve(size_t size) {
   310   if (ensure_size(size) != NULL) {
   311     const int64_t reserved_offset = this->current_offset();
   312     this->set_current_pos(size);
   313     return reserved_offset;
   314   }
   315   this->cancel();
   316   return 0;
   317 }
   319 template <typename BE, typename IE, typename WriterPolicyImpl>
   320 template <typename T>
   321 inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded_at_offset(T value, int64_t offset) {
   322   if (this->is_valid()) {
   323     const int64_t current = this->current_offset();
   324     this->seek(offset);
   325     write_padded(value);
   326     this->seek(current); // restore
   327   }
   328 }
   330 template <typename BE, typename IE, typename WriterPolicyImpl>
   331 template <typename T>
   332 inline void WriterHost<BE, IE, WriterPolicyImpl>::write_at_offset(T value, int64_t offset) {
   333   if (this->is_valid()) {
   334     const int64_t current = this->current_offset();
   335     this->seek(offset);
   336     write(value);
   337     this->seek(current); // restore
   338   }
   339 }
   341 template <typename BE, typename IE, typename WriterPolicyImpl>
   342 template <typename T>
   343 inline void WriterHost<BE, IE, WriterPolicyImpl>::write_be_at_offset(T value, int64_t offset) {
   344   if (this->is_valid()) {
   345     const int64_t current = this->current_offset();
   346     this->seek(offset);
   347     be_write(value);
   348     this->seek(current); // restore
   349   }
   350 }
   352 #endif // SHARE_VM_JFR_WRITERS_JFRWRITERHOST_INLINE_HPP

mercurial