Skip to content

Commit 0b0445b

Browse files
committedMay 17, 2024
8331724: Refactor j.l.constant implementation to internal package
Reviewed-by: liach, asotona
1 parent d84a8fd commit 0b0445b

20 files changed

+363
-191
lines changed
 

‎src/java.base/share/classes/java/lang/constant/ClassDesc.java

+56-35
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,19 @@
2828
import java.lang.invoke.TypeDescriptor;
2929
import java.util.stream.Stream;
3030

31+
import jdk.internal.constant.PrimitiveClassDescImpl;
32+
import jdk.internal.constant.ReferenceClassDescImpl;
3133
import sun.invoke.util.Wrapper;
3234

33-
import static java.lang.constant.ConstantUtils.binaryToInternal;
34-
import static java.lang.constant.ConstantUtils.dropLastChar;
35-
import static java.lang.constant.ConstantUtils.internalToBinary;
36-
import static java.lang.constant.ConstantUtils.validateMemberName;
37-
import static java.util.Objects.requireNonNull;
3835
import static java.util.stream.Collectors.joining;
36+
import static jdk.internal.constant.ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS;
37+
import static jdk.internal.constant.ConstantUtils.arrayDepth;
38+
import static jdk.internal.constant.ConstantUtils.binaryToInternal;
39+
import static jdk.internal.constant.ConstantUtils.dropFirstAndLastChar;
40+
import static jdk.internal.constant.ConstantUtils.internalToBinary;
41+
import static jdk.internal.constant.ConstantUtils.validateBinaryClassName;
42+
import static jdk.internal.constant.ConstantUtils.validateInternalClassName;
43+
import static jdk.internal.constant.ConstantUtils.validateMemberName;
3944

4045
/**
4146
* A <a href="package-summary.html#nominal">nominal descriptor</a> for a
@@ -77,7 +82,7 @@ public sealed interface ClassDesc
7782
* @see ClassDesc#ofInternalName(String)
7883
*/
7984
static ClassDesc of(String name) {
80-
ConstantUtils.validateBinaryClassName(requireNonNull(name));
85+
validateBinaryClassName(name);
8186
return ClassDesc.ofDescriptor("L" + binaryToInternal(name) + ";");
8287
}
8388

@@ -103,7 +108,7 @@ static ClassDesc of(String name) {
103108
* @since 20
104109
*/
105110
static ClassDesc ofInternalName(String name) {
106-
ConstantUtils.validateInternalClassName(requireNonNull(name));
111+
validateInternalClassName(name);
107112
return ClassDesc.ofDescriptor("L" + name + ";");
108113
}
109114

@@ -122,11 +127,11 @@ static ClassDesc ofInternalName(String name) {
122127
* not in the correct format
123128
*/
124129
static ClassDesc of(String packageName, String className) {
125-
ConstantUtils.validateBinaryClassName(requireNonNull(packageName));
130+
validateBinaryClassName(packageName);
126131
if (packageName.isEmpty()) {
127132
return of(className);
128133
}
129-
validateMemberName(requireNonNull(className), false);
134+
validateMemberName(className, false);
130135
return ofDescriptor("L" + binaryToInternal(packageName) +
131136
"/" + className + ";");
132137
}
@@ -162,7 +167,7 @@ static ClassDesc ofDescriptor(String descriptor) {
162167
return (descriptor.length() == 1)
163168
? Wrapper.forPrimitiveType(descriptor.charAt(0)).classDescriptor()
164169
// will throw IAE on descriptor.length == 0 or if array dimensions too long
165-
: new ReferenceClassDescImpl(descriptor);
170+
: ReferenceClassDescImpl.of(descriptor);
166171
}
167172

168173
/**
@@ -175,13 +180,18 @@ static ClassDesc ofDescriptor(String descriptor) {
175180
* @jvms 4.4.1 The CONSTANT_Class_info Structure
176181
*/
177182
default ClassDesc arrayType() {
178-
int depth = ConstantUtils.arrayDepth(descriptorString());
179-
if (depth >= ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS) {
183+
String desc = descriptorString();
184+
int depth = arrayDepth(desc);
185+
if (depth >= MAX_ARRAY_TYPE_DESC_DIMENSIONS) {
180186
throw new IllegalStateException(
181187
"Cannot create an array type descriptor with more than " +
182-
ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS + " dimensions");
188+
MAX_ARRAY_TYPE_DESC_DIMENSIONS + " dimensions");
183189
}
184-
return arrayType(1);
190+
String newDesc = "[".concat(desc);
191+
if (desc.length() == 1 && desc.charAt(0) == 'V') {
192+
throw new IllegalArgumentException("not a valid reference type descriptor: " + newDesc);
193+
}
194+
return ReferenceClassDescImpl.ofValidated(newDesc);
185195
}
186196

187197
/**
@@ -196,22 +206,22 @@ default ClassDesc arrayType() {
196206
* @jvms 4.4.1 The CONSTANT_Class_info Structure
197207
*/
198208
default ClassDesc arrayType(int rank) {
199-
int netRank;
200209
if (rank <= 0) {
201210
throw new IllegalArgumentException("rank " + rank + " is not a positive value");
202211
}
203-
try {
204-
int currentDepth = ConstantUtils.arrayDepth(descriptorString());
205-
netRank = Math.addExact(currentDepth, rank);
206-
if (netRank > ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS) {
207-
throw new IllegalArgumentException("rank: " + netRank +
208-
" exceeds maximum supported dimension of " +
209-
ConstantUtils.MAX_ARRAY_TYPE_DESC_DIMENSIONS);
210-
}
211-
} catch (ArithmeticException ae) {
212-
throw new IllegalArgumentException("Integer overflow in rank computation");
212+
String desc = descriptorString();
213+
long currentDepth = arrayDepth(desc);
214+
long netRank = currentDepth + rank;
215+
if (netRank > MAX_ARRAY_TYPE_DESC_DIMENSIONS) {
216+
throw new IllegalArgumentException("rank: " + netRank +
217+
" exceeds maximum supported dimension of " +
218+
MAX_ARRAY_TYPE_DESC_DIMENSIONS);
219+
}
220+
String newDesc = new StringBuilder(desc.length() + rank).repeat('[', rank).append(desc).toString();
221+
if (desc.length() == 1 && desc.charAt(0) == 'V') {
222+
throw new IllegalArgumentException("not a valid reference type descriptor: " + newDesc);
213223
}
214-
return ClassDesc.ofDescriptor("[".repeat(rank) + descriptorString());
224+
return ReferenceClassDescImpl.ofValidated(newDesc);
215225
}
216226

217227
/**
@@ -235,7 +245,10 @@ default ClassDesc nested(String nestedName) {
235245
validateMemberName(nestedName, false);
236246
if (!isClassOrInterface())
237247
throw new IllegalStateException("Outer class is not a class or interface type");
238-
return ClassDesc.ofDescriptor(dropLastChar(descriptorString()) + "$" + nestedName + ";");
248+
String desc = descriptorString();
249+
StringBuilder sb = new StringBuilder(desc.length() + nestedName.length() + 1);
250+
sb.append(desc, 0, desc.length() - 1).append('$').append(nestedName).append(';');
251+
return ReferenceClassDescImpl.ofValidated(sb.toString());
239252
}
240253

241254
/**
@@ -255,7 +268,7 @@ default ClassDesc nested(String firstNestedName, String... moreNestedNames) {
255268
if (!isClassOrInterface())
256269
throw new IllegalStateException("Outer class is not a class or interface type");
257270
validateMemberName(firstNestedName, false);
258-
requireNonNull(moreNestedNames);
271+
// implicit null-check
259272
for (String addNestedNames : moreNestedNames) {
260273
validateMemberName(addNestedNames, false);
261274
}
@@ -299,7 +312,15 @@ default boolean isClassOrInterface() {
299312
* if this descriptor does not describe an array type
300313
*/
301314
default ClassDesc componentType() {
302-
return isArray() ? ClassDesc.ofDescriptor(descriptorString().substring(1)) : null;
315+
if (isArray()) {
316+
String desc = descriptorString();
317+
if (desc.length() == 2) {
318+
return Wrapper.forBasicType(desc.charAt(1)).classDescriptor();
319+
} else {
320+
return ReferenceClassDescImpl.ofValidated(desc.substring(1));
321+
}
322+
}
323+
return null;
303324
}
304325

305326
/**
@@ -312,9 +333,9 @@ default ClassDesc componentType() {
312333
default String packageName() {
313334
if (!isClassOrInterface())
314335
return "";
315-
String className = internalToBinary(ConstantUtils.dropFirstAndLastChar(descriptorString()));
316-
int index = className.lastIndexOf('.');
317-
return (index == -1) ? "" : className.substring(0, index);
336+
String desc = descriptorString();
337+
int index = desc.lastIndexOf('/');
338+
return (index == -1) ? "" : internalToBinary(desc.substring(1, index));
318339
}
319340

320341
/**
@@ -332,11 +353,11 @@ default String displayName() {
332353
if (isPrimitive())
333354
return Wrapper.forBasicType(descriptorString().charAt(0)).primitiveSimpleName();
334355
else if (isClassOrInterface()) {
335-
return descriptorString().substring(Math.max(1, descriptorString().lastIndexOf('/') + 1),
336-
descriptorString().length() - 1);
356+
String desc = descriptorString();
357+
return desc.substring(Math.max(1, desc.lastIndexOf('/') + 1), desc.length() - 1);
337358
}
338359
else if (isArray()) {
339-
int depth = ConstantUtils.arrayDepth(descriptorString());
360+
int depth = arrayDepth(descriptorString());
340361
ClassDesc c = this;
341362
for (int i=0; i<depth; i++)
342363
c = c.componentType();

‎src/java.base/share/classes/java/lang/constant/ConstantDescs.java

+40-37
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
*/
2525
package java.lang.constant;
2626

27+
import jdk.internal.constant.PrimitiveClassDescImpl;
28+
import jdk.internal.constant.ReferenceClassDescImpl;
29+
2730
import java.lang.Enum.EnumDesc;
2831
import java.lang.invoke.CallSite;
2932
import java.lang.invoke.ConstantBootstraps;
@@ -64,115 +67,115 @@ private ConstantDescs() { }
6467
// Don't change the order of these declarations!
6568

6669
/** {@link ClassDesc} representing {@link Object} */
67-
public static final ClassDesc CD_Object = new ReferenceClassDescImpl("Ljava/lang/Object;");
70+
public static final ClassDesc CD_Object = ReferenceClassDescImpl.ofValidated("Ljava/lang/Object;");
6871

6972
/** {@link ClassDesc} representing {@link String} */
70-
public static final ClassDesc CD_String = new ReferenceClassDescImpl("Ljava/lang/String;");
73+
public static final ClassDesc CD_String = ReferenceClassDescImpl.ofValidated("Ljava/lang/String;");
7174

7275
/** {@link ClassDesc} representing {@link Class} */
73-
public static final ClassDesc CD_Class = new ReferenceClassDescImpl("Ljava/lang/Class;");
76+
public static final ClassDesc CD_Class = ReferenceClassDescImpl.ofValidated("Ljava/lang/Class;");
7477

7578
/** {@link ClassDesc} representing {@link Number} */
76-
public static final ClassDesc CD_Number = new ReferenceClassDescImpl("Ljava/lang/Number;");
79+
public static final ClassDesc CD_Number = ReferenceClassDescImpl.ofValidated("Ljava/lang/Number;");
7780

7881
/** {@link ClassDesc} representing {@link Integer} */
79-
public static final ClassDesc CD_Integer = new ReferenceClassDescImpl("Ljava/lang/Integer;");
82+
public static final ClassDesc CD_Integer = ReferenceClassDescImpl.ofValidated("Ljava/lang/Integer;");
8083

8184
/** {@link ClassDesc} representing {@link Long} */
82-
public static final ClassDesc CD_Long = new ReferenceClassDescImpl("Ljava/lang/Long;");
85+
public static final ClassDesc CD_Long = ReferenceClassDescImpl.ofValidated("Ljava/lang/Long;");
8386

8487
/** {@link ClassDesc} representing {@link Float} */
85-
public static final ClassDesc CD_Float = new ReferenceClassDescImpl("Ljava/lang/Float;");
88+
public static final ClassDesc CD_Float = ReferenceClassDescImpl.ofValidated("Ljava/lang/Float;");
8689

8790
/** {@link ClassDesc} representing {@link Double} */
88-
public static final ClassDesc CD_Double = new ReferenceClassDescImpl("Ljava/lang/Double;");
91+
public static final ClassDesc CD_Double = ReferenceClassDescImpl.ofValidated("Ljava/lang/Double;");
8992

9093
/** {@link ClassDesc} representing {@link Short} */
91-
public static final ClassDesc CD_Short = new ReferenceClassDescImpl("Ljava/lang/Short;");
94+
public static final ClassDesc CD_Short = ReferenceClassDescImpl.ofValidated("Ljava/lang/Short;");
9295

9396
/** {@link ClassDesc} representing {@link Byte} */
94-
public static final ClassDesc CD_Byte = new ReferenceClassDescImpl("Ljava/lang/Byte;");
97+
public static final ClassDesc CD_Byte = ReferenceClassDescImpl.ofValidated("Ljava/lang/Byte;");
9598

9699
/** {@link ClassDesc} representing {@link Character} */
97-
public static final ClassDesc CD_Character = new ReferenceClassDescImpl("Ljava/lang/Character;");
100+
public static final ClassDesc CD_Character = ReferenceClassDescImpl.ofValidated("Ljava/lang/Character;");
98101

99102
/** {@link ClassDesc} representing {@link Boolean} */
100-
public static final ClassDesc CD_Boolean = new ReferenceClassDescImpl("Ljava/lang/Boolean;");
103+
public static final ClassDesc CD_Boolean = ReferenceClassDescImpl.ofValidated("Ljava/lang/Boolean;");
101104

102105
/** {@link ClassDesc} representing {@link Void} */
103-
public static final ClassDesc CD_Void = new ReferenceClassDescImpl("Ljava/lang/Void;");
106+
public static final ClassDesc CD_Void = ReferenceClassDescImpl.ofValidated("Ljava/lang/Void;");
104107

105108
/** {@link ClassDesc} representing {@link Throwable} */
106-
public static final ClassDesc CD_Throwable = new ReferenceClassDescImpl("Ljava/lang/Throwable;");
109+
public static final ClassDesc CD_Throwable = ReferenceClassDescImpl.ofValidated("Ljava/lang/Throwable;");
107110

108111
/** {@link ClassDesc} representing {@link Exception} */
109-
public static final ClassDesc CD_Exception = new ReferenceClassDescImpl("Ljava/lang/Exception;");
112+
public static final ClassDesc CD_Exception = ReferenceClassDescImpl.ofValidated("Ljava/lang/Exception;");
110113

111114
/** {@link ClassDesc} representing {@link Enum} */
112-
public static final ClassDesc CD_Enum = new ReferenceClassDescImpl("Ljava/lang/Enum;");
115+
public static final ClassDesc CD_Enum = ReferenceClassDescImpl.ofValidated("Ljava/lang/Enum;");
113116

114117
/** {@link ClassDesc} representing {@link VarHandle} */
115-
public static final ClassDesc CD_VarHandle = new ReferenceClassDescImpl("Ljava/lang/invoke/VarHandle;");
118+
public static final ClassDesc CD_VarHandle = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/VarHandle;");
116119

117120
/** {@link ClassDesc} representing {@link MethodHandles} */
118-
public static final ClassDesc CD_MethodHandles = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodHandles;");
121+
public static final ClassDesc CD_MethodHandles = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/MethodHandles;");
119122

120123
/** {@link ClassDesc} representing {@link MethodHandles.Lookup} */
121-
public static final ClassDesc CD_MethodHandles_Lookup = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodHandles$Lookup;");
124+
public static final ClassDesc CD_MethodHandles_Lookup = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/MethodHandles$Lookup;");
122125

123126
/** {@link ClassDesc} representing {@link MethodHandle} */
124-
public static final ClassDesc CD_MethodHandle = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodHandle;");
127+
public static final ClassDesc CD_MethodHandle = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/MethodHandle;");
125128

126129
/** {@link ClassDesc} representing {@link MethodType} */
127-
public static final ClassDesc CD_MethodType = new ReferenceClassDescImpl("Ljava/lang/invoke/MethodType;");
130+
public static final ClassDesc CD_MethodType = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/MethodType;");
128131

129132
/** {@link ClassDesc} representing {@link CallSite} */
130-
public static final ClassDesc CD_CallSite = new ReferenceClassDescImpl("Ljava/lang/invoke/CallSite;");
133+
public static final ClassDesc CD_CallSite = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/CallSite;");
131134

132135
/** {@link ClassDesc} representing {@link Collection} */
133-
public static final ClassDesc CD_Collection = new ReferenceClassDescImpl("Ljava/util/Collection;");
136+
public static final ClassDesc CD_Collection = ReferenceClassDescImpl.ofValidated("Ljava/util/Collection;");
134137

135138
/** {@link ClassDesc} representing {@link List} */
136-
public static final ClassDesc CD_List = new ReferenceClassDescImpl("Ljava/util/List;");
139+
public static final ClassDesc CD_List = ReferenceClassDescImpl.ofValidated("Ljava/util/List;");
137140

138141
/** {@link ClassDesc} representing {@link Set} */
139-
public static final ClassDesc CD_Set = new ReferenceClassDescImpl("Ljava/util/Set;");
142+
public static final ClassDesc CD_Set = ReferenceClassDescImpl.ofValidated("Ljava/util/Set;");
140143

141144
/** {@link ClassDesc} representing {@link Map} */
142-
public static final ClassDesc CD_Map = new ReferenceClassDescImpl("Ljava/util/Map;");
145+
public static final ClassDesc CD_Map = ReferenceClassDescImpl.ofValidated("Ljava/util/Map;");
143146

144147
/** {@link ClassDesc} representing {@link ConstantDesc} */
145-
public static final ClassDesc CD_ConstantDesc = new ReferenceClassDescImpl("Ljava/lang/constant/ConstantDesc;");
148+
public static final ClassDesc CD_ConstantDesc = ReferenceClassDescImpl.ofValidated("Ljava/lang/constant/ConstantDesc;");
146149

147150
/** {@link ClassDesc} representing {@link ClassDesc} */
148-
public static final ClassDesc CD_ClassDesc = new ReferenceClassDescImpl("Ljava/lang/constant/ClassDesc;");
151+
public static final ClassDesc CD_ClassDesc = ReferenceClassDescImpl.ofValidated("Ljava/lang/constant/ClassDesc;");
149152

150153
/** {@link ClassDesc} representing {@link EnumDesc} */
151-
public static final ClassDesc CD_EnumDesc = new ReferenceClassDescImpl("Ljava/lang/Enum$EnumDesc;");
154+
public static final ClassDesc CD_EnumDesc = ReferenceClassDescImpl.ofValidated("Ljava/lang/Enum$EnumDesc;");
152155

153156
/** {@link ClassDesc} representing {@link MethodTypeDesc} */
154-
public static final ClassDesc CD_MethodTypeDesc = new ReferenceClassDescImpl("Ljava/lang/constant/MethodTypeDesc;");
157+
public static final ClassDesc CD_MethodTypeDesc = ReferenceClassDescImpl.ofValidated("Ljava/lang/constant/MethodTypeDesc;");
155158

156159
/** {@link ClassDesc} representing {@link MethodHandleDesc} */
157-
public static final ClassDesc CD_MethodHandleDesc = new ReferenceClassDescImpl("Ljava/lang/constant/MethodHandleDesc;");
160+
public static final ClassDesc CD_MethodHandleDesc = ReferenceClassDescImpl.ofValidated("Ljava/lang/constant/MethodHandleDesc;");
158161

159162
/** {@link ClassDesc} representing {@link DirectMethodHandleDesc} */
160-
public static final ClassDesc CD_DirectMethodHandleDesc = new ReferenceClassDescImpl("Ljava/lang/constant/DirectMethodHandleDesc;");
163+
public static final ClassDesc CD_DirectMethodHandleDesc = ReferenceClassDescImpl.ofValidated("Ljava/lang/constant/DirectMethodHandleDesc;");
161164

162165
/** {@link ClassDesc} representing {@link VarHandleDesc} */
163-
public static final ClassDesc CD_VarHandleDesc = new ReferenceClassDescImpl("Ljava/lang/invoke/VarHandle$VarHandleDesc;");
166+
public static final ClassDesc CD_VarHandleDesc = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/VarHandle$VarHandleDesc;");
164167

165168
/** {@link ClassDesc} representing {@link DirectMethodHandleDesc.Kind} */
166-
public static final ClassDesc CD_MethodHandleDesc_Kind = new ReferenceClassDescImpl("Ljava/lang/constant/DirectMethodHandleDesc$Kind;");
169+
public static final ClassDesc CD_MethodHandleDesc_Kind = ReferenceClassDescImpl.ofValidated("Ljava/lang/constant/DirectMethodHandleDesc$Kind;");
167170

168171
/** {@link ClassDesc} representing {@link DynamicConstantDesc} */
169-
public static final ClassDesc CD_DynamicConstantDesc = new ReferenceClassDescImpl("Ljava/lang/constant/DynamicConstantDesc;");
172+
public static final ClassDesc CD_DynamicConstantDesc = ReferenceClassDescImpl.ofValidated("Ljava/lang/constant/DynamicConstantDesc;");
170173

171174
/** {@link ClassDesc} representing {@link DynamicCallSiteDesc} */
172-
public static final ClassDesc CD_DynamicCallSiteDesc = new ReferenceClassDescImpl("Ljava/lang/constant/DynamicCallSiteDesc;");
175+
public static final ClassDesc CD_DynamicCallSiteDesc = ReferenceClassDescImpl.ofValidated("Ljava/lang/constant/DynamicCallSiteDesc;");
173176

174177
/** {@link ClassDesc} representing {@link ConstantBootstraps} */
175-
public static final ClassDesc CD_ConstantBootstraps = new ReferenceClassDescImpl("Ljava/lang/invoke/ConstantBootstraps;");
178+
public static final ClassDesc CD_ConstantBootstraps = ReferenceClassDescImpl.ofValidated("Ljava/lang/invoke/ConstantBootstraps;");
176179

177180
private static final ClassDesc[] INDY_BOOTSTRAP_ARGS = {
178181
CD_MethodHandles_Lookup,

‎src/java.base/share/classes/java/lang/constant/DirectMethodHandleDesc.java

+3-21
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -26,9 +26,8 @@
2626

2727
import java.lang.invoke.MethodHandle;
2828
import java.lang.invoke.MethodHandleInfo;
29-
import java.util.OptionalInt;
30-
import java.util.stream.Stream;
3129

30+
import jdk.internal.constant.DirectMethodHandleDescImpl;
3231
import jdk.internal.vm.annotation.Stable;
3332

3433
import static java.lang.invoke.MethodHandleInfo.REF_getField;
@@ -89,7 +88,7 @@ enum Kind {
8988
*/
9089
public final boolean isInterface;
9190
Kind(int refKind) {
92-
this(refKind, false);
91+
this.refKind = refKind; this.isInterface = false;
9392
}
9493

9594
Kind(int refKind, boolean isInterface) { this.refKind = refKind; this.isInterface = isInterface; }
@@ -179,23 +178,6 @@ private static int tableIndex(int refKind, boolean isInterface) {
179178
}
180179
}
181180
}
182-
183-
/**
184-
* Does this {@code Kind} correspond to a virtual method invocation?
185-
*
186-
* @return if this {@code Kind} corresponds to a virtual method invocation
187-
*/
188-
boolean isVirtualMethod() {
189-
switch (this) {
190-
case VIRTUAL:
191-
case SPECIAL:
192-
case INTERFACE_VIRTUAL:
193-
case INTERFACE_SPECIAL:
194-
return true;
195-
default:
196-
return false;
197-
}
198-
}
199181
}
200182

201183
/**

‎src/java.base/share/classes/java/lang/constant/DynamicCallSiteDesc.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -32,10 +32,10 @@
3232
import java.util.stream.Stream;
3333

3434
import static java.lang.constant.ConstantDescs.CD_String;
35-
import static java.lang.constant.ConstantUtils.EMPTY_CONSTANTDESC;
36-
import static java.lang.constant.ConstantUtils.validateMemberName;
3735
import static java.util.Objects.requireNonNull;
3836
import static java.util.stream.Collectors.joining;
37+
import static jdk.internal.constant.ConstantUtils.EMPTY_CONSTANTDESC;
38+
import static jdk.internal.constant.ConstantUtils.validateMemberName;
3939

4040
/**
4141
* A <a href="package-summary.html#nominal">nominal descriptor</a> for an

‎src/java.base/share/classes/java/lang/constant/DynamicConstantDesc.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -39,10 +39,10 @@
3939
import static java.lang.constant.ConstantDescs.CD_Class;
4040
import static java.lang.constant.ConstantDescs.CD_VarHandle;
4141
import static java.lang.constant.ConstantDescs.DEFAULT_NAME;
42-
import static java.lang.constant.ConstantUtils.EMPTY_CONSTANTDESC;
43-
import static java.lang.constant.ConstantUtils.validateMemberName;
4442
import static java.util.Objects.requireNonNull;
4543
import static java.util.stream.Collectors.joining;
44+
import static jdk.internal.constant.ConstantUtils.EMPTY_CONSTANTDESC;
45+
import static jdk.internal.constant.ConstantUtils.validateMemberName;
4646

4747
/**
4848
* A <a href="package-summary.html#nominal">nominal descriptor</a> for a

‎src/java.base/share/classes/java/lang/constant/MethodHandleDesc.java

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -28,6 +28,8 @@
2828
import java.lang.invoke.MethodHandles;
2929
import java.lang.invoke.MethodType;
3030

31+
import jdk.internal.constant.DirectMethodHandleDescImpl;
32+
3133
import static java.lang.constant.ConstantDescs.CD_void;
3234
import static java.lang.constant.DirectMethodHandleDesc.Kind.CONSTRUCTOR;
3335

‎src/java.base/share/classes/java/lang/constant/MethodTypeDesc.java

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -31,6 +31,11 @@
3131
import java.util.stream.Collectors;
3232
import java.util.stream.Stream;
3333

34+
import jdk.internal.constant.ConstantUtils;
35+
import jdk.internal.constant.MethodTypeDescImpl;
36+
37+
import static java.util.Objects.requireNonNull;
38+
3439
/**
3540
* A <a href="package-summary.html#nominal">nominal descriptor</a> for a
3641
* {@linkplain MethodType} constant.
@@ -64,7 +69,7 @@ static MethodTypeDesc ofDescriptor(String descriptor) {
6469
* @since 21
6570
*/
6671
static MethodTypeDesc of(ClassDesc returnDesc) {
67-
return MethodTypeDescImpl.ofTrusted(returnDesc, ConstantUtils.EMPTY_CLASSDESC);
72+
return MethodTypeDescImpl.ofValidated(requireNonNull(returnDesc), ConstantUtils.EMPTY_CLASSDESC);
6873
}
6974

7075
/**

‎src/java.base/share/classes/java/lang/constant/ModuleDesc.java

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,9 @@
2424
*/
2525
package java.lang.constant;
2626

27+
import jdk.internal.constant.ConstantUtils;
28+
import jdk.internal.constant.ModuleDescImpl;
29+
2730
import static java.util.Objects.requireNonNull;
2831

2932
/**

‎src/java.base/share/classes/java/lang/constant/PackageDesc.java

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
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.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -24,6 +24,9 @@
2424
*/
2525
package java.lang.constant;
2626

27+
import jdk.internal.constant.ConstantUtils;
28+
import jdk.internal.constant.PackageDescImpl;
29+
2730
import static java.util.Objects.requireNonNull;
2831

2932
/**

‎src/java.base/share/classes/java/lang/constant/ConstantUtils.java ‎src/java.base/share/classes/jdk/internal/constant/ConstantUtils.java

+44-40
Original file line numberDiff line numberDiff line change
@@ -22,38 +22,42 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package java.lang.constant;
25+
package jdk.internal.constant;
2626

2727
import sun.invoke.util.Wrapper;
2828

29+
import java.lang.constant.ClassDesc;
30+
import java.lang.constant.ConstantDesc;
31+
import java.lang.constant.ConstantDescs;
2932
import java.util.ArrayList;
3033
import java.util.List;
3134
import java.util.Set;
3235

33-
import static java.util.Objects.requireNonNull;
34-
3536
/**
3637
* Helper methods for the implementation of {@code java.lang.constant}.
3738
*/
38-
class ConstantUtils {
39+
public final class ConstantUtils {
3940
/** an empty constant descriptor */
4041
public static final ConstantDesc[] EMPTY_CONSTANTDESC = new ConstantDesc[0];
41-
static final ClassDesc[] EMPTY_CLASSDESC = new ClassDesc[0];
42-
static final Constable[] EMPTY_CONSTABLE = new Constable[0];
43-
static final int MAX_ARRAY_TYPE_DESC_DIMENSIONS = 255;
42+
public static final ClassDesc[] EMPTY_CLASSDESC = new ClassDesc[0];
43+
public static final int MAX_ARRAY_TYPE_DESC_DIMENSIONS = 255;
4444

4545
private static final Set<String> pointyNames = Set.of(ConstantDescs.INIT_NAME, ConstantDescs.CLASS_INIT_NAME);
4646

47+
/** No instantiation */
48+
private ConstantUtils() {}
49+
4750
/**
4851
* Validates the correctness of a binary class name. In particular checks for the presence of
4952
* invalid characters in the name.
5053
*
5154
* @param name the class name
5255
* @return the class name passed if valid
5356
* @throws IllegalArgumentException if the class name is invalid
57+
* @throws NullPointerException if class name is {@code null}
5458
*/
55-
static String validateBinaryClassName(String name) {
56-
for (int i=0; i<name.length(); i++) {
59+
public static String validateBinaryClassName(String name) {
60+
for (int i = 0; i < name.length(); i++) {
5761
char ch = name.charAt(i);
5862
if (ch == ';' || ch == '[' || ch == '/')
5963
throw new IllegalArgumentException("Invalid class name: " + name);
@@ -62,21 +66,22 @@ static String validateBinaryClassName(String name) {
6266
}
6367

6468
/**
65-
* Validates the correctness of an internal class name.
66-
* In particular checks for the presence of invalid characters in the name.
67-
*
68-
* @param name the class name
69-
* @return the class name passed if valid
70-
* @throws IllegalArgumentException if the class name is invalid
71-
*/
72-
static String validateInternalClassName(String name) {
73-
for (int i=0; i<name.length(); i++) {
74-
char ch = name.charAt(i);
75-
if (ch == ';' || ch == '[' || ch == '.')
76-
throw new IllegalArgumentException("Invalid class name: " + name);
77-
}
78-
return name;
79-
}
69+
* Validates the correctness of an internal class name.
70+
* In particular checks for the presence of invalid characters in the name.
71+
*
72+
* @param name the class name
73+
* @return the class name passed if valid
74+
* @throws IllegalArgumentException if the class name is invalid
75+
* @throws NullPointerException if class name is {@code null}
76+
*/
77+
public static String validateInternalClassName(String name) {
78+
for (int i = 0; i < name.length(); i++) {
79+
char ch = name.charAt(i);
80+
if (ch == ';' || ch == '[' || ch == '.')
81+
throw new IllegalArgumentException("Invalid class name: " + name);
82+
}
83+
return name;
84+
}
8085

8186
/**
8287
* Validates the correctness of a binary package name.
@@ -89,7 +94,7 @@ static String validateInternalClassName(String name) {
8994
* @throws NullPointerException if the package name is {@code null}
9095
*/
9196
public static String validateBinaryPackageName(String name) {
92-
for (int i=0; i<name.length(); i++) {
97+
for (int i = 0; i < name.length(); i++) {
9398
char ch = name.charAt(i);
9499
if (ch == ';' || ch == '[' || ch == '/')
95100
throw new IllegalArgumentException("Invalid package name: " + name);
@@ -108,7 +113,7 @@ public static String validateBinaryPackageName(String name) {
108113
* @throws NullPointerException if the package name is {@code null}
109114
*/
110115
public static String validateInternalPackageName(String name) {
111-
for (int i=0; i<name.length(); i++) {
116+
for (int i = 0; i < name.length(); i++) {
112117
char ch = name.charAt(i);
113118
if (ch == ';' || ch == '[' || ch == '.')
114119
throw new IllegalArgumentException("Invalid package name: " + name);
@@ -129,7 +134,7 @@ public static String validateInternalPackageName(String name) {
129134
* @throws NullPointerException if the module name is {@code null}
130135
*/
131136
public static String validateModuleName(String name) {
132-
for (int i=name.length() - 1; i >= 0; i--) {
137+
for (int i = name.length() - 1; i >= 0; i--) {
133138
char ch = name.charAt(i);
134139
if ((ch >= '\u0000' && ch <= '\u001F')
135140
|| ((ch == '\\' || ch == ':' || ch =='@') && (i == 0 || name.charAt(--i) != '\\')))
@@ -144,11 +149,13 @@ public static String validateModuleName(String name) {
144149
* @param name the name of the member
145150
* @return the name passed if valid
146151
* @throws IllegalArgumentException if the member name is invalid
152+
* @throws NullPointerException if the member name is {@code null}
147153
*/
148154
public static String validateMemberName(String name, boolean method) {
149-
if (name.length() == 0)
155+
int len = name.length();
156+
if (len == 0)
150157
throw new IllegalArgumentException("zero-length member name");
151-
for (int i=0; i<name.length(); i++) {
158+
for (int i = 0; i < len; i++) {
152159
char ch = name.charAt(i);
153160
if (ch == '.' || ch == ';' || ch == '[' || ch == '/')
154161
throw new IllegalArgumentException("Invalid member name: " + name);
@@ -160,31 +167,27 @@ public static String validateMemberName(String name, boolean method) {
160167
return name;
161168
}
162169

163-
static void validateClassOrInterface(ClassDesc classDesc) {
170+
public static void validateClassOrInterface(ClassDesc classDesc) {
164171
if (!classDesc.isClassOrInterface())
165172
throw new IllegalArgumentException("not a class or interface type: " + classDesc);
166173
}
167174

168-
static int arrayDepth(String descriptorString) {
175+
public static int arrayDepth(String descriptorString) {
169176
int depth = 0;
170177
while (descriptorString.charAt(depth) == '[')
171178
depth++;
172179
return depth;
173180
}
174181

175-
static String binaryToInternal(String name) {
182+
public static String binaryToInternal(String name) {
176183
return name.replace('.', '/');
177184
}
178185

179-
static String internalToBinary(String name) {
186+
public static String internalToBinary(String name) {
180187
return name.replace('/', '.');
181188
}
182189

183-
static String dropLastChar(String s) {
184-
return s.substring(0, s.length() - 1);
185-
}
186-
187-
static String dropFirstAndLastChar(String s) {
190+
public static String dropFirstAndLastChar(String s) {
188191
return s.substring(1, s.length() - 1);
189192
}
190193

@@ -196,7 +199,7 @@ static String dropFirstAndLastChar(String s) {
196199
* @return the list of types
197200
* @throws IllegalArgumentException if the descriptor string is not valid
198201
*/
199-
static List<ClassDesc> parseMethodDescriptor(String descriptor) {
202+
public static List<ClassDesc> parseMethodDescriptor(String descriptor) {
200203
int cur = 0, end = descriptor.length();
201204
ArrayList<ClassDesc> ptypes = new ArrayList<>();
202205
ptypes.add(null); // placeholder for return type
@@ -227,7 +230,8 @@ private static ClassDesc resolveClassDesc(String descriptor, int start, int len)
227230
if (len == 1) {
228231
return Wrapper.forPrimitiveType(descriptor.charAt(start)).classDescriptor();
229232
}
230-
return ClassDesc.ofDescriptor(descriptor.substring(start, start + len));
233+
// Pre-verified in parseMethodDescriptor; avoid redundant verification
234+
return ReferenceClassDescImpl.ofValidated(descriptor.substring(start, start + len));
231235
}
232236

233237
private static final char JVM_SIGNATURE_ARRAY = '[';

‎src/java.base/share/classes/java/lang/constant/DirectMethodHandleDescImpl.java ‎src/java.base/share/classes/jdk/internal/constant/DirectMethodHandleDescImpl.java

+14-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,25 +22,28 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package java.lang.constant;
25+
package jdk.internal.constant;
2626

27+
import java.lang.constant.ClassDesc;
28+
import java.lang.constant.DirectMethodHandleDesc;
29+
import java.lang.constant.MethodTypeDesc;
2730
import java.lang.invoke.MethodHandle;
2831
import java.lang.invoke.MethodHandles;
2932
import java.lang.invoke.MethodType;
3033
import java.util.Objects;
3134

3235
import static java.lang.constant.ConstantDescs.CD_void;
33-
import static java.lang.constant.ConstantUtils.validateClassOrInterface;
34-
import static java.lang.constant.ConstantUtils.validateMemberName;
3536
import static java.lang.constant.DirectMethodHandleDesc.Kind.CONSTRUCTOR;
3637
import static java.util.Objects.requireNonNull;
38+
import static jdk.internal.constant.ConstantUtils.validateClassOrInterface;
39+
import static jdk.internal.constant.ConstantUtils.validateMemberName;
3740

3841
/**
3942
* A <a href="package-summary.html#nominal">nominal descriptor</a> for a direct
4043
* {@link MethodHandle}. A {@linkplain DirectMethodHandleDescImpl} corresponds to
4144
* a {@code Constant_MethodHandle_info} entry in the constant pool of a classfile.
4245
*/
43-
final class DirectMethodHandleDescImpl implements DirectMethodHandleDesc {
46+
public final class DirectMethodHandleDescImpl implements DirectMethodHandleDesc {
4447

4548
private final Kind kind;
4649
private final ClassDesc owner;
@@ -62,7 +65,7 @@ final class DirectMethodHandleDescImpl implements DirectMethodHandleDesc {
6265
* is not {@code void}
6366
* @jvms 4.2.2 Unqualified Names
6467
*/
65-
DirectMethodHandleDescImpl(Kind kind, ClassDesc owner, String name, MethodTypeDesc type) {
68+
public DirectMethodHandleDescImpl(Kind kind, ClassDesc owner, String name, MethodTypeDesc type) {
6669
if (kind == CONSTRUCTOR)
6770
name = "<init>";
6871

@@ -82,12 +85,11 @@ final class DirectMethodHandleDescImpl implements DirectMethodHandleDesc {
8285
this.kind = kind;
8386
this.owner = owner;
8487
this.name = name;
85-
if (kind.isVirtualMethod())
86-
this.invocationType = type.insertParameterTypes(0, owner);
87-
else if (kind == CONSTRUCTOR)
88-
this.invocationType = type.changeReturnType(owner);
89-
else
90-
this.invocationType = type;
88+
this.invocationType = switch (kind) {
89+
case VIRTUAL, SPECIAL, INTERFACE_VIRTUAL, INTERFACE_SPECIAL -> type.insertParameterTypes(0, owner);
90+
case CONSTRUCTOR -> type.changeReturnType(owner);
91+
default -> type;
92+
};
9193
}
9294

9395
private static void validateFieldType(MethodTypeDesc type, boolean isSetter, boolean isVirtual) {

‎src/java.base/share/classes/java/lang/constant/MethodTypeDescImpl.java ‎src/java.base/share/classes/jdk/internal/constant/MethodTypeDescImpl.java

+40-16
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package java.lang.constant;
25+
package jdk.internal.constant;
2626

2727
import jdk.internal.vm.annotation.Stable;
2828

29+
import java.lang.constant.ClassDesc;
30+
import java.lang.constant.MethodTypeDesc;
2931
import java.lang.invoke.MethodHandles;
3032
import java.lang.invoke.MethodType;
3133
import java.security.AccessController;
@@ -41,7 +43,7 @@
4143
* {@link MethodType}. A {@linkplain MethodTypeDescImpl} corresponds to a
4244
* {@code Constant_MethodType_info} entry in the constant pool of a classfile.
4345
*/
44-
final class MethodTypeDescImpl implements MethodTypeDesc {
46+
public final class MethodTypeDescImpl implements MethodTypeDesc {
4547
private final ClassDesc returnType;
4648
private final @Stable ClassDesc[] argTypes;
4749
private @Stable String cachedDescriptorString;
@@ -65,15 +67,31 @@ private MethodTypeDescImpl(ClassDesc returnType, ClassDesc[] validatedArgTypes)
6567
* @param returnType a {@link ClassDesc} describing the return type
6668
* @param trustedArgTypes {@link ClassDesc}s describing the trusted parameter types
6769
*/
68-
static MethodTypeDescImpl ofTrusted(ClassDesc returnType, ClassDesc[] trustedArgTypes) {
70+
public static MethodTypeDescImpl ofTrusted(ClassDesc returnType, ClassDesc[] trustedArgTypes) {
6971
requireNonNull(returnType);
70-
if (trustedArgTypes.length == 0) // implicit null check
71-
return new MethodTypeDescImpl(returnType, ConstantUtils.EMPTY_CLASSDESC);
72+
// implicit null checks of trustedArgTypes and all elements
73+
for (ClassDesc cd : trustedArgTypes) {
74+
validateArgument(cd);
75+
}
76+
return ofValidated(returnType, trustedArgTypes);
77+
}
7278

73-
for (ClassDesc cd : trustedArgTypes)
74-
if (cd.descriptorString().charAt(0) == 'V') // implicit null check
75-
throw new IllegalArgumentException("Void parameters not permitted");
79+
private static ClassDesc validateArgument(ClassDesc arg) {
80+
if (arg.descriptorString().charAt(0) == 'V') // implicit null check
81+
throw new IllegalArgumentException("Void parameters not permitted");
82+
return arg;
83+
}
7684

85+
/**
86+
* Constructs a {@linkplain MethodTypeDesc} with the specified pre-validated return type
87+
* and a pre-validated trusted parameter types array.
88+
*
89+
* @param returnType a {@link ClassDesc} describing the return type
90+
* @param trustedArgTypes {@link ClassDesc}s describing the trusted parameter types
91+
*/
92+
public static MethodTypeDescImpl ofValidated(ClassDesc returnType, ClassDesc[] trustedArgTypes) {
93+
if (trustedArgTypes.length == 0)
94+
return new MethodTypeDescImpl(returnType, ConstantUtils.EMPTY_CLASSDESC);
7795
return new MethodTypeDescImpl(returnType, trustedArgTypes);
7896
}
7997

@@ -86,15 +104,15 @@ static MethodTypeDescImpl ofTrusted(ClassDesc returnType, ClassDesc[] trustedArg
86104
* method descriptor
87105
* @jvms 4.3.3 Method Descriptors
88106
*/
89-
static MethodTypeDescImpl ofDescriptor(String descriptor) {
107+
public static MethodTypeDescImpl ofDescriptor(String descriptor) {
90108
// Implicit null-check of descriptor
91109
List<ClassDesc> ptypes = ConstantUtils.parseMethodDescriptor(descriptor);
92110
int args = ptypes.size() - 1;
93111
ClassDesc[] paramTypes = args > 0
94112
? ptypes.subList(1, args + 1).toArray(ConstantUtils.EMPTY_CLASSDESC)
95113
: ConstantUtils.EMPTY_CLASSDESC;
96114

97-
MethodTypeDescImpl result = ofTrusted(ptypes.get(0), paramTypes);
115+
MethodTypeDescImpl result = ofValidated(ptypes.get(0), paramTypes);
98116
result.cachedDescriptorString = descriptor;
99117
return result;
100118
}
@@ -127,14 +145,14 @@ public ClassDesc[] parameterArray() {
127145

128146
@Override
129147
public MethodTypeDesc changeReturnType(ClassDesc returnType) {
130-
return new MethodTypeDescImpl(requireNonNull(returnType), argTypes);
148+
return ofValidated(requireNonNull(returnType), argTypes);
131149
}
132150

133151
@Override
134152
public MethodTypeDesc changeParameterType(int index, ClassDesc paramType) {
135153
ClassDesc[] newArgs = argTypes.clone();
136-
newArgs[index] = paramType;
137-
return ofTrusted(returnType, newArgs);
154+
newArgs[index] = validateArgument(paramType);
155+
return ofValidated(returnType, newArgs);
138156
}
139157

140158
@Override
@@ -149,7 +167,7 @@ public MethodTypeDesc dropParameterTypes(int start, int end) {
149167
if (end < argTypes.length) {
150168
System.arraycopy(argTypes, end, newArgs, start, argTypes.length - end);
151169
}
152-
return ofTrusted(returnType, newArgs);
170+
return ofValidated(returnType, newArgs);
153171
}
154172

155173
@Override
@@ -162,10 +180,16 @@ public MethodTypeDesc insertParameterTypes(int pos, ClassDesc... paramTypes) {
162180
System.arraycopy(argTypes, 0, newArgs, 0, pos);
163181
}
164182
System.arraycopy(paramTypes, 0, newArgs, pos, paramTypes.length);
183+
int destPos = pos + paramTypes.length;
165184
if (pos < argTypes.length) {
166-
System.arraycopy(argTypes, pos, newArgs, pos + paramTypes.length, argTypes.length - pos);
185+
System.arraycopy(argTypes, pos, newArgs, destPos, argTypes.length - pos);
186+
}
187+
// Validate after copying to avoid TOCTOU
188+
for (int i = pos; i < destPos; i++) {
189+
validateArgument(newArgs[i]);
167190
}
168-
return ofTrusted(returnType, newArgs);
191+
192+
return ofValidated(returnType, newArgs);
169193
}
170194

171195
@Override

‎src/java.base/share/classes/java/lang/constant/ModuleDescImpl.java ‎src/java.base/share/classes/jdk/internal/constant/ModuleDescImpl.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
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.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,13 +22,15 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package java.lang.constant;
25+
package jdk.internal.constant;
26+
27+
import java.lang.constant.ModuleDesc;
2628

2729
/*
2830
* Implementation of {@code ModuleDesc}
2931
* @param name must have been validated
3032
*/
31-
record ModuleDescImpl(String name) implements ModuleDesc {
33+
public record ModuleDescImpl(String name) implements ModuleDesc {
3234

3335
@Override
3436
public String toString() {

‎src/java.base/share/classes/java/lang/constant/PackageDescImpl.java ‎src/java.base/share/classes/jdk/internal/constant/PackageDescImpl.java

+5-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
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.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,13 +22,15 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package java.lang.constant;
25+
package jdk.internal.constant;
26+
27+
import java.lang.constant.PackageDesc;
2628

2729
/*
2830
* Implementation of {@code PackageDesc}
2931
* @param internalName must have been validated
3032
*/
31-
record PackageDescImpl(String internalName) implements PackageDesc {
33+
public record PackageDescImpl(String internalName) implements PackageDesc {
3234

3335
@Override
3436
public String toString() {

‎src/java.base/share/classes/java/lang/constant/PrimitiveClassDescImpl.java ‎src/java.base/share/classes/jdk/internal/constant/PrimitiveClassDescImpl.java

+7-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,8 +22,11 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package java.lang.constant;
25+
package jdk.internal.constant;
2626

27+
import java.lang.constant.ClassDesc;
28+
import java.lang.constant.ConstantDescs;
29+
import java.lang.constant.DynamicConstantDesc;
2730
import java.lang.invoke.MethodHandles;
2831

2932
import sun.invoke.util.Wrapper;
@@ -34,7 +37,7 @@
3437
* A <a href="package-summary.html#nominal">nominal descriptor</a> for the class
3538
* constant corresponding to a primitive type (e.g., {@code int.class}).
3639
*/
37-
final class PrimitiveClassDescImpl
40+
public final class PrimitiveClassDescImpl
3841
extends DynamicConstantDesc<Class<?>> implements ClassDesc {
3942

4043
private final String descriptor;
@@ -49,7 +52,7 @@ final class PrimitiveClassDescImpl
4952
* describe a valid primitive type
5053
* @jvms 4.3 Descriptors
5154
*/
52-
PrimitiveClassDescImpl(String descriptor) {
55+
public PrimitiveClassDescImpl(String descriptor) {
5356
super(ConstantDescs.BSM_PRIMITIVE_CLASS, requireNonNull(descriptor), ConstantDescs.CD_Class);
5457
if (descriptor.length() != 1
5558
|| "VIJCSBFDZ".indexOf(descriptor.charAt(0)) < 0)

‎src/java.base/share/classes/java/lang/constant/ReferenceClassDescImpl.java ‎src/java.base/share/classes/jdk/internal/constant/ReferenceClassDescImpl.java

+22-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,21 +22,25 @@
2222
* or visit www.oracle.com if you need additional information or have any
2323
* questions.
2424
*/
25-
package java.lang.constant;
25+
package jdk.internal.constant;
2626

27+
import java.lang.constant.ClassDesc;
2728
import java.lang.invoke.MethodHandles;
2829

29-
import static java.lang.constant.ConstantUtils.*;
30-
import static java.util.Objects.requireNonNull;
30+
import static jdk.internal.constant.ConstantUtils.*;
3131

3232
/**
3333
* A <a href="package-summary.html#nominal">nominal descriptor</a> for a class,
3434
* interface, or array type. A {@linkplain ReferenceClassDescImpl} corresponds to a
3535
* {@code Constant_Class_info} entry in the constant pool of a classfile.
3636
*/
37-
final class ReferenceClassDescImpl implements ClassDesc {
37+
public final class ReferenceClassDescImpl implements ClassDesc {
3838
private final String descriptor;
3939

40+
private ReferenceClassDescImpl(String descriptor) {
41+
this.descriptor = descriptor;
42+
}
43+
4044
/**
4145
* Creates a {@linkplain ClassDesc} from a descriptor string for a class or
4246
* interface type or an array type.
@@ -46,12 +50,23 @@ final class ReferenceClassDescImpl implements ClassDesc {
4650
* field descriptor string, or does not describe a class or interface type
4751
* @jvms 4.3.2 Field Descriptors
4852
*/
49-
ReferenceClassDescImpl(String descriptor) {
53+
public static ReferenceClassDescImpl of(String descriptor) {
5054
int dLen = descriptor.length();
5155
int len = ConstantUtils.skipOverFieldSignature(descriptor, 0, dLen, false);
5256
if (len <= 1 || len != dLen)
5357
throw new IllegalArgumentException(String.format("not a valid reference type descriptor: %s", descriptor));
54-
this.descriptor = descriptor;
58+
return new ReferenceClassDescImpl(descriptor);
59+
}
60+
61+
/**
62+
* Creates a {@linkplain ClassDesc} from a pre-validated descriptor string
63+
* for a class or interface type or an array type.
64+
*
65+
* @param descriptor a field descriptor string for a class or interface type
66+
* @jvms 4.3.2 Field Descriptors
67+
*/
68+
public static ReferenceClassDescImpl ofValidated(String descriptor) {
69+
return new ReferenceClassDescImpl(descriptor);
5570
}
5671

5772
@Override

‎test/jdk/java/lang/constant/ClassDescTest.java

+6
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,12 @@ public void testArrayClassDesc() throws ReflectiveOperationException {
237237
testBadArrayRank(ClassDesc.of("Bar"));
238238
testArrayRankOverflow();
239239
}
240+
try {
241+
ConstantDescs.CD_void.arrayType();
242+
fail("Should throw IAE");
243+
} catch (IllegalArgumentException iae) {
244+
// Expected
245+
}
240246
}
241247

242248
public void testBadClassDescs() {

‎test/jdk/java/lang/constant/boottest/java.base/java/lang/constant/ConstantUtilsTest.java ‎test/jdk/java/lang/constant/boottest/java.base/jdk/internal/constant/ConstantUtilsTest.java

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -21,9 +21,8 @@
2121
* questions.
2222
*/
2323

24-
package java.lang.constant;
24+
package jdk.internal.constant;
2525

26-
import java.lang.invoke.*;
2726
import java.lang.constant.*;
2827
import java.util.*;
2928

@@ -35,6 +34,7 @@
3534
* @test
3635
* @bug 8303930
3736
* @compile ConstantUtilsTest.java
37+
* @modules java.base/jdk.internal.constant
3838
* @run testng ConstantUtilsTest
3939
* @summary unit tests for methods of java.lang.constant.ConstantUtils that are not covered by other unit tests
4040
*/

‎test/micro/org/openjdk/bench/java/lang/constant/ClassDescFactories.java

+16
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
import org.openjdk.jmh.annotations.Warmup;
3636

3737
import java.lang.constant.ClassDesc;
38+
import java.lang.constant.ConstantDescs;
3839
import java.util.concurrent.TimeUnit;
3940

4041
/**
@@ -60,4 +61,19 @@ public class ClassDescFactories {
6061
public ClassDesc ofDescriptor() {
6162
return ClassDesc.ofDescriptor(descString);
6263
}
64+
65+
@BenchmarkMode(Mode.AverageTime)
66+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
67+
@Warmup(iterations = 3, time = 2)
68+
@Measurement(iterations = 6, time = 1)
69+
@Fork(1)
70+
@State(Scope.Thread)
71+
public static class ReferenceOnly {
72+
public ClassDesc desc = ConstantDescs.CD_Object;
73+
@Benchmark
74+
public ClassDesc ofNested() {
75+
return desc.nested("Foo");
76+
}
77+
78+
}
6379
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright (c) 2024, 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+
package org.openjdk.bench.java.lang.constant;
24+
25+
import org.openjdk.jmh.annotations.Benchmark;
26+
import org.openjdk.jmh.annotations.BenchmarkMode;
27+
import org.openjdk.jmh.annotations.Fork;
28+
import org.openjdk.jmh.annotations.Measurement;
29+
import org.openjdk.jmh.annotations.Mode;
30+
import org.openjdk.jmh.annotations.OutputTimeUnit;
31+
import org.openjdk.jmh.annotations.Param;
32+
import org.openjdk.jmh.annotations.Scope;
33+
import org.openjdk.jmh.annotations.State;
34+
import org.openjdk.jmh.annotations.Warmup;
35+
import org.openjdk.jmh.infra.Blackhole;
36+
37+
import java.lang.constant.ClassDesc;
38+
import java.lang.constant.ConstantDescs;
39+
import java.util.concurrent.TimeUnit;
40+
41+
/**
42+
* Test various operations on
43+
*/
44+
@BenchmarkMode(Mode.AverageTime)
45+
@OutputTimeUnit(TimeUnit.NANOSECONDS)
46+
@Warmup(iterations = 3, time = 2)
47+
@Measurement(iterations = 5, time = 1)
48+
@Fork(3)
49+
@State(Scope.Thread)
50+
public class ClassDescMethods {
51+
52+
@Benchmark
53+
public String packageName() {
54+
return ConstantDescs.CD_Object.packageName();
55+
}
56+
57+
@Benchmark
58+
public String displayName() {
59+
return ConstantDescs.CD_Object.displayName();
60+
}
61+
62+
@Benchmark
63+
public void arrayType(Blackhole bh) {
64+
bh.consume(ConstantDescs.CD_Object.arrayType());
65+
bh.consume(ConstantDescs.CD_boolean.arrayType());
66+
}
67+
68+
@Benchmark
69+
public void arrayType1(Blackhole bh) {
70+
bh.consume(ConstantDescs.CD_Object.arrayType(1));
71+
bh.consume(ConstantDescs.CD_boolean.arrayType(1));
72+
}
73+
74+
@Benchmark
75+
public void arrayType2(Blackhole bh) {
76+
bh.consume(ConstantDescs.CD_Object.arrayType(2));
77+
bh.consume(ConstantDescs.CD_boolean.arrayType(2));
78+
}
79+
}

1 commit comments

Comments
 (1)

openjdk-notifier[bot] commented on May 17, 2024

@openjdk-notifier[bot]
Please sign in to comment.