Skip to content

Commit 78d5fdf

Browse files
authored
Merge pull request #155 from ChengJin01/jep389_implement_valist_power_zlinux_jdk17
[JEP389/412]Implement VaList on Power and zLinux in JDK17
2 parents f6a0391 + 847e416 commit 78d5fdf

File tree

6 files changed

+1554
-379
lines changed

6 files changed

+1554
-379
lines changed
Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
/*
2+
* Copyright (c) 2020, 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+
/*
27+
* ===========================================================================
28+
* (c) Copyright IBM Corp. 2022, 2022 All Rights Reserved
29+
* ===========================================================================
30+
*/
31+
32+
package jdk.internal.foreign.abi.ppc64;
33+
34+
import java.lang.invoke.VarHandle;
35+
36+
import jdk.incubator.foreign.CLinker.TypeKind;
37+
import jdk.incubator.foreign.GroupLayout;
38+
import jdk.incubator.foreign.MemoryAddress;
39+
import jdk.incubator.foreign.MemoryLayout;
40+
import jdk.incubator.foreign.MemorySegment;
41+
import jdk.incubator.foreign.ValueLayout;
42+
import jdk.internal.foreign.abi.SharedUtils;
43+
import static jdk.incubator.foreign.CLinker.*;
44+
import static jdk.incubator.foreign.CLinker.TypeKind.*;
45+
46+
/**
47+
* This class enumerates three argument types for Linux/ppc64le, in which case the code
48+
* is backported from OpenJDK19 with modifications against the implementation of TypeClass
49+
* on x64/windows as the template.
50+
*/
51+
public enum TypeClass {
52+
PRIMITIVE, /* Intended for all primitive types */
53+
POINTER,
54+
STRUCT;
55+
56+
private static String osName = System.getProperty("os.name").toLowerCase();
57+
/* long long is 64 bits on AIX/ppc64, which is the same as Windows */
58+
private static ValueLayout longLayout = osName.contains("aix") ? C_LONG_LONG : C_LONG;
59+
60+
public static VarHandle classifyVarHandle(ValueLayout layout) {
61+
VarHandle argHandle = null;
62+
Class<?> carrier = classifyCarrier(layout);
63+
64+
/* According to the API Spec, all non-long integral types are promoted to long
65+
* while a float is promoted to double.
66+
*/
67+
if ((carrier == byte.class)
68+
|| (carrier == short.class)
69+
|| (carrier == int.class)
70+
|| (carrier == long.class)
71+
) {
72+
argHandle = SharedUtils.vhPrimitiveOrAddress(long.class, longLayout);
73+
} else if (carrier == float.class) {
74+
argHandle = SharedUtils.vhPrimitiveOrAddress(double.class, C_DOUBLE);
75+
} else if ((carrier == double.class)
76+
|| (carrier == MemoryAddress.class)
77+
) {
78+
argHandle = SharedUtils.vhPrimitiveOrAddress(carrier, layout);
79+
} else {
80+
throw new IllegalStateException("Unspported carrier: " + carrier.getName());
81+
}
82+
83+
return argHandle;
84+
}
85+
86+
public static Class<?> classifyCarrier(MemoryLayout layout) {
87+
Class<?> carrier = null;
88+
89+
if (layout instanceof ValueLayout) {
90+
carrier = classifyValueLayoutCarrier((ValueLayout)layout);
91+
} else if (layout instanceof GroupLayout) {
92+
carrier = MemorySegment.class;
93+
} else {
94+
throw new IllegalArgumentException("Unsupported layout: " + layout);
95+
}
96+
97+
return carrier;
98+
}
99+
100+
private static Class<?> classifyValueLayoutCarrier(ValueLayout layout) {
101+
Class<?> carrier = null;
102+
103+
/* Extract the kind from the specified layout with the ATTR_NAME "abi/kind".
104+
* e.g. b32[abi/kind=INT]
105+
*/
106+
TypeKind kind = (TypeKind)layout.attribute(TypeKind.ATTR_NAME)
107+
.orElseThrow(() -> new IllegalArgumentException("The layout's ABI class is empty"));
108+
109+
switch (kind) {
110+
case CHAR:
111+
carrier = byte.class;
112+
break;
113+
case SHORT:
114+
carrier = short.class;
115+
break;
116+
case INT:
117+
carrier = int.class;
118+
break;
119+
case LONG: /* Fall through */
120+
case LONG_LONG:
121+
carrier = long.class;
122+
break;
123+
case FLOAT:
124+
carrier = float.class;
125+
break;
126+
case DOUBLE:
127+
carrier = double.class;
128+
break;
129+
case POINTER:
130+
carrier = MemoryAddress.class;
131+
break;
132+
default:
133+
throw new IllegalArgumentException("The layout's ABI Class is undefined: layout = " + layout);
134+
}
135+
136+
return carrier;
137+
}
138+
139+
public static TypeClass classifyLayout(MemoryLayout layout) {
140+
TypeClass layoutType = PRIMITIVE;
141+
142+
if (layout instanceof ValueLayout) {
143+
layoutType = classifyValueType((ValueLayout)layout);
144+
} else if (layout instanceof GroupLayout) {
145+
layoutType = STRUCT;
146+
} else {
147+
throw new IllegalArgumentException("Unsupported layout: " + layout);
148+
}
149+
150+
return layoutType;
151+
}
152+
153+
private static TypeClass classifyValueType(ValueLayout layout) {
154+
TypeClass layoutType = null;
155+
156+
/* Extract the kind from the specified layout with the ATTR_NAME "abi/kind".
157+
* e.g. b32[abi/kind=INT]
158+
*/
159+
TypeKind kind = (TypeKind)layout.attribute(TypeKind.ATTR_NAME)
160+
.orElseThrow(() -> new IllegalArgumentException("The layout's ABI class is empty"));
161+
162+
switch (kind) {
163+
case CHAR: /* Fall through */
164+
case SHORT: /* Fall through */
165+
case INT: /* Fall through */
166+
case LONG: /* Fall through */
167+
case LONG_LONG: /* Fall through */
168+
case FLOAT: /* Fall through */
169+
case DOUBLE:
170+
layoutType = PRIMITIVE;
171+
break;
172+
case POINTER:
173+
layoutType = POINTER;
174+
break;
175+
default:
176+
throw new IllegalArgumentException("The layout's ABI Class is undefined: layout = " + layout);
177+
}
178+
179+
return layoutType;
180+
}
181+
}

0 commit comments

Comments
 (0)