Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/openj9
Path: blob/master/jcl/src/java.base/share/classes/java/lang/invoke/FoldHandle.java
12520 views
1
/*[INCLUDE-IF Sidecar17 & !OPENJDK_METHODHANDLES]*/
2
/*******************************************************************************
3
* Copyright (c) 2011, 2020 IBM Corp. and others
4
*
5
* This program and the accompanying materials are made available under
6
* the terms of the Eclipse Public License 2.0 which accompanies this
7
* distribution and is available at https://www.eclipse.org/legal/epl-2.0/
8
* or the Apache License, Version 2.0 which accompanies this distribution and
9
* is available at https://www.apache.org/licenses/LICENSE-2.0.
10
*
11
* This Source Code may also be made available under the following
12
* Secondary Licenses when the conditions for such availability set
13
* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU
14
* General Public License, version 2 with the GNU Classpath
15
* Exception [1] and GNU General Public License, version 2 with the
16
* OpenJDK Assembly Exception [2].
17
*
18
* [1] https://www.gnu.org/software/classpath/license.html
19
* [2] http://openjdk.java.net/legal/assembly-exception.html
20
*
21
* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception
22
*******************************************************************************/
23
package java.lang.invoke;
24
25
/*[IF JAVA_SPEC_VERSION >= 15]*/
26
import java.util.List;
27
/*[ENDIF] JAVA_SPEC_VERSION >= 15 */
28
29
abstract class FoldHandle extends MethodHandle {
30
protected final MethodHandle next;
31
protected final MethodHandle combiner;
32
@VMCONSTANTPOOL_FIELD
33
private final int foldPosition; /* The starting position of fold arguments */
34
@VMCONSTANTPOOL_FIELD
35
private final int[] argumentIndices; /* An array of argument indexes of fold handle */
36
37
protected FoldHandle(MethodHandle next, MethodHandle combiner, MethodType type, int foldPosition, int... argumentIndices) {
38
super(type, KIND_FOLDHANDLE, infoAffectingThunks(combiner.type(), foldPosition, argumentIndices));
39
this.next = next;
40
this.combiner = combiner;
41
this.foldPosition = foldPosition;
42
this.argumentIndices = argumentIndices;
43
}
44
45
FoldHandle(FoldHandle originalHandle, MethodType newType) {
46
super(originalHandle, newType);
47
this.next = originalHandle.next;
48
this.combiner = originalHandle.combiner;
49
this.foldPosition = originalHandle.foldPosition;
50
this.argumentIndices = originalHandle.argumentIndices;
51
}
52
53
public static FoldHandle get(MethodHandle next, MethodHandle combiner, MethodType type, int foldPosition, int... argumentIndices) {
54
if (combiner.type().returnType() == void.class) {
55
/* The foldPosition is used to determine the starting position of combiner,
56
* so it must be kept unchanged even though the combiner returns void.
57
*/
58
return new FoldVoidHandle(next, combiner, type, foldPosition, argumentIndices);
59
} else {
60
return new FoldNonvoidHandle(next, combiner, type, foldPosition, argumentIndices);
61
}
62
}
63
64
private static Object[] infoAffectingThunks(MethodType combinerType, int foldPosition, int... argumentIndices) {
65
// The number and types of values to fold affect jitted thunks
66
Object[] result = { combinerType, foldPosition, argumentIndices};
67
return result;
68
}
69
70
private static final ThunkTable _thunkTable = new ThunkTable();
71
protected ThunkTable thunkTable(){ return _thunkTable; }
72
73
74
protected final ThunkTuple computeThunks(Object info) {
75
return thunkTable().get(new ThunkKeyWithObjectArray(ThunkKey.computeThunkableType(type()), (Object[])info));
76
}
77
78
final void compareWith(MethodHandle right, Comparator c) {
79
if (right instanceof FoldHandle) {
80
((FoldHandle)right).compareWithFold(this, c);
81
} else {
82
c.fail();
83
}
84
}
85
86
final void compareWithFold(FoldHandle left, Comparator c) {
87
c.compareChildHandle(left.next, this.next);
88
c.compareChildHandle(left.combiner, this.combiner);
89
c.compareStructuralParameter(left.foldPosition, this.foldPosition);
90
/* The comparator does not address the case where two FoldHandles,
91
* one with empty indices array and the other with non-empty indices array
92
* but the argument indices for them are the same, should share the same thunkArchetype.
93
* This is because that case will not happen due to the way we create the FoldHandle:
94
* if the argument indices in the array are exactly the same to the argument indices
95
* starting from the fold position, the FoldHandle will be created as if no array is passed in.
96
*/
97
c.compareStructuralParameter(left.argumentIndices, this.argumentIndices);
98
}
99
100
/*[IF JAVA_SPEC_VERSION >= 15]*/
101
@Override
102
boolean addRelatedMHs(List<MethodHandle> relatedMHs) {
103
relatedMHs.add(next);
104
relatedMHs.add(combiner);
105
return true;
106
}
107
/*[ENDIF] JAVA_SPEC_VERSION >= 15 */
108
109
// {{{ JIT support
110
protected static native int foldPosition();
111
protected static native int argIndices();
112
protected static native int argumentsForCombiner(int indice, int argPlaceholder);
113
// }}} JIT support
114
}
115
116
final class FoldNonvoidHandle extends FoldHandle {
117
118
FoldNonvoidHandle(MethodHandle next, MethodHandle combiner, MethodType type, int foldPosition, int... argumentIndices) {
119
super(next, combiner, type, foldPosition, argumentIndices); //$NON-NLS-1$
120
}
121
122
// {{{ JIT support
123
124
FoldNonvoidHandle(FoldNonvoidHandle originalHandle, MethodType newType) {
125
super(originalHandle, newType);
126
}
127
128
@FrameIteratorSkip
129
private final int invokeExact_thunkArchetype_X(int argPlaceholder) {
130
if (ILGenMacros.isShareableThunk()) {
131
undoCustomizationLogic(combiner, next);
132
}
133
if (!ILGenMacros.isCustomThunk()) {
134
doCustomizationLogic();
135
}
136
return ILGenMacros.invokeExact_X(next, ILGenMacros.placeholder(
137
ILGenMacros.firstN(foldPosition(), argPlaceholder),
138
ILGenMacros.invokeExact(combiner, argumentsForCombiner(argIndices(), argPlaceholder)),
139
ILGenMacros.dropFirstN(foldPosition(), argPlaceholder)));
140
}
141
142
// }}} JIT support
143
144
@Override
145
MethodHandle cloneWithNewType(MethodType newType) {
146
return new FoldNonvoidHandle(this, newType);
147
}
148
}
149
150
final class FoldVoidHandle extends FoldHandle {
151
152
FoldVoidHandle(MethodHandle next, MethodHandle combiner, MethodType type, int foldPosition, int... argumentIndices) {
153
super(next, combiner, type, foldPosition, argumentIndices); //$NON-NLS-1$
154
}
155
156
FoldVoidHandle(FoldVoidHandle foldVoidHandle, MethodType newType) {
157
super(foldVoidHandle, newType);
158
}
159
160
// {{{ JIT support
161
162
163
@FrameIteratorSkip
164
private final int invokeExact_thunkArchetype_X(int argPlaceholder) {
165
if (ILGenMacros.isShareableThunk()) {
166
undoCustomizationLogic(combiner, next);
167
}
168
if (!ILGenMacros.isCustomThunk()) {
169
doCustomizationLogic();
170
}
171
ILGenMacros.invokeExact(combiner, argumentsForCombiner(argIndices(), argPlaceholder));
172
return ILGenMacros.invokeExact_X(next, argPlaceholder);
173
}
174
175
// }}} JIT support
176
177
@Override
178
MethodHandle cloneWithNewType(MethodType newType) {
179
return new FoldVoidHandle(this, newType);
180
}
181
}
182
183