Path: blob/master/src/hotspot/share/jfr/writers/jfrWriterHost.inline.hpp
41152 views
/*1* Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324#ifndef SHARE_JFR_WRITERS_JFRWRITERHOST_INLINE_HPP25#define SHARE_JFR_WRITERS_JFRWRITERHOST_INLINE_HPP2627#include "jfr/writers/jfrWriterHost.hpp"2829#include "classfile/javaClasses.hpp"30#include "jfr/recorder/checkpoint/types/traceid/jfrTraceId.inline.hpp"31#include "jfr/recorder/service/jfrOptionSet.hpp"32#include "jfr/writers/jfrEncoding.hpp"33#include "memory/resourceArea.hpp"34#include "oops/oop.hpp"35#include "oops/symbol.hpp"36#include "oops/typeArrayOop.inline.hpp"37#include "runtime/jniHandles.hpp"3839inline bool compressed_integers() {40static const bool comp_integers = JfrOptionSet::compressed_integers();41return comp_integers;42}4344template <typename BE, typename IE, typename WriterPolicyImpl >45template <typename T>46inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded(T value) {47write_padded(&value, 1);48}4950template <typename BE, typename IE, typename WriterPolicyImpl >51template <typename T>52inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded(const T* value, size_t len) {53assert(value != NULL, "invariant");54assert(len > 0, "invariant");55u1* const pos = ensure_size(sizeof(T) * len);56if (pos) {57this->set_current_pos(write_padded(value, len, pos));58}59}6061template <typename BE, typename IE, typename WriterPolicyImpl >62template <typename T>63inline u1* WriterHost<BE, IE, WriterPolicyImpl>::write_padded(const T* value, size_t len, u1* pos) {64assert(value != NULL, "invariant");65assert(len > 0, "invariant");66assert(pos != NULL, "invariant");67return _compressed_integers ? IE::write_padded(value, len, pos) : BE::write_padded(value, len, pos);68}6970template <typename BE, typename IE, typename WriterPolicyImpl >71template <typename T>72inline void WriterHost<BE, IE, WriterPolicyImpl>::write(const T* value, size_t len) {73assert(value != NULL, "invariant");74assert(len > 0, "invariant");75// Might need T + 1 size76u1* const pos = ensure_size(sizeof(T) * len + len);77if (pos) {78this->set_current_pos(write(value, len, pos));79}80}8182template <typename BE, typename IE, typename WriterPolicyImpl >83template <typename T>84inline u1* WriterHost<BE, IE, WriterPolicyImpl>::write(const T* value, size_t len, u1* pos) {85assert(value != NULL, "invariant");86assert(len > 0, "invariant");87assert(pos != NULL, "invariant");88return _compressed_integers ? IE::write(value, len, pos) : BE::write(value, len, pos);89}9091template <typename BE, typename IE, typename WriterPolicyImpl>92void WriterHost<BE, IE, WriterPolicyImpl>::write_utf8(const char* value) {93if (NULL == value) {94// only write encoding byte indicating NULL string95write<u1>(NULL_STRING);96return;97}98write<u1>(UTF8); // designate encoding99const jint len = MIN2<jint>(max_jint, (jint)strlen(value));100write(len);101if (len > 0) {102be_write(value, len);103}104}105106template <typename BE, typename IE, typename WriterPolicyImpl>107void WriterHost<BE, IE, WriterPolicyImpl>::write_utf16(const jchar* value, jint len) {108assert(value != NULL, "invariant");109write((u1)UTF16); // designate encoding110write(len);111if (len > 0) {112write(value, len);113}114}115116template <typename BE, typename IE, typename WriterPolicyImpl >117template <typename T>118inline void WriterHost<BE, IE, WriterPolicyImpl>::be_write(T value) {119be_write(&value, 1);120}121122template <typename BE, typename IE, typename WriterPolicyImpl >123template <typename T>124inline void WriterHost<BE, IE, WriterPolicyImpl>::be_write(const T* value, size_t len) {125assert(value != NULL, "invariant");126assert(len > 0, "invariant");127// Might need T + 1 size128u1* const pos = ensure_size(sizeof(T) * len + len);129if (pos) {130this->set_current_pos(BE::be_write(value, len, pos));131}132}133134template <typename BE, typename IE, typename WriterPolicyImpl >135template <typename StorageType>136inline WriterHost<BE, IE, WriterPolicyImpl>::WriterHost(StorageType* storage, Thread* thread) :137WriterPolicyImpl(storage, thread),138_compressed_integers(compressed_integers()) {139}140141// Extra size added as a safety cushion when dimensioning memory.142// With varint encoding, the worst case is143// associated with writing negative values.144// For example, writing a negative s1 (-1)145// will encode as 0xff 0x0f (2 bytes).146static const size_t size_safety_cushion = 1;147148template <typename BE, typename IE, typename WriterPolicyImpl >149template <typename StorageType>150inline WriterHost<BE, IE, WriterPolicyImpl>::WriterHost(StorageType* storage, size_t size) :151WriterPolicyImpl(storage, size + size_safety_cushion),152_compressed_integers(compressed_integers()) {153}154155template <typename BE, typename IE, typename WriterPolicyImpl >156inline WriterHost<BE, IE, WriterPolicyImpl>::WriterHost(Thread* thread) :157WriterPolicyImpl(thread),158_compressed_integers(compressed_integers()) {159}160161template <typename BE, typename IE, typename WriterPolicyImpl>162inline u1* WriterHost<BE, IE, WriterPolicyImpl>::ensure_size(size_t requested_size) {163if (!this->is_valid()) {164// cancelled165return NULL;166}167if (this->available_size() < requested_size) {168if (!this->accommodate(this->used_size(), requested_size)) {169assert(!this->is_valid(), "invariant");170return NULL;171}172}173assert(requested_size <= this->available_size(), "invariant");174return this->current_pos();175}176177template <typename BE, typename IE, typename WriterPolicyImpl>178template <typename T>179inline void WriterHost<BE, IE, WriterPolicyImpl>::write(T value) {180write(&value, 1);181}182183template <typename BE, typename IE, typename WriterPolicyImpl>184inline void WriterHost<BE, IE, WriterPolicyImpl>::write(bool value) {185be_write((u1)value);186}187188template <typename BE, typename IE, typename WriterPolicyImpl>189inline void WriterHost<BE, IE, WriterPolicyImpl>::write(float value) {190be_write(*(u4*)&(value));191}192193template <typename BE, typename IE, typename WriterPolicyImpl>194inline void WriterHost<BE, IE, WriterPolicyImpl>::write(double value) {195be_write(*(u8*)&(value));196}197198template <typename BE, typename IE, typename WriterPolicyImpl>199inline void WriterHost<BE, IE, WriterPolicyImpl>::write(const char* value) {200// UTF-8, max_jint len201write_utf8(value);202}203204template <typename BE, typename IE, typename WriterPolicyImpl>205inline void WriterHost<BE, IE, WriterPolicyImpl>::write(char* value) {206write(const_cast<const char*>(value));207}208209template <typename BE, typename IE, typename WriterPolicyImpl>210inline void WriterHost<BE, IE, WriterPolicyImpl>::write(jstring string) {211if (string == NULL) {212write<u1>(NULL_STRING);213return;214}215const oop string_oop = JNIHandles::resolve_external_guard(string);216assert(string_oop != NULL, "invariant");217const size_t length = (size_t)java_lang_String::length(string_oop);218if (0 == length) {219write<u1>(EMPTY_STRING);220return;221}222const bool is_latin1_encoded = java_lang_String::is_latin1(string_oop);223const typeArrayOop value = java_lang_String::value(string_oop);224assert(value != NULL, "invariant");225if (is_latin1_encoded) {226write<u1>(LATIN1);227write<u4>((u4)length);228be_write(value->byte_at_addr(0), length);229} else {230write<u1>(UTF16);231write<u4>((u4)length);232write(value->char_at_addr(0), length);233}234}235236template <typename Writer, typename T>237inline void tag_write(Writer* w, const T* t) {238assert(w != NULL, "invariant");239const traceid id = t == NULL ? 0 : JfrTraceId::load(t);240w->write(id);241}242243template <typename BE, typename IE, typename WriterPolicyImpl>244void WriterHost<BE, IE, WriterPolicyImpl>::write(const ClassLoaderData* cld) {245tag_write(this, cld);246}247248template <typename BE, typename IE, typename WriterPolicyImpl>249void WriterHost<BE, IE, WriterPolicyImpl>::write(const Klass* klass) {250tag_write(this, klass);251}252253template <typename BE, typename IE, typename WriterPolicyImpl>254void WriterHost<BE, IE, WriterPolicyImpl>::write(const Method* method) {255tag_write(this, method);256}257258template <typename BE, typename IE, typename WriterPolicyImpl>259void WriterHost<BE, IE, WriterPolicyImpl>::write(const ModuleEntry* module) {260tag_write(this, module);261}262263template <typename BE, typename IE, typename WriterPolicyImpl>264void WriterHost<BE, IE, WriterPolicyImpl>::write(const PackageEntry* package) {265tag_write(this, package);266}267268template <typename BE, typename IE, typename WriterPolicyImpl>269void WriterHost<BE, IE, WriterPolicyImpl>::write(const Symbol* symbol) {270ResourceMark rm;271write_utf8(symbol != NULL ? symbol->as_C_string() : NULL);272}273274template <typename BE, typename IE, typename WriterPolicyImpl>275void WriterHost<BE, IE, WriterPolicyImpl>::write(const Ticks& time) {276write((uintptr_t)JfrTime::is_ft_enabled() ? time.ft_value() : time.value());277}278279template <typename BE, typename IE, typename WriterPolicyImpl>280void WriterHost<BE, IE, WriterPolicyImpl>::write(const Tickspan& time) {281write((uintptr_t)JfrTime::is_ft_enabled() ? time.ft_value() : time.value());282}283284template <typename BE, typename IE, typename WriterPolicyImpl>285void WriterHost<BE, IE, WriterPolicyImpl>::write(const JfrTicks& time) {286write((uintptr_t)time.value());287}288289template <typename BE, typename IE, typename WriterPolicyImpl>290void WriterHost<BE, IE, WriterPolicyImpl>::write(const JfrTickspan& time) {291write((uintptr_t)time.value());292}293294template <typename BE, typename IE, typename WriterPolicyImpl>295void WriterHost<BE, IE, WriterPolicyImpl>::write_bytes(const void* buf, intptr_t len) {296assert(len >= 0, "invariant");297u1* const pos = this->ensure_size((size_t)len);298if (pos != NULL) {299WriterPolicyImpl::write_bytes(pos, buf, len); // WriterPolicyImpl responsible for position update300}301}302303// UTF-8 for use with classfile/bytecodes304template <typename BE, typename IE, typename WriterPolicyImpl>305inline void WriterHost<BE, IE, WriterPolicyImpl>::write_utf8_u2_len(const char* value) {306u2 len = 0;307if (value != NULL) {308len = MIN2<u2>(max_jushort, (u2)strlen(value));309}310write(len);311if (len > 0) {312be_write(value, len);313}314}315316template <typename BE, typename IE, typename WriterPolicyImpl>317inline int64_t WriterHost<BE, IE, WriterPolicyImpl>::reserve(size_t size) {318if (ensure_size(size) != NULL) {319const int64_t reserved_offset = this->current_offset();320this->set_current_pos(size);321return reserved_offset;322}323this->cancel();324return 0;325}326327template <typename BE, typename IE, typename WriterPolicyImpl>328template <typename T>329inline void WriterHost<BE, IE, WriterPolicyImpl>::write_padded_at_offset(T value, int64_t offset) {330if (this->is_valid()) {331const int64_t current = this->current_offset();332this->seek(offset);333write_padded(value);334this->seek(current); // restore335}336}337338template <typename BE, typename IE, typename WriterPolicyImpl>339template <typename T>340inline void WriterHost<BE, IE, WriterPolicyImpl>::write_at_offset(T value, int64_t offset) {341if (this->is_valid()) {342const int64_t current = this->current_offset();343this->seek(offset);344write(value);345this->seek(current); // restore346}347}348349template <typename BE, typename IE, typename WriterPolicyImpl>350template <typename T>351inline void WriterHost<BE, IE, WriterPolicyImpl>::write_be_at_offset(T value, int64_t offset) {352if (this->is_valid()) {353const int64_t current = this->current_offset();354this->seek(offset);355be_write(value);356this->seek(current); // restore357}358}359360#endif // SHARE_JFR_WRITERS_JFRWRITERHOST_INLINE_HPP361362363