Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/jfr/writers/jfrEncoders.hpp
41149 views
1
/*
2
* Copyright (c) 2015, 2019, 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
*/
24
25
#ifndef SHARE_JFR_WRITERS_JFRENCODERS_HPP
26
#define SHARE_JFR_WRITERS_JFRENCODERS_HPP
27
28
#include "memory/allocation.hpp"
29
#include "utilities/bytes.hpp"
30
#include "utilities/debug.hpp"
31
#include "utilities/globalDefinitions.hpp"
32
33
//
34
// The Encoding policy prescribes a template
35
// method taking a first parameter of type T.
36
// This is the value to be encoded. The second
37
// parameter is a memory address - where to write
38
// the encoded value.
39
// The encoder method(s) should return the
40
// number of bytes encoded into that memory address.
41
//
42
// template <typename T>
43
// size_t encoder(T value, u1* dest);
44
//
45
// The caller ensures the destination
46
// address is not null and that T can be fitted
47
// in encoded form.
48
//
49
50
// Encoding policy classes
51
52
class BigEndianEncoderImpl {
53
public:
54
template <typename T>
55
static size_t encode(T value, u1* dest);
56
57
template <typename T>
58
static size_t encode(const T* src, size_t len, u1* dest);
59
60
template <typename T>
61
static size_t encode_padded(T value, u1* dest);
62
63
template <typename T>
64
static size_t encode_padded(const T* src, size_t len, u1* dest);
65
66
};
67
68
template <typename T>
69
inline size_t BigEndianEncoderImpl::encode(T value, u1* dest) {
70
assert(dest != NULL, "invariant");
71
switch (sizeof(T)) {
72
case 1: {
73
ShouldNotReachHere();
74
return 0;
75
}
76
case 2: {
77
Bytes::put_Java_u2(dest, value);
78
return 2;
79
}
80
case 4: {
81
Bytes::put_Java_u4(dest, value);
82
return 4;
83
}
84
case 8: {
85
Bytes::put_Java_u8(dest, value);
86
return 8;
87
}
88
}
89
ShouldNotReachHere();
90
return 0;
91
}
92
93
template <typename T>
94
inline size_t BigEndianEncoderImpl::encode(const T* src, size_t len, u1* dest) {
95
assert(dest != NULL, "invariant");
96
assert(len >= 1, "invariant");
97
if (1 == sizeof(T)) {
98
memcpy(dest, src, len);
99
return len;
100
}
101
size_t size = encode(*src, dest);
102
if (len > 1) {
103
for (size_t i = 1; i < len; ++i) {
104
size += encode(*(src + i), dest + size);
105
}
106
}
107
return size;
108
}
109
110
template <typename T>
111
inline size_t BigEndianEncoderImpl::encode_padded(T value, u1* dest) {
112
return encode(value, dest);
113
}
114
115
template <typename T>
116
inline size_t BigEndianEncoderImpl::encode_padded(const T* src, size_t len, u1* dest) {
117
assert(dest != NULL, "invariant");
118
assert(len >= 1, "invariant");
119
if (1 == sizeof(T)) {
120
memcpy(dest, src, len);
121
return len;
122
}
123
size_t size = encode_padded(*src, dest);
124
if (len > 1) {
125
for (size_t i = 1; i < len; ++i) {
126
size += encode_padded(*(src + i), dest + size);
127
}
128
}
129
return size;
130
}
131
132
133
// The Varint128 encoder implements encoding according to
134
// msb(it) 128bit encoding (1 encode bit | 7 value bits),
135
// using least significant byte order.
136
//
137
// Example (little endian platform):
138
// Value: 25674
139
// Binary: 00000000 0000000 01100100 01001010
140
// Varint encoded (3 bytes):
141
// Value: 13289473
142
// Varint encoded: 11001010 11001000 00000001
143
//
144
145
class Varint128EncoderImpl {
146
private:
147
template <typename T>
148
static u8 to_u8(T value);
149
150
public:
151
template <typename T>
152
static size_t encode(T value, u1* dest);
153
154
template <typename T>
155
static size_t encode(const T* src, size_t len, u1* dest);
156
157
template <typename T>
158
static size_t encode_padded(T value, u1* dest);
159
160
template <typename T>
161
static size_t encode_padded(const T* src, size_t len, u1* dest);
162
163
};
164
165
template <typename T>
166
inline u8 Varint128EncoderImpl::to_u8(T value) {
167
switch(sizeof(T)) {
168
case 1:
169
return static_cast<u8>(static_cast<u1>(value) & static_cast<u1>(0xff));
170
case 2:
171
return static_cast<u8>(static_cast<u2>(value) & static_cast<u2>(0xffff));
172
case 4:
173
return static_cast<u8>(static_cast<u4>(value) & static_cast<u4>(0xffffffff));
174
case 8:
175
return static_cast<u8>(value);
176
default:
177
fatal("unsupported type");
178
}
179
return 0;
180
}
181
182
static const u1 ext_bit = 0x80;
183
#define GREATER_THAN_OR_EQUAL_TO_128(v) (((u8)(~(ext_bit - 1)) & (v)))
184
#define LESS_THAN_128(v) !GREATER_THAN_OR_EQUAL_TO_128(v)
185
186
template <typename T>
187
inline size_t Varint128EncoderImpl::encode(T value, u1* dest) {
188
assert(dest != NULL, "invariant");
189
190
const u8 v = to_u8(value);
191
192
if (LESS_THAN_128(v)) {
193
*dest = static_cast<u1>(v); // set bit 0-6, no extension
194
return 1;
195
}
196
*dest = static_cast<u1>(v | ext_bit); // set bit 0-6, with extension
197
if (LESS_THAN_128(v >> 7)) {
198
*(dest + 1) = static_cast<u1>(v >> 7); // set bit 7-13, no extension
199
return 2;
200
}
201
*(dest + 1) = static_cast<u1>((v >> 7) | ext_bit); // set bit 7-13, with extension
202
if (LESS_THAN_128(v >> 14)) {
203
*(dest + 2) = static_cast<u1>(v >> 14); // set bit 14-20, no extension
204
return 3;
205
}
206
*(dest + 2) = static_cast<u1>((v >> 14) | ext_bit); // set bit 14-20, with extension
207
if (LESS_THAN_128(v >> 21)) {
208
*(dest + 3) = static_cast<u1>(v >> 21); // set bit 21-27, no extension
209
return 4;
210
}
211
*(dest + 3) = static_cast<u1>((v >> 21) | ext_bit); // set bit 21-27, with extension
212
if (LESS_THAN_128(v >> 28)) {
213
*(dest + 4) = static_cast<u1>(v >> 28); // set bit 28-34, no extension
214
return 5;
215
}
216
*(dest + 4) = static_cast<u1>((v >> 28) | ext_bit); // set bit 28-34, with extension
217
if (LESS_THAN_128(v >> 35)) {
218
*(dest + 5) = static_cast<u1>(v >> 35); // set bit 35-41, no extension
219
return 6;
220
}
221
*(dest + 5) = static_cast<u1>((v >> 35) | ext_bit); // set bit 35-41, with extension
222
if (LESS_THAN_128(v >> 42)) {
223
*(dest + 6) = static_cast<u1>(v >> 42); // set bit 42-48, no extension
224
return 7;
225
}
226
*(dest + 6) = static_cast<u1>((v >> 42) | ext_bit); // set bit 42-48, with extension
227
if (LESS_THAN_128(v >> 49)) {
228
*(dest + 7) = static_cast<u1>(v >> 49); // set bit 49-55, no extension
229
return 8;
230
}
231
*(dest + 7) = static_cast<u1>((v >> 49) | ext_bit); // set bit 49-55, with extension
232
// no need to extend since only 64 bits allowed.
233
*(dest + 8) = static_cast<u1>(v >> 56); // set bit 56-63
234
return 9;
235
}
236
237
template <typename T>
238
inline size_t Varint128EncoderImpl::encode(const T* src, size_t len, u1* dest) {
239
assert(dest != NULL, "invariant");
240
assert(len >= 1, "invariant");
241
size_t size = encode(*src, dest);
242
if (len > 1) {
243
for (size_t i = 1; i < len; ++i) {
244
size += encode(*(src + i), dest + size);
245
}
246
}
247
return size;
248
}
249
250
template <typename T>
251
inline size_t Varint128EncoderImpl::encode_padded(T value, u1* dest) {
252
assert(dest != NULL, "invariant");
253
const u8 v = to_u8(value);
254
switch (sizeof(T)) {
255
case 1:
256
dest[0] = static_cast<u1>(v);
257
return 1;
258
case 2:
259
dest[0] = static_cast<u1>(v | 0x80);
260
dest[1] = static_cast<u1>(v >> 7);
261
return 2;
262
case 4:
263
dest[0] = static_cast<u1>(v | 0x80);
264
dest[1] = static_cast<u1>(v >> 7 | 0x80);
265
dest[2] = static_cast<u1>(v >> 14 | 0x80);
266
dest[3] = static_cast<u1>(v >> 21);
267
return 4;
268
case 8:
269
dest[0] = static_cast<u1>(v | 0x80);
270
dest[1] = static_cast<u1>(v >> 7 | 0x80);
271
dest[2] = static_cast<u1>(v >> 14 | 0x80);
272
dest[3] = static_cast<u1>(v >> 21 | 0x80);
273
dest[4] = static_cast<u1>(v >> 28 | 0x80);
274
dest[5] = static_cast<u1>(v >> 35 | 0x80);
275
dest[6] = static_cast<u1>(v >> 42 | 0x80);
276
dest[7] = static_cast<u1>(v >> 49);
277
return 8;
278
default:
279
ShouldNotReachHere();
280
}
281
return 0;
282
}
283
284
285
template <typename T>
286
inline size_t Varint128EncoderImpl::encode_padded(const T* src, size_t len, u1* dest) {
287
assert(dest != NULL, "invariant");
288
assert(len >= 1, "invariant");
289
size_t size = encode_padded(*src, dest);
290
if (len > 1) {
291
for (size_t i = 1; i < len; ++i) {
292
size += encode_padded(*(src + i), dest + size);
293
}
294
}
295
return size;
296
}
297
298
#endif // SHARE_JFR_WRITERS_JFRENCODERS_HPP
299
300