|
1 | 1 | /* |
2 | | - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. |
| 2 | + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. |
3 | 3 | * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 | 4 | * |
5 | 5 | * This code is free software; you can redistribute it and/or modify it |
|
29 | 29 | * @run testng/othervm -Djava.lang.invoke.VarHandle.VAR_HANDLE_GUARDS=false -Djava.lang.invoke.VarHandle.VAR_HANDLE_IDENTITY_ADAPT=true -Xverify:all TestAccessModes |
30 | 30 | */ |
31 | 31 |
|
32 | | -import java.lang.foreign.AddressLayout; |
33 | | -import java.lang.foreign.Arena; |
34 | | -import java.lang.foreign.MemoryLayout; |
35 | | -import java.lang.foreign.MemorySegment; |
36 | | -import java.lang.foreign.ValueLayout; |
| 32 | +import java.lang.foreign.*; |
37 | 33 | import java.lang.invoke.MethodHandle; |
38 | 34 | import java.lang.invoke.MethodHandles; |
39 | 35 | import java.lang.invoke.MethodType; |
|
50 | 46 | public class TestAccessModes { |
51 | 47 |
|
52 | 48 | @Test(dataProvider = "segmentsAndLayoutsAndModes") |
53 | | - public void testAccessModes(MemorySegment segment, ValueLayout layout, AccessMode mode) throws Throwable { |
54 | | - VarHandle varHandle = layout.varHandle(); |
| 49 | + public void testAccessModes(MemorySegment segment, MemoryLayout layout, AccessMode mode) throws Throwable { |
| 50 | + VarHandle varHandle = layout instanceof ValueLayout ? |
| 51 | + layout.varHandle() : |
| 52 | + layout.varHandle(MemoryLayout.PathElement.groupElement(0)); |
55 | 53 | MethodHandle methodHandle = varHandle.toMethodHandle(mode); |
56 | | - boolean compatible = AccessModeKind.supportedModes(layout).contains(AccessModeKind.of(mode)); |
| 54 | + boolean compatible = AccessModeKind.supportedModes(accessLayout(layout)).contains(AccessModeKind.of(mode)); |
57 | 55 | try { |
58 | 56 | Object o = methodHandle.invokeWithArguments(makeArgs(segment, varHandle.accessModeType(mode))); |
59 | 57 | assertTrue(compatible); |
60 | 58 | } catch (UnsupportedOperationException ex) { |
61 | 59 | assertFalse(compatible); |
62 | 60 | } catch (IllegalArgumentException ex) { |
63 | 61 | // access is unaligned, but access mode is supported |
64 | | - assertTrue(compatible); |
| 62 | + assertTrue(compatible || |
| 63 | + (layout instanceof GroupLayout && segment.maxByteAlignment() < layout.byteAlignment())); |
65 | 64 | } |
66 | 65 | } |
67 | 66 |
|
| 67 | + static ValueLayout accessLayout(MemoryLayout layout) { |
| 68 | + return switch (layout) { |
| 69 | + case ValueLayout vl -> vl; |
| 70 | + case GroupLayout gl -> accessLayout(gl.memberLayouts().get(0)); |
| 71 | + default -> throw new IllegalStateException(); |
| 72 | + }; |
| 73 | + } |
| 74 | + |
68 | 75 | Object[] makeArgs(MemorySegment segment, MethodType type) throws Throwable { |
69 | 76 | List<Object> args = new ArrayList<>(); |
70 | 77 | args.add(segment); |
@@ -145,6 +152,7 @@ static MemoryLayout[] layouts() { |
145 | 152 | for (MemoryLayout layout : valueLayouts) { |
146 | 153 | for (int align : new int[] { 1, 2, 4, 8 }) { |
147 | 154 | layouts.add(layout.withByteAlignment(align)); |
| 155 | + layouts.add(MemoryLayout.structLayout(layout.withByteAlignment(align))); |
148 | 156 | } |
149 | 157 | } |
150 | 158 | return layouts.toArray(new MemoryLayout[0]); |
|
0 commit comments