Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/nio/MappedByteBuffer.java
41152 views
1
/*
2
* Copyright (c) 2000, 2021, 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. Oracle designates this
8
* particular file as subject to the "Classpath" exception as provided
9
* by Oracle in the LICENSE file that accompanied this code.
10
*
11
* This code is distributed in the hope that it will be useful, but WITHOUT
12
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14
* version 2 for more details (a copy is included in the LICENSE file that
15
* accompanied this code).
16
*
17
* You should have received a copy of the GNU General Public License version
18
* 2 along with this work; if not, write to the Free Software Foundation,
19
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20
*
21
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22
* or visit www.oracle.com if you need additional information or have any
23
* questions.
24
*/
25
26
package java.nio;
27
28
import java.io.FileDescriptor;
29
import java.io.UncheckedIOException;
30
import java.lang.ref.Reference;
31
import java.util.Objects;
32
33
import jdk.internal.access.foreign.MemorySegmentProxy;
34
import jdk.internal.access.foreign.UnmapperProxy;
35
import jdk.internal.misc.ScopedMemoryAccess;
36
import jdk.internal.misc.Unsafe;
37
38
39
/**
40
* A direct byte buffer whose content is a memory-mapped region of a file.
41
*
42
* <p> Mapped byte buffers are created via the {@link
43
* java.nio.channels.FileChannel#map FileChannel.map} method. This class
44
* extends the {@link ByteBuffer} class with operations that are specific to
45
* memory-mapped file regions.
46
*
47
* <p> A mapped byte buffer and the file mapping that it represents remain
48
* valid until the buffer itself is garbage-collected.
49
*
50
* <p> The content of a mapped byte buffer can change at any time, for example
51
* if the content of the corresponding region of the mapped file is changed by
52
* this program or another. Whether or not such changes occur, and when they
53
* occur, is operating-system dependent and therefore unspecified.
54
*
55
* <a id="inaccess"></a><p> All or part of a mapped byte buffer may become
56
* inaccessible at any time, for example if the mapped file is truncated. An
57
* attempt to access an inaccessible region of a mapped byte buffer will not
58
* change the buffer's content and will cause an unspecified exception to be
59
* thrown either at the time of the access or at some later time. It is
60
* therefore strongly recommended that appropriate precautions be taken to
61
* avoid the manipulation of a mapped file by this program, or by a
62
* concurrently running program, except to read or write the file's content.
63
*
64
* <p> Mapped byte buffers otherwise behave no differently than ordinary direct
65
* byte buffers. </p>
66
*
67
*
68
* @author Mark Reinhold
69
* @author JSR-51 Expert Group
70
* @since 1.4
71
*/
72
73
public abstract class MappedByteBuffer
74
extends ByteBuffer
75
{
76
77
// This is a little bit backwards: By rights MappedByteBuffer should be a
78
// subclass of DirectByteBuffer, but to keep the spec clear and simple, and
79
// for optimization purposes, it's easier to do it the other way around.
80
// This works because DirectByteBuffer is a package-private class.
81
82
// For mapped buffers, a FileDescriptor that may be used for mapping
83
// operations if valid; null if the buffer is not mapped.
84
private final FileDescriptor fd;
85
86
// A flag true if this buffer is mapped against non-volatile
87
// memory using one of the extended FileChannel.MapMode modes,
88
// MapMode.READ_ONLY_SYNC or MapMode.READ_WRITE_SYNC and false if
89
// it is mapped using any of the other modes. This flag only
90
// determines the behavior of force operations.
91
private final boolean isSync;
92
93
static final ScopedMemoryAccess SCOPED_MEMORY_ACCESS = ScopedMemoryAccess.getScopedMemoryAccess();
94
95
// This should only be invoked by the DirectByteBuffer constructors
96
//
97
MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
98
FileDescriptor fd, boolean isSync, MemorySegmentProxy segment) {
99
super(mark, pos, lim, cap, segment);
100
this.fd = fd;
101
this.isSync = isSync;
102
}
103
104
MappedByteBuffer(int mark, int pos, int lim, int cap, // package-private
105
boolean isSync, MemorySegmentProxy segment) {
106
super(mark, pos, lim, cap, segment);
107
this.fd = null;
108
this.isSync = isSync;
109
}
110
111
MappedByteBuffer(int mark, int pos, int lim, int cap, MemorySegmentProxy segment) { // package-private
112
super(mark, pos, lim, cap, segment);
113
this.fd = null;
114
this.isSync = false;
115
}
116
117
UnmapperProxy unmapper() {
118
return fd != null ?
119
new UnmapperProxy() {
120
@Override
121
public long address() {
122
return address;
123
}
124
125
@Override
126
public FileDescriptor fileDescriptor() {
127
return fd;
128
}
129
130
@Override
131
public boolean isSync() {
132
return isSync;
133
}
134
135
@Override
136
public void unmap() {
137
Unsafe.getUnsafe().invokeCleaner(MappedByteBuffer.this);
138
}
139
} : null;
140
}
141
142
/**
143
* Tells whether this buffer was mapped against a non-volatile
144
* memory device by passing one of the sync map modes {@link
145
* jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC
146
* ExtendedMapModeMapMode#READ_ONLY_SYNC} or {@link
147
* jdk.nio.mapmode.ExtendedMapMode#READ_ONLY_SYNC
148
* ExtendedMapMode#READ_WRITE_SYNC} in the call to {@link
149
* java.nio.channels.FileChannel#map FileChannel.map} or was
150
* mapped by passing one of the other map modes.
151
*
152
* @return true if the file was mapped using one of the sync map
153
* modes, otherwise false.
154
*/
155
final boolean isSync() { // package-private
156
return isSync;
157
}
158
159
/**
160
* Returns the {@code FileDescriptor} associated with this
161
* {@code MappedByteBuffer}.
162
*
163
* @return the buffer's file descriptor; may be {@code null}
164
*/
165
final FileDescriptor fileDescriptor() { // package-private
166
return fd;
167
}
168
169
/**
170
* Tells whether or not this buffer's content is resident in physical
171
* memory.
172
*
173
* <p> A return value of {@code true} implies that it is highly likely
174
* that all of the data in this buffer is resident in physical memory and
175
* may therefore be accessed without incurring any virtual-memory page
176
* faults or I/O operations. A return value of {@code false} does not
177
* necessarily imply that the buffer's content is not resident in physical
178
* memory.
179
*
180
* <p> The returned value is a hint, rather than a guarantee, because the
181
* underlying operating system may have paged out some of the buffer's data
182
* by the time that an invocation of this method returns. </p>
183
*
184
* @return {@code true} if it is likely that this buffer's content
185
* is resident in physical memory
186
*/
187
public final boolean isLoaded() {
188
if (fd == null) {
189
return true;
190
}
191
return SCOPED_MEMORY_ACCESS.isLoaded(scope(), address, isSync, capacity());
192
}
193
194
/**
195
* Loads this buffer's content into physical memory.
196
*
197
* <p> This method makes a best effort to ensure that, when it returns,
198
* this buffer's content is resident in physical memory. Invoking this
199
* method may cause some number of page faults and I/O operations to
200
* occur. </p>
201
*
202
* @return This buffer
203
*/
204
public final MappedByteBuffer load() {
205
if (fd == null) {
206
return this;
207
}
208
try {
209
SCOPED_MEMORY_ACCESS.load(scope(), address, isSync, capacity());
210
} finally {
211
Reference.reachabilityFence(this);
212
}
213
return this;
214
}
215
216
/**
217
* Forces any changes made to this buffer's content to be written to the
218
* storage device containing the mapped file. The region starts at index
219
* zero in this buffer and is {@code capacity()} bytes. An invocation of
220
* this method behaves in exactly the same way as the invocation
221
* {@link force(int,int) force(0,capacity())}.
222
*
223
* <p> If the file mapped into this buffer resides on a local storage
224
* device then when this method returns it is guaranteed that all changes
225
* made to the buffer since it was created, or since this method was last
226
* invoked, will have been written to that device.
227
*
228
* <p> If the file does not reside on a local device then no such guarantee
229
* is made.
230
*
231
* <p> If this buffer was not mapped in read/write mode ({@link
232
* java.nio.channels.FileChannel.MapMode#READ_WRITE}) then
233
* invoking this method may have no effect. In particular, the
234
* method has no effect for buffers mapped in read-only or private
235
* mapping modes. This method may or may not have an effect for
236
* implementation-specific mapping modes. </p>
237
*
238
* @throws UncheckedIOException
239
* If an I/O error occurs writing the buffer's content to the
240
* storage device containing the mapped file
241
*
242
* @return This buffer
243
*/
244
public final MappedByteBuffer force() {
245
if (fd == null) {
246
return this;
247
}
248
int capacity = capacity();
249
if (isSync || ((address != 0) && (capacity != 0))) {
250
return force(0, capacity);
251
}
252
return this;
253
}
254
255
/**
256
* Forces any changes made to a region of this buffer's content to
257
* be written to the storage device containing the mapped
258
* file. The region starts at the given {@code index} in this
259
* buffer and is {@code length} bytes.
260
*
261
* <p> If the file mapped into this buffer resides on a local
262
* storage device then when this method returns it is guaranteed
263
* that all changes made to the selected region buffer since it
264
* was created, or since this method was last invoked, will have
265
* been written to that device. The force operation is free to
266
* write bytes that lie outside the specified region, for example
267
* to ensure that data blocks of some device-specific granularity
268
* are transferred in their entirety.
269
*
270
* <p> If the file does not reside on a local device then no such
271
* guarantee is made.
272
*
273
* <p> If this buffer was not mapped in read/write mode ({@link
274
* java.nio.channels.FileChannel.MapMode#READ_WRITE}) then
275
* invoking this method may have no effect. In particular, the
276
* method has no effect for buffers mapped in read-only or private
277
* mapping modes. This method may or may not have an effect for
278
* implementation-specific mapping modes. </p>
279
*
280
* @param index
281
* The index of the first byte in the buffer region that is
282
* to be written back to storage; must be non-negative
283
* and less than {@code capacity()}
284
*
285
* @param length
286
* The length of the region in bytes; must be non-negative
287
* and no larger than {@code capacity() - index}
288
*
289
* @throws IndexOutOfBoundsException
290
* if the preconditions on the index and length do not
291
* hold.
292
*
293
* @throws UncheckedIOException
294
* If an I/O error occurs writing the buffer's content to the
295
* storage device containing the mapped file
296
*
297
* @return This buffer
298
*
299
* @since 13
300
*/
301
public final MappedByteBuffer force(int index, int length) {
302
if (fd == null) {
303
return this;
304
}
305
int capacity = capacity();
306
if ((address != 0) && (capacity != 0)) {
307
// check inputs
308
Objects.checkFromIndexSize(index, length, capacity);
309
SCOPED_MEMORY_ACCESS.force(scope(), fd, address, isSync, index, length);
310
}
311
return this;
312
}
313
314
// -- Covariant return type overrides
315
316
/**
317
* {@inheritDoc}
318
*/
319
@Override
320
public final MappedByteBuffer position(int newPosition) {
321
super.position(newPosition);
322
return this;
323
}
324
325
/**
326
* {@inheritDoc}
327
*/
328
@Override
329
public final MappedByteBuffer limit(int newLimit) {
330
super.limit(newLimit);
331
return this;
332
}
333
334
/**
335
* {@inheritDoc}
336
*/
337
@Override
338
public final MappedByteBuffer mark() {
339
super.mark();
340
return this;
341
}
342
343
/**
344
* {@inheritDoc}
345
*/
346
@Override
347
public final MappedByteBuffer reset() {
348
super.reset();
349
return this;
350
}
351
352
/**
353
* {@inheritDoc}
354
*/
355
@Override
356
public final MappedByteBuffer clear() {
357
super.clear();
358
return this;
359
}
360
361
/**
362
* {@inheritDoc}
363
*/
364
@Override
365
public final MappedByteBuffer flip() {
366
super.flip();
367
return this;
368
}
369
370
/**
371
* {@inheritDoc}
372
*/
373
@Override
374
public final MappedByteBuffer rewind() {
375
super.rewind();
376
return this;
377
}
378
379
/**
380
* {@inheritDoc}
381
*
382
* <p> Reading bytes into physical memory by invoking {@code load()} on the
383
* returned buffer, or writing bytes to the storage device by invoking
384
* {@code force()} on the returned buffer, will only act on the sub-range
385
* of this buffer that the returned buffer represents, namely
386
* {@code [position(),limit())}.
387
*/
388
@Override
389
public abstract MappedByteBuffer slice();
390
391
/**
392
* {@inheritDoc}
393
*
394
* <p> Reading bytes into physical memory by invoking {@code load()} on the
395
* returned buffer, or writing bytes to the storage device by invoking
396
* {@code force()} on the returned buffer, will only act on the sub-range
397
* of this buffer that the returned buffer represents, namely
398
* {@code [index,index+length)}, where {@code index} and {@code length} are
399
* assumed to satisfy the preconditions.
400
*/
401
@Override
402
public abstract MappedByteBuffer slice(int index, int length);
403
404
/**
405
* {@inheritDoc}
406
*/
407
@Override
408
public abstract MappedByteBuffer duplicate();
409
410
/**
411
* {@inheritDoc}
412
*/
413
@Override
414
public abstract MappedByteBuffer compact();
415
}
416
417