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/CollectHandle.java
12520 views
1
/*[INCLUDE-IF Sidecar17 & !OPENJDK_METHODHANDLES]*/
2
/*******************************************************************************
3
* Copyright (c) 2009, 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
import com.ibm.oti.util.Msg;
26
import java.lang.reflect.Array;
27
/*[IF JAVA_SPEC_VERSION >= 15]*/
28
import java.util.List;
29
/*[ENDIF] JAVA_SPEC_VERSION >= 15 */
30
31
/* CollectHandle is a MethodHandle subclass used to call another MethodHandle.
32
* It accepts the incoming arguments and collects the requested number
33
* of them into an array of type 'T'.
34
* <p>
35
* Return types can NOT be adapted by this handle.
36
* <p>
37
* Can't pre-allocate the collect array as its not thread-safe - same handle
38
* can be used in multiple threads or collected args array can be modified
39
* down the call chain.
40
*/
41
final class CollectHandle extends MethodHandle {
42
@VMCONSTANTPOOL_FIELD
43
final MethodHandle next;
44
@VMCONSTANTPOOL_FIELD
45
final int collectArraySize; /* Size of the collect array */
46
@VMCONSTANTPOOL_FIELD
47
final int collectPosition; /* The starting position of arguments to collect */
48
final Object emptyArray;
49
50
CollectHandle(MethodHandle next, int collectArraySize, int collectPosition) {
51
super(collectMethodType(next.type(), collectArraySize, collectPosition), KIND_COLLECT, new int[]{collectArraySize, collectPosition});
52
this.collectPosition = collectPosition;
53
this.collectArraySize = collectArraySize;
54
this.next = next;
55
if (collectArraySize == 0) {
56
emptyArray = Array.newInstance(next.type.parameterType(collectPosition).getComponentType(), 0);
57
} else {
58
emptyArray = null;
59
}
60
}
61
62
CollectHandle(CollectHandle original, MethodType newType) {
63
super(original, newType);
64
this.collectPosition = original.collectPosition;
65
this.collectArraySize = original.collectArraySize;
66
this.next = original.next;
67
this.emptyArray = original.emptyArray;
68
}
69
70
private static final MethodType collectMethodType(MethodType type, int collectArraySize, int collectPosition) {
71
int parameterCount = type.parameterCount();
72
if (0 == parameterCount) {
73
/*[MSG "K05ca", "The argument of MethodType at '{0}' must be an array class"]*/
74
throw new IllegalArgumentException(Msg.getString("K05ca", collectPosition)); //$NON-NLS-1$
75
}
76
// Ensure the class at the specified position is an array
77
Class<?> arrayComponent = type.parameterType(collectPosition).getComponentType();
78
if (null == arrayComponent) {
79
/*[MSG "K05ca", "The argument of MethodType at '{0}' must be an array class"]*/
80
throw new IllegalArgumentException(Msg.getString("K05ca", collectPosition)); //$NON-NLS-1$
81
}
82
// Change the T[] into a 'T'
83
MethodType newType = type.changeParameterType(collectPosition, arrayComponent);
84
85
// Add necessary additional 'T' to the type
86
if (0 == collectArraySize) {
87
newType = newType.dropParameterTypes(collectPosition , collectPosition + 1);
88
} else if (collectArraySize > 1) {
89
Class<?>[] classes = new Class[collectArraySize - 1];
90
int arrayLength = classes.length;
91
for (int j = 0; j < arrayLength; j++) {
92
classes[j] = arrayComponent;
93
}
94
newType = newType.insertParameterTypes(collectPosition + 1, classes);
95
}
96
return newType;
97
}
98
99
@Override
100
MethodHandle cloneWithNewType(MethodType newType) {
101
return new CollectHandle(this, newType);
102
}
103
104
/*[IF JAVA_SPEC_VERSION >= 15]*/
105
@Override
106
boolean addRelatedMHs(List<MethodHandle> relatedMHs) {
107
relatedMHs.add(next);
108
return true;
109
}
110
/*[ENDIF] JAVA_SPEC_VERSION >= 15 */
111
112
// {{{ JIT support
113
114
private static final ThunkTable _thunkTable = new ThunkTable();
115
protected final ThunkTable thunkTable(){ return _thunkTable; }
116
protected final ThunkTuple computeThunks(Object arg) {
117
int[] collectArguments = (int[]) arg;
118
return thunkTable().get(new ThunkKeyWithIntArray(ThunkKey.computeThunkableType(type()), collectArguments));
119
}
120
121
private static final Object allocateArray(CollectHandle mh) {
122
return Array.newInstance(
123
mh.next.type.parameterType(mh.collectPosition).getComponentType(),
124
mh.collectArraySize);
125
}
126
127
private static native int numArgsToCollect();
128
private static native int collectionStart();
129
private static native int numArgsAfterCollectArray();
130
131
@FrameIteratorSkip
132
private final int invokeExact_thunkArchetype_X(int argPlaceholder) throws Throwable {
133
if (ILGenMacros.isShareableThunk()) {
134
undoCustomizationLogic(next);
135
}
136
if (!ILGenMacros.isCustomThunk()) {
137
doCustomizationLogic();
138
}
139
ILGenMacros.populateArray(
140
ILGenMacros.push(collectArraySize == 0 ? emptyArray : allocateArray(this)),
141
ILGenMacros.middleN(collectionStart(), numArgsToCollect(), argPlaceholder));
142
return ILGenMacros.invokeExact_X(
143
next,
144
ILGenMacros.placeholder(
145
ILGenMacros.firstN(collectionStart(), argPlaceholder),
146
ILGenMacros.pop_L(),
147
ILGenMacros.lastN(numArgsAfterCollectArray(), argPlaceholder)));
148
}
149
150
// }}} JIT support
151
152
final void compareWith(MethodHandle right, Comparator c) {
153
if (right instanceof CollectHandle) {
154
((CollectHandle)right).compareWithCollect(this, c);
155
} else {
156
c.fail();
157
}
158
}
159
160
final void compareWithCollect(CollectHandle left, Comparator c) {
161
c.compareStructuralParameter(left.collectArraySize, this.collectArraySize);
162
c.compareStructuralParameter(left.collectPosition, this.collectPosition);
163
c.compareChildHandle(left.next, this.next);
164
}
165
}
166
167