Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/hotspot/share/jfr/writers/jfrStorageAdapter.hpp
41152 views
1
/*
2
* Copyright (c) 2016, 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_JFRSTORAGEADAPTER_HPP
26
#define SHARE_JFR_WRITERS_JFRSTORAGEADAPTER_HPP
27
28
#include "jfr/utilities/jfrAllocation.hpp"
29
30
class Thread;
31
32
//
33
// The adapters present writers with a uniform interface over storage.
34
//
35
// Adapter policy
36
//
37
// StorageType* storage();
38
// const u1* start() const;
39
// const u1* pos();
40
// const u1* end() const;
41
// void commit(u1* position);
42
// bool flush(size_t used, size_t requested);
43
// void release();
44
//
45
46
template <typename Flush>
47
class Adapter {
48
public:
49
typedef typename Flush::Type StorageType;
50
Adapter(StorageType* storage, Thread* thread) : _storage(storage), _thread(thread) {}
51
Adapter(Thread* thread) : _storage(NULL), _thread(thread) {}
52
53
void set_storage(StorageType* storage) {
54
_storage = storage;
55
}
56
57
StorageType* storage() {
58
return _storage;
59
}
60
61
const u1* start() const {
62
assert(_storage != NULL, "invariant");
63
return _storage->start();
64
}
65
66
u1* pos() {
67
assert(_storage != NULL, "invariant");
68
return _storage->pos();
69
}
70
71
const u1* end() const {
72
assert(_storage != NULL, "invariant");
73
return _storage->end();
74
}
75
76
void commit(u1* position) {
77
assert(_storage != NULL, "invariant");
78
_storage->set_pos(position);
79
}
80
81
bool flush(size_t used, size_t requested) {
82
assert(_thread != NULL, "invariant");
83
Flush f(_storage, used, requested, _thread);
84
_storage = f.result();
85
return _storage != NULL && !_storage->excluded();
86
}
87
88
void release() {
89
if (_storage != NULL && _storage->lease()) {
90
// This flush call will return the lease
91
// of a temporary storage area.
92
// Since the requested size is 0,
93
// the flush implementation will accomodate
94
// that 'size' request in the
95
// original thread local storage,
96
// by implication restoring the original
97
// in the process of returning a lease.
98
flush(0, 0);
99
}
100
}
101
102
private:
103
StorageType* _storage;
104
Thread* _thread;
105
};
106
107
template <size_t DEFAULT_SIZE = K>
108
class MallocAdapter {
109
private:
110
u1* _start;
111
u1* _pos;
112
u1* _end;
113
size_t _initial_size;
114
bool _has_ownership;
115
116
bool allocate(size_t size);
117
void deallocate();
118
119
public:
120
typedef u1 StorageType;
121
MallocAdapter(u1* storage, Thread* thread);
122
MallocAdapter(u1* storage, size_t size);
123
MallocAdapter(Thread* thread);
124
~MallocAdapter();
125
126
StorageType* storage() { return _start; }
127
const u1* start() const { return _start; }
128
u1* pos() { return _pos; }
129
void commit(u1* position) { _pos = position; }
130
const u1* end() const { return _end; }
131
void release() {}
132
bool flush(size_t used, size_t requested);
133
};
134
135
template <size_t DEFAULT_SIZE>
136
MallocAdapter<DEFAULT_SIZE>::MallocAdapter(u1* storage, size_t size) :
137
_start(storage),
138
_pos(storage),
139
_end(storage + size),
140
_initial_size(size),
141
_has_ownership(false) {
142
}
143
144
template <size_t DEFAULT_SIZE>
145
MallocAdapter<DEFAULT_SIZE> ::MallocAdapter(u1* storage, Thread* thread) :
146
_start(storage),
147
_pos(storage),
148
_end(storage),
149
_initial_size(0),
150
_has_ownership(false) {
151
}
152
153
template <size_t DEFAULT_SIZE>
154
MallocAdapter<DEFAULT_SIZE>::MallocAdapter(Thread* thread) :
155
_start(NULL),
156
_pos(NULL),
157
_end(NULL),
158
_initial_size(DEFAULT_SIZE),
159
_has_ownership(true) {
160
allocate(DEFAULT_SIZE);
161
}
162
163
template <size_t DEFAULT_SIZE>
164
MallocAdapter<DEFAULT_SIZE>::~MallocAdapter() {
165
if (_has_ownership) {
166
deallocate();
167
}
168
}
169
170
template <size_t DEFAULT_SIZE>
171
bool MallocAdapter<DEFAULT_SIZE>::allocate(size_t size) {
172
if (NULL == _start) {
173
_start = JfrCHeapObj::new_array<u1>(size);
174
if (_start) {
175
_pos = _start;
176
_end = _start + size;
177
_initial_size = size;
178
}
179
}
180
return _start != NULL;
181
}
182
183
template <size_t DEFAULT_SIZE>
184
void MallocAdapter<DEFAULT_SIZE>::deallocate() {
185
if (_start != NULL) {
186
JfrCHeapObj::free(_start, (size_t)(_end - _start));
187
}
188
}
189
190
template <size_t DEFAULT_SIZE>
191
bool MallocAdapter<DEFAULT_SIZE>::flush(size_t used, size_t requested) {
192
if (!_has_ownership) {
193
// can't just realloc a storage that we don't own
194
return false;
195
}
196
assert(_start != NULL, "invariant");
197
assert(used <= (size_t)(_end - _pos), "invariant");
198
assert(_pos + used <= _end, "invariant");
199
const size_t previous_storage_size = _end - _start;
200
const size_t new_storage_size = used + requested + (previous_storage_size * 2);
201
u1* const new_storage = JfrCHeapObj::new_array<u1>(new_storage_size);
202
if (!new_storage) {
203
return false;
204
}
205
const size_t previous_pos_offset = _pos - _start;
206
// migrate in-flight data
207
memcpy(new_storage, _start, previous_pos_offset + used);
208
JfrCHeapObj::free(_start, previous_storage_size);
209
_start = new_storage;
210
_pos = _start + previous_pos_offset;
211
_end = _start + new_storage_size;
212
return true;
213
}
214
215
class NoOwnershipAdapter {
216
private:
217
u1* _start;
218
u1* _pos;
219
u1* _end;
220
size_t _size;
221
222
public:
223
typedef u1 StorageType;
224
NoOwnershipAdapter(u1* storage, size_t size) : _start(storage), _pos(storage), _end(storage + size), _size(size) {}
225
NoOwnershipAdapter(u1* storage, Thread* thread) : _start(storage), _pos(storage), _end(storage), _size(0) {
226
ShouldNotCallThis();
227
}
228
NoOwnershipAdapter(Thread* thread) : _start(NULL), _pos(NULL), _end(NULL), _size(0) {
229
ShouldNotCallThis();
230
}
231
StorageType* storage() { return _start; }
232
const u1* start() const { return _start; }
233
u1* pos() { return _pos; }
234
void commit(u1* position) { _pos = position; }
235
const u1* end() const { return _end; }
236
void release() {}
237
bool flush(size_t used, size_t requested) {
238
// don't flush/expand a buffer that is not our own
239
_pos = _start;
240
return true;
241
}
242
};
243
244
#endif // SHARE_JFR_WRITERS_JFRSTORAGEADAPTER_HPP
245
246