Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/jdk/java/foreign/TestLayouts.java
41145 views
1
/*
2
* Copyright (c) 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
* @test
26
* @run testng TestLayouts
27
*/
28
29
import jdk.incubator.foreign.*;
30
31
import java.lang.invoke.VarHandle;
32
import java.nio.ByteOrder;
33
import java.util.function.LongFunction;
34
import java.util.stream.Stream;
35
36
import org.testng.annotations.*;
37
import static org.testng.Assert.*;
38
39
public class TestLayouts {
40
41
@Test(dataProvider = "badLayoutSizes", expectedExceptions = IllegalArgumentException.class)
42
public void testBadLayoutSize(SizedLayoutFactory factory, long size) {
43
factory.make(size);
44
}
45
46
@Test(dataProvider = "badAlignments", expectedExceptions = IllegalArgumentException.class)
47
public void testBadLayoutAlignment(MemoryLayout layout, long alignment) {
48
layout.withBitAlignment(alignment);
49
}
50
51
@Test
52
public void testVLAInStruct() {
53
MemoryLayout layout = MemoryLayout.structLayout(
54
MemoryLayouts.JAVA_INT.withName("size"),
55
MemoryLayout.paddingLayout(32),
56
MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_DOUBLE).withName("arr"));
57
assertFalse(layout.hasSize());
58
VarHandle size_handle = layout.varHandle(int.class, MemoryLayout.PathElement.groupElement("size"));
59
VarHandle array_elem_handle = layout.varHandle(double.class,
60
MemoryLayout.PathElement.groupElement("arr"),
61
MemoryLayout.PathElement.sequenceElement());
62
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
63
MemorySegment segment = MemorySegment.allocateNative(
64
layout.map(l -> ((SequenceLayout)l).withElementCount(4), MemoryLayout.PathElement.groupElement("arr")), scope);
65
size_handle.set(segment, 4);
66
for (int i = 0 ; i < 4 ; i++) {
67
array_elem_handle.set(segment, i, (double)i);
68
}
69
//check
70
assertEquals(4, (int)size_handle.get(segment));
71
for (int i = 0 ; i < 4 ; i++) {
72
assertEquals((double)i, (double)array_elem_handle.get(segment, i));
73
}
74
}
75
}
76
77
@Test
78
public void testVLAInSequence() {
79
MemoryLayout layout = MemoryLayout.structLayout(
80
MemoryLayouts.JAVA_INT.withName("size"),
81
MemoryLayout.paddingLayout(32),
82
MemoryLayout.sequenceLayout(1, MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_DOUBLE)).withName("arr"));
83
assertFalse(layout.hasSize());
84
VarHandle size_handle = layout.varHandle(int.class, MemoryLayout.PathElement.groupElement("size"));
85
VarHandle array_elem_handle = layout.varHandle(double.class,
86
MemoryLayout.PathElement.groupElement("arr"),
87
MemoryLayout.PathElement.sequenceElement(0),
88
MemoryLayout.PathElement.sequenceElement());
89
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
90
MemorySegment segment = MemorySegment.allocateNative(
91
layout.map(l -> ((SequenceLayout)l).withElementCount(4), MemoryLayout.PathElement.groupElement("arr"), MemoryLayout.PathElement.sequenceElement()), scope);
92
size_handle.set(segment, 4);
93
for (int i = 0 ; i < 4 ; i++) {
94
array_elem_handle.set(segment, i, (double)i);
95
}
96
//check
97
assertEquals(4, (int)size_handle.get(segment));
98
for (int i = 0 ; i < 4 ; i++) {
99
assertEquals((double)i, (double)array_elem_handle.get(segment, i));
100
}
101
}
102
}
103
104
@Test
105
public void testIndexedSequencePath() {
106
MemoryLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayouts.JAVA_INT);
107
try (ResourceScope scope = ResourceScope.newConfinedScope()) {
108
MemorySegment segment = MemorySegment.allocateNative(seq, scope);
109
VarHandle indexHandle = seq.varHandle(int.class, MemoryLayout.PathElement.sequenceElement());
110
// init segment
111
for (int i = 0 ; i < 10 ; i++) {
112
indexHandle.set(segment, (long)i, i);
113
}
114
//check statically indexed handles
115
for (int i = 0 ; i < 10 ; i++) {
116
VarHandle preindexHandle = seq.varHandle(int.class, MemoryLayout.PathElement.sequenceElement(i));
117
int expected = (int)indexHandle.get(segment, (long)i);
118
int found = (int)preindexHandle.get(segment);
119
assertEquals(expected, found);
120
}
121
}
122
}
123
124
@Test(dataProvider = "unboundLayouts", expectedExceptions = UnsupportedOperationException.class)
125
public void testUnboundSize(MemoryLayout layout, long align) {
126
layout.bitSize();
127
}
128
129
@Test(dataProvider = "unboundLayouts")
130
public void testUnboundAlignment(MemoryLayout layout, long align) {
131
assertEquals(align, layout.bitAlignment());
132
}
133
134
@Test(dataProvider = "unboundLayouts")
135
public void testUnboundEquals(MemoryLayout layout, long align) {
136
assertTrue(layout.equals(layout));
137
}
138
139
@Test(dataProvider = "unboundLayouts")
140
public void testUnboundHash(MemoryLayout layout, long align) {
141
layout.hashCode();
142
}
143
144
@Test(expectedExceptions = IllegalArgumentException.class)
145
public void testBadUnboundSequenceLayoutResize() {
146
SequenceLayout seq = MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT);
147
seq.withElementCount(-1);
148
}
149
150
@Test(expectedExceptions = IllegalArgumentException.class)
151
public void testBadBoundSequenceLayoutResize() {
152
SequenceLayout seq = MemoryLayout.sequenceLayout(10, MemoryLayouts.JAVA_INT);
153
seq.withElementCount(-1);
154
}
155
156
@Test
157
public void testEmptyGroup() {
158
MemoryLayout struct = MemoryLayout.structLayout();
159
assertEquals(struct.bitSize(), 0);
160
assertEquals(struct.bitAlignment(), 1);
161
162
MemoryLayout union = MemoryLayout.unionLayout();
163
assertEquals(union.bitSize(), 0);
164
assertEquals(union.bitAlignment(), 1);
165
}
166
167
@Test
168
public void testStructSizeAndAlign() {
169
MemoryLayout struct = MemoryLayout.structLayout(
170
MemoryLayout.paddingLayout(8),
171
MemoryLayouts.JAVA_BYTE,
172
MemoryLayouts.JAVA_CHAR,
173
MemoryLayouts.JAVA_INT,
174
MemoryLayouts.JAVA_LONG
175
);
176
assertEquals(struct.byteSize(), 1 + 1 + 2 + 4 + 8);
177
assertEquals(struct.byteAlignment(), MemoryLayouts.ADDRESS.byteAlignment());
178
}
179
180
@Test(dataProvider="basicLayouts")
181
public void testPaddingNoAlign(MemoryLayout layout) {
182
assertEquals(MemoryLayout.paddingLayout(layout.bitSize()).bitAlignment(), 1);
183
}
184
185
@Test(dataProvider="basicLayouts")
186
public void testStructPaddingAndAlign(MemoryLayout layout) {
187
MemoryLayout struct = MemoryLayout.structLayout(
188
layout, MemoryLayout.paddingLayout(128 - layout.bitSize()));
189
assertEquals(struct.bitAlignment(), layout.bitAlignment());
190
}
191
192
@Test(dataProvider="basicLayouts")
193
public void testUnionPaddingAndAlign(MemoryLayout layout) {
194
MemoryLayout struct = MemoryLayout.unionLayout(
195
layout, MemoryLayout.paddingLayout(128 - layout.bitSize()));
196
assertEquals(struct.bitAlignment(), layout.bitAlignment());
197
}
198
199
@Test
200
public void testUnionSizeAndAlign() {
201
MemoryLayout struct = MemoryLayout.unionLayout(
202
MemoryLayouts.JAVA_BYTE,
203
MemoryLayouts.JAVA_CHAR,
204
MemoryLayouts.JAVA_INT,
205
MemoryLayouts.JAVA_LONG
206
);
207
assertEquals(struct.byteSize(), 8);
208
assertEquals(struct.byteAlignment(), MemoryLayouts.ADDRESS.byteAlignment());
209
}
210
211
@Test(dataProvider = "layoutKinds")
212
public void testPadding(LayoutKind kind) {
213
assertEquals(kind == LayoutKind.PADDING, kind.layout.isPadding());
214
}
215
216
@Test(dataProvider="layoutsAndAlignments")
217
public void testAlignmentString(MemoryLayout layout, long bitAlign) {
218
long[] alignments = { 8, 16, 32, 64, 128 };
219
for (long a : alignments) {
220
if (layout.bitAlignment() == layout.bitSize()) {
221
assertFalse(layout.toString().contains("%"));
222
assertEquals(layout.withBitAlignment(a).toString().contains("%"), a != bitAlign);
223
}
224
}
225
}
226
227
@DataProvider(name = "badLayoutSizes")
228
public Object[][] factoriesAndSizes() {
229
return new Object[][] {
230
{ SizedLayoutFactory.VALUE_BE, 0 },
231
{ SizedLayoutFactory.VALUE_BE, -1 },
232
{ SizedLayoutFactory.VALUE_LE, 0 },
233
{ SizedLayoutFactory.VALUE_LE, -1 },
234
{ SizedLayoutFactory.PADDING, 0 },
235
{ SizedLayoutFactory.PADDING, -1 },
236
{ SizedLayoutFactory.SEQUENCE, -1 }
237
};
238
}
239
240
@DataProvider(name = "unboundLayouts")
241
public Object[][] unboundLayouts() {
242
return new Object[][] {
243
{ MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT), 32 },
244
{ MemoryLayout.sequenceLayout(MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT)), 32 },
245
{ MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT)), 32 },
246
{ MemoryLayout.structLayout(MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT)), 32 },
247
{ MemoryLayout.structLayout(MemoryLayout.sequenceLayout(MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT))), 32 },
248
{ MemoryLayout.structLayout(MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT))), 32 },
249
{ MemoryLayout.unionLayout(MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT)), 32 },
250
{ MemoryLayout.unionLayout(MemoryLayout.sequenceLayout(MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT))), 32 },
251
{ MemoryLayout.unionLayout(MemoryLayout.sequenceLayout(4, MemoryLayout.sequenceLayout(MemoryLayouts.JAVA_INT))), 32 },
252
};
253
}
254
255
@DataProvider(name = "badAlignments")
256
public Object[][] layoutsAndBadAlignments() {
257
LayoutKind[] layoutKinds = LayoutKind.values();
258
Object[][] values = new Object[layoutKinds.length * 2][2];
259
for (int i = 0; i < layoutKinds.length ; i++) {
260
values[i * 2] = new Object[] { layoutKinds[i].layout, 3 }; // smaller than 8
261
values[(i * 2) + 1] = new Object[] { layoutKinds[i].layout, 18 }; // not a power of 2
262
}
263
return values;
264
}
265
266
@DataProvider(name = "layoutKinds")
267
public Object[][] layoutsKinds() {
268
return Stream.of(LayoutKind.values())
269
.map(lk -> new Object[] { lk })
270
.toArray(Object[][]::new);
271
}
272
273
enum SizedLayoutFactory {
274
VALUE_LE(size -> MemoryLayout.valueLayout(size, ByteOrder.LITTLE_ENDIAN)),
275
VALUE_BE(size -> MemoryLayout.valueLayout(size, ByteOrder.BIG_ENDIAN)),
276
PADDING(MemoryLayout::paddingLayout),
277
SEQUENCE(size -> MemoryLayout.sequenceLayout(size, MemoryLayouts.PAD_8));
278
279
private final LongFunction<MemoryLayout> factory;
280
281
SizedLayoutFactory(LongFunction<MemoryLayout> factory) {
282
this.factory = factory;
283
}
284
285
MemoryLayout make(long size) {
286
return factory.apply(size);
287
}
288
}
289
290
enum LayoutKind {
291
VALUE_LE(MemoryLayouts.BITS_8_LE),
292
VALUE_BE(MemoryLayouts.BITS_8_BE),
293
PADDING(MemoryLayouts.PAD_8),
294
SEQUENCE(MemoryLayout.sequenceLayout(1, MemoryLayouts.PAD_8)),
295
STRUCT(MemoryLayout.structLayout(MemoryLayouts.PAD_8, MemoryLayouts.PAD_8)),
296
UNION(MemoryLayout.unionLayout(MemoryLayouts.PAD_8, MemoryLayouts.PAD_8));
297
298
final MemoryLayout layout;
299
300
LayoutKind(MemoryLayout layout) {
301
this.layout = layout;
302
}
303
}
304
305
@DataProvider(name = "basicLayouts")
306
public Object[][] basicLayouts() {
307
return Stream.of(basicLayouts)
308
.map(l -> new Object[] { l })
309
.toArray(Object[][]::new);
310
}
311
312
@DataProvider(name = "layoutsAndAlignments")
313
public Object[][] layoutsAndAlignments() {
314
Object[][] layoutsAndAlignments = new Object[basicLayouts.length * 4][];
315
int i = 0;
316
//add basic layouts
317
for (MemoryLayout l : basicLayouts) {
318
layoutsAndAlignments[i++] = new Object[] { l, l.bitAlignment() };
319
}
320
//add basic layouts wrapped in a sequence with given size
321
for (MemoryLayout l : basicLayouts) {
322
layoutsAndAlignments[i++] = new Object[] { MemoryLayout.sequenceLayout(4, l), l.bitAlignment() };
323
}
324
//add basic layouts wrapped in a struct
325
for (MemoryLayout l : basicLayouts) {
326
layoutsAndAlignments[i++] = new Object[] { MemoryLayout.structLayout(l), l.bitAlignment() };
327
}
328
//add basic layouts wrapped in a union
329
for (MemoryLayout l : basicLayouts) {
330
layoutsAndAlignments[i++] = new Object[] { MemoryLayout.unionLayout(l), l.bitAlignment() };
331
}
332
return layoutsAndAlignments;
333
}
334
335
static MemoryLayout[] basicLayouts = {
336
MemoryLayouts.JAVA_BYTE,
337
MemoryLayouts.JAVA_CHAR,
338
MemoryLayouts.JAVA_SHORT,
339
MemoryLayouts.JAVA_INT,
340
MemoryLayouts.JAVA_FLOAT,
341
MemoryLayouts.JAVA_LONG,
342
MemoryLayouts.JAVA_DOUBLE,
343
};
344
}
345
346