Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/src/share/vm/jfr/writers/jfrEncoders.hpp
38920 views
/*1* Copyright (c) 2015, 2018, 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_VM_JFR_WRITERS_JFRENCODERS_HPP25#define SHARE_VM_JFR_WRITERS_JFRENCODERS_HPP2627#include "memory/allocation.hpp"28#include "utilities/debug.hpp"29#include "utilities/globalDefinitions.hpp"30#ifdef TARGET_ARCH_x8631# include "bytes_x86.hpp"32#endif33#ifdef TARGET_ARCH_sparc34# include "bytes_sparc.hpp"35#endif36#ifdef TARGET_ARCH_zero37# include "bytes_zero.hpp"38#endif39#ifdef TARGET_ARCH_arm40# include "bytes_arm.hpp"41#endif42#ifdef TARGET_ARCH_ppc43# include "bytes_ppc.hpp"44#endif45#ifdef TARGET_ARCH_aarch3246# include "bytes_aarch32.hpp"47#endif48#ifdef TARGET_ARCH_aarch6449# include "bytes_aarch64.hpp"50#endif5152//53// The Encoding policy prescribes a template54// method taking a first parameter of type T.55// This is the value to be encoded. The second56// parameter is a memory address - where to write57// the encoded value.58// The encoder method(s) should return the59// number of bytes encoded into that memory address.60//61// template <typename T>62// size_t encoder(T value, u1* dest);63//64// The caller ensures the destination65// address is not null and that T can be fitted66// in encoded form.67//6869// Encoding policy classes7071class BigEndianEncoderImpl {72public:73template <typename T>74static size_t encode(T value, u1* dest);7576template <typename T>77static size_t encode(const T* src, size_t len, u1* dest);7879template <typename T>80static size_t encode_padded(T value, u1* dest);8182template <typename T>83static size_t encode_padded(const T* src, size_t len, u1* dest);8485};8687template <typename T>88inline size_t BigEndianEncoderImpl::encode(T value, u1* dest) {89assert(dest != NULL, "invariant");90switch (sizeof(T)) {91case 1: {92ShouldNotReachHere();93return 0;94}95case 2: {96Bytes::put_Java_u2(dest, value);97return 2;98}99case 4: {100Bytes::put_Java_u4(dest, value);101return 4;102}103case 8: {104Bytes::put_Java_u8(dest, value);105return 8;106}107}108ShouldNotReachHere();109return 0;110}111112template <typename T>113inline size_t BigEndianEncoderImpl::encode(const T* src, size_t len, u1* dest) {114assert(dest != NULL, "invariant");115assert(len >= 1, "invariant");116if (1 == sizeof(T)) {117memcpy(dest, src, len);118return len;119}120size_t size = encode(*src, dest);121if (len > 1) {122for (size_t i = 1; i < len; ++i) {123size += encode(*(src + i), dest + size);124}125}126return size;127}128129template <typename T>130inline size_t BigEndianEncoderImpl::encode_padded(T value, u1* dest) {131return encode(value, dest);132}133134template <typename T>135inline size_t BigEndianEncoderImpl::encode_padded(const T* src, size_t len, u1* dest) {136assert(dest != NULL, "invariant");137assert(len >= 1, "invariant");138if (1 == sizeof(T)) {139memcpy(dest, src, len);140return len;141}142size_t size = encode_padded(*src, dest);143if (len > 1) {144for (size_t i = 1; i < len; ++i) {145size += encode_padded(*(src + i), dest + size);146}147}148return size;149}150151152// The Varint128 encoder implements encoding according to153// msb(it) 128bit encoding (1 encode bit | 7 value bits),154// using least significant byte order.155//156// Example (little endian platform):157// Value: 25674158// Binary: 00000000 0000000 01100100 01001010159// Varint encoded (3 bytes):160// Value: 13289473161// Varint encoded: 11001010 11001000 00000001162//163164class Varint128EncoderImpl {165private:166template <typename T>167static u8 to_u8(T value);168169public:170template <typename T>171static size_t encode(T value, u1* dest);172173template <typename T>174static size_t encode(const T* src, size_t len, u1* dest);175176template <typename T>177static size_t encode_padded(T value, u1* dest);178179template <typename T>180static size_t encode_padded(const T* src, size_t len, u1* dest);181182};183184template <typename T>185inline u8 Varint128EncoderImpl::to_u8(T value) {186switch(sizeof(T)) {187case 1:188return static_cast<u8>(static_cast<u1>(value) & static_cast<u1>(0xff));189case 2:190return static_cast<u8>(static_cast<u2>(value) & static_cast<u2>(0xffff));191case 4:192return static_cast<u8>(static_cast<u4>(value) & static_cast<u4>(0xffffffff));193case 8:194return static_cast<u8>(value);195default:196fatal("unsupported type");197}198return 0;199}200201static const u1 ext_bit = 0x80;202#define GREATER_THAN_OR_EQUAL_TO_128(v) (((u8)(~(ext_bit - 1)) & (v)))203#define LESS_THAN_128(v) !GREATER_THAN_OR_EQUAL_TO_128(v)204205template <typename T>206inline size_t Varint128EncoderImpl::encode(T value, u1* dest) {207assert(dest != NULL, "invariant");208209const u8 v = to_u8(value);210211if (LESS_THAN_128(v)) {212*dest = static_cast<u1>(v); // set bit 0-6, no extension213return 1;214}215*dest = static_cast<u1>(v | ext_bit); // set bit 0-6, with extension216if (LESS_THAN_128(v >> 7)) {217*(dest + 1) = static_cast<u1>(v >> 7); // set bit 7-13, no extension218return 2;219}220*(dest + 1) = static_cast<u1>((v >> 7) | ext_bit); // set bit 7-13, with extension221if (LESS_THAN_128(v >> 14)) {222*(dest + 2) = static_cast<u1>(v >> 14); // set bit 14-20, no extension223return 3;224}225*(dest + 2) = static_cast<u1>((v >> 14) | ext_bit); // set bit 14-20, with extension226if (LESS_THAN_128(v >> 21)) {227*(dest + 3) = static_cast<u1>(v >> 21); // set bit 21-27, no extension228return 4;229}230*(dest + 3) = static_cast<u1>((v >> 21) | ext_bit); // set bit 21-27, with extension231if (LESS_THAN_128(v >> 28)) {232*(dest + 4) = static_cast<u1>(v >> 28); // set bit 28-34, no extension233return 5;234}235*(dest + 4) = static_cast<u1>((v >> 28) | ext_bit); // set bit 28-34, with extension236if (LESS_THAN_128(v >> 35)) {237*(dest + 5) = static_cast<u1>(v >> 35); // set bit 35-41, no extension238return 6;239}240*(dest + 5) = static_cast<u1>((v >> 35) | ext_bit); // set bit 35-41, with extension241if (LESS_THAN_128(v >> 42)) {242*(dest + 6) = static_cast<u1>(v >> 42); // set bit 42-48, no extension243return 7;244}245*(dest + 6) = static_cast<u1>((v >> 42) | ext_bit); // set bit 42-48, with extension246if (LESS_THAN_128(v >> 49)) {247*(dest + 7) = static_cast<u1>(v >> 49); // set bit 49-55, no extension248return 8;249}250*(dest + 7) = static_cast<u1>((v >> 49) | ext_bit); // set bit 49-55, with extension251// no need to extend since only 64 bits allowed.252*(dest + 8) = static_cast<u1>(v >> 56); // set bit 56-63253return 9;254}255256template <typename T>257inline size_t Varint128EncoderImpl::encode(const T* src, size_t len, u1* dest) {258assert(dest != NULL, "invariant");259assert(len >= 1, "invariant");260size_t size = encode(*src, dest);261if (len > 1) {262for (size_t i = 1; i < len; ++i) {263size += encode(*(src + i), dest + size);264}265}266return size;267}268269template <typename T>270inline size_t Varint128EncoderImpl::encode_padded(T value, u1* dest) {271assert(dest != NULL, "invariant");272const u8 v = to_u8(value);273switch (sizeof(T)) {274case 1:275dest[0] = static_cast<u1>(v);276return 1;277case 2:278dest[0] = static_cast<u1>(v | 0x80);279dest[1] = static_cast<u1>(v >> 7);280return 2;281case 4:282dest[0] = static_cast<u1>(v | 0x80);283dest[1] = static_cast<u1>(v >> 7 | 0x80);284dest[2] = static_cast<u1>(v >> 14 | 0x80);285dest[3] = static_cast<u1>(v >> 21);286return 4;287case 8:288dest[0] = static_cast<u1>(v | 0x80);289dest[1] = static_cast<u1>(v >> 7 | 0x80);290dest[2] = static_cast<u1>(v >> 14 | 0x80);291dest[3] = static_cast<u1>(v >> 21 | 0x80);292dest[4] = static_cast<u1>(v >> 28 | 0x80);293dest[5] = static_cast<u1>(v >> 35 | 0x80);294dest[6] = static_cast<u1>(v >> 42 | 0x80);295dest[7] = static_cast<u1>(v >> 49);296return 8;297default:298ShouldNotReachHere();299}300return 0;301}302303304template <typename T>305inline size_t Varint128EncoderImpl::encode_padded(const T* src, size_t len, u1* dest) {306assert(dest != NULL, "invariant");307assert(len >= 1, "invariant");308size_t size = encode_padded(*src, dest);309if (len > 1) {310for (size_t i = 1; i < len; ++i) {311size += encode_padded(*(src + i), dest + size);312}313}314return size;315}316317#endif // SHARE_VM_JFR_WRITERS_JFRENCODERS_HPP318319320