Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.base/share/classes/java/nio/MappedMemoryUtils.java
41152 views
1
/*
2
* Copyright (c) 2020, 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 jdk.internal.misc.Unsafe;
29
30
import java.io.FileDescriptor;
31
import java.io.IOException;
32
import java.io.UncheckedIOException;
33
34
/* package */ class MappedMemoryUtils {
35
36
static boolean isLoaded(long address, boolean isSync, long size) {
37
// a sync mapped buffer is always loaded
38
if (isSync) {
39
return true;
40
}
41
if ((address == 0) || (size == 0))
42
return true;
43
long offset = mappingOffset(address);
44
long length = mappingLength(offset, size);
45
return isLoaded0(mappingAddress(address, offset), length, Bits.pageCount(length));
46
}
47
48
static void load(long address, boolean isSync, long size) {
49
// no need to load a sync mapped buffer
50
if (isSync) {
51
return;
52
}
53
if ((address == 0) || (size == 0))
54
return;
55
long offset = mappingOffset(address);
56
long length = mappingLength(offset, size);
57
load0(mappingAddress(address, offset), length);
58
59
// Read a byte from each page to bring it into memory. A checksum
60
// is computed as we go along to prevent the compiler from otherwise
61
// considering the loop as dead code.
62
Unsafe unsafe = Unsafe.getUnsafe();
63
int ps = Bits.pageSize();
64
long count = Bits.pageCount(length);
65
long a = mappingAddress(address, offset);
66
byte x = 0;
67
for (long i=0; i<count; i++) {
68
// TODO consider changing to getByteOpaque thus avoiding
69
// dead code elimination and the need to calculate a checksum
70
x ^= unsafe.getByte(a);
71
a += ps;
72
}
73
if (unused != 0)
74
unused = x;
75
}
76
77
// not used, but a potential target for a store, see load() for details.
78
private static byte unused;
79
80
static void unload(long address, boolean isSync, long size) {
81
// no need to load a sync mapped buffer
82
if (isSync) {
83
return;
84
}
85
if ((address == 0) || (size == 0))
86
return;
87
long offset = mappingOffset(address);
88
long length = mappingLength(offset, size);
89
unload0(mappingAddress(address, offset), length);
90
}
91
92
static void force(FileDescriptor fd, long address, boolean isSync, long index, long length) {
93
if (isSync) {
94
// simply force writeback of associated cache lines
95
Unsafe.getUnsafe().writebackMemory(address + index, length);
96
} else {
97
// force writeback via file descriptor
98
long offset = mappingOffset(address, index);
99
try {
100
force0(fd, mappingAddress(address, offset, index), mappingLength(offset, length));
101
} catch (IOException cause) {
102
throw new UncheckedIOException(cause);
103
}
104
}
105
}
106
107
// native methods
108
109
private static native boolean isLoaded0(long address, long length, long pageCount);
110
private static native void load0(long address, long length);
111
private static native void unload0(long address, long length);
112
private static native void force0(FileDescriptor fd, long address, long length) throws IOException;
113
114
// utility methods
115
116
// Returns the distance (in bytes) of the buffer start from the
117
// largest page aligned address of the mapping less than or equal
118
// to the start address.
119
private static long mappingOffset(long address) {
120
return mappingOffset(address, 0);
121
}
122
123
// Returns the distance (in bytes) of the buffer element
124
// identified by index from the largest page aligned address of
125
// the mapping less than or equal to the element address. Computed
126
// each time to avoid storing in every direct buffer.
127
private static long mappingOffset(long address, long index) {
128
int ps = Bits.pageSize();
129
long indexAddress = address + index;
130
long baseAddress = alignDown(indexAddress, ps);
131
return indexAddress - baseAddress;
132
}
133
134
// Given an offset previously obtained from calling
135
// mappingOffset() returns the largest page aligned address of the
136
// mapping less than or equal to the buffer start address.
137
private static long mappingAddress(long address, long mappingOffset) {
138
return mappingAddress(address, mappingOffset, 0);
139
}
140
141
// Given an offset previously otained from calling
142
// mappingOffset(index) returns the largest page aligned address
143
// of the mapping less than or equal to the address of the buffer
144
// element identified by index.
145
private static long mappingAddress(long address, long mappingOffset, long index) {
146
long indexAddress = address + index;
147
return indexAddress - mappingOffset;
148
}
149
150
// given a mappingOffset previously otained from calling
151
// mappingOffset(index) return that offset added to the supplied
152
// length.
153
private static long mappingLength(long mappingOffset, long length) {
154
return length + mappingOffset;
155
}
156
157
// align address down to page size
158
private static long alignDown(long address, int pageSize) {
159
// pageSize must be a power of 2
160
return address & ~(pageSize - 1);
161
}
162
}
163
164