From 019fcd819c4f24e6c9de9d4f9fc64b8db6bc6cfa Mon Sep 17 00:00:00 2001 From: Chen Liang Date: Tue, 21 Mar 2023 16:16:08 +0000 Subject: [PATCH] 8304139: Add and method constants to ConstantDescs Reviewed-by: mchung --- .../share/classes/java/lang/Class.java | 24 ++++++++------- .../classes/java/lang/StackTraceElement.java | 7 +++-- .../java/lang/constant/ConstantDescs.java | 29 ++++++++++++++++++- .../java/lang/constant/ConstantUtils.java | 2 +- .../lang/constant/DirectMethodHandleDesc.java | 2 +- .../java/lang/invoke/MethodHandleInfo.java | 3 +- .../java/lang/invoke/MethodHandles.java | 10 ++++--- 7 files changed, 56 insertions(+), 21 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index 9e59f3438e9..2c57cde97a9 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -27,6 +27,7 @@ package java.lang; import java.lang.annotation.Annotation; import java.lang.constant.ClassDesc; +import java.lang.constant.ConstantDescs; import java.lang.invoke.TypeDescriptor; import java.lang.invoke.MethodHandles; import java.lang.module.ModuleReader; @@ -1524,9 +1525,9 @@ public final class Class implements java.io.Serializable, return enclosingClass == null || name == null || descriptor == null; } - boolean isConstructor() { return !isPartial() && "".equals(name); } + boolean isConstructor() { return !isPartial() && ConstantDescs.INIT_NAME.equals(name); } - boolean isMethod() { return !isPartial() && !isConstructor() && !"".equals(name); } + boolean isMethod() { return !isPartial() && !isConstructor() && !ConstantDescs.CLASS_INIT_NAME.equals(name); } Class getEnclosingClass() { return enclosingClass; } @@ -2040,8 +2041,8 @@ public final class Class implements java.io.Serializable, * has length 0. (Note that a {@code Class} object which represents a class * always has public methods, inherited from {@code Object}.) * - *

The returned array never contains methods with names "{@code }" - * or "{@code }". + *

The returned array never contains methods with names {@value + * ConstantDescs#INIT_NAME} or {@value ConstantDescs#CLASS_INIT_NAME}. * *

The elements in the returned array are not sorted and are not in any * particular order. @@ -2234,8 +2235,8 @@ public final class Class implements java.io.Serializable, * this interface or any of its superinterfaces, then this method does not * find any method. * - *

This method does not find any method with name "{@code }" or - * "{@code }". + *

This method does not find any method with name {@value + * ConstantDescs#INIT_NAME} or {@value ConstantDescs#CLASS_INIT_NAME}. * *

Generally, the method to be reflected is determined by the 4 step * algorithm that follows. @@ -2293,7 +2294,8 @@ public final class Class implements java.io.Serializable, * @return the {@code Method} object that matches the specified * {@code name} and {@code parameterTypes} * @throws NoSuchMethodException if a matching method is not found - * or if the name is "<init>"or "<clinit>". + * or if the name is {@value ConstantDescs#INIT_NAME} or + * {@value ConstantDescs#CLASS_INIT_NAME}. * @throws NullPointerException if {@code name} is {@code null} * @throws SecurityException * If a security manager, s, is present and @@ -2549,8 +2551,9 @@ public final class Class implements java.io.Serializable, * object for each such method. * *

If this {@code Class} object represents a class or interface that - * has a class initialization method {@code }, then the returned - * array does not have a corresponding {@code Method} object. + * has a class initialization method {@value ConstantDescs#CLASS_INIT_NAME}, + * then the returned array does not have a corresponding {@code + * Method} object. * *

If this {@code Class} object represents a class or interface with no * declared methods, then the returned array has length 0. @@ -2721,7 +2724,8 @@ public final class Class implements java.io.Serializable, * parameter types is declared in a class, and one of these methods has a * return type that is more specific than any of the others, that method is * returned; otherwise one of the methods is chosen arbitrarily. If the - * name is "<init>"or "<clinit>" a {@code NoSuchMethodException} + * name is {@value ConstantDescs#INIT_NAME} or {@value + * ConstantDescs#CLASS_INIT_NAME} a {@code NoSuchMethodException} * is raised. * *

If this {@code Class} object represents an array type, then this diff --git a/src/java.base/share/classes/java/lang/StackTraceElement.java b/src/java.base/share/classes/java/lang/StackTraceElement.java index a98e2b72ae7..fc39291b316 100644 --- a/src/java.base/share/classes/java/lang/StackTraceElement.java +++ b/src/java.base/share/classes/java/lang/StackTraceElement.java @@ -30,6 +30,7 @@ import jdk.internal.misc.VM; import jdk.internal.module.ModuleHashes; import jdk.internal.module.ModuleReferenceImpl; +import java.lang.constant.ConstantDescs; import java.lang.module.ModuleReference; import java.lang.module.ResolvedModule; import java.util.HashSet; @@ -262,9 +263,9 @@ public final class StackTraceElement implements java.io.Serializable { * Returns the name of the method containing the execution point * represented by this stack trace element. If the execution point is * contained in an instance or class initializer, this method will return - * the appropriate special method name, {@code } or - * {@code }, as per Section {@jvms 3.9} of The Java Virtual - * Machine Specification. + * the appropriate special method name, {@value ConstantDescs#INIT_NAME} + * or {@value ConstantDescs#CLASS_INIT_NAME}, as per Section {@jvms 3.9} + * of The Java Virtual Machine Specification. * * @return the name of the method containing the execution point * represented by this stack trace element. diff --git a/src/java.base/share/classes/java/lang/constant/ConstantDescs.java b/src/java.base/share/classes/java/lang/constant/ConstantDescs.java index 08dbb031cdc..bd489386ea2 100644 --- a/src/java.base/share/classes/java/lang/constant/ConstantDescs.java +++ b/src/java.base/share/classes/java/lang/constant/ConstantDescs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -299,6 +299,33 @@ public final class ConstantDescs { = DynamicConstantDesc.ofNamed(BSM_GET_STATIC_FINAL, "FALSE", CD_Boolean, CD_Boolean); + /** + * The special name of instance initialization methods, {@value}. An instance + * initialization method has this special name and is {@code void}. + * + * @jvms 2.9.1 Instance Initialization Methods + * @since 21 + */ + public static final String INIT_NAME = ""; + + /** + * The special name of class initialization methods, {@value}. A class + * initialization method has this special name, {@link java.lang.reflect.AccessFlag#STATIC + * ACC_STATIC} flag set, is {@link #MTD_void void} and takes no arguments. + * + * @jvms 2.9.2 Class Initialization Methods + * @since 21 + */ + public static final String CLASS_INIT_NAME = ""; + + /** + * Nominal descriptor representing the method descriptor {@code ()V}, + * taking no argument and returning {@code void}. + * + * @since 21 + */ + public static final MethodTypeDesc MTD_void = MethodTypeDesc.of(CD_void); + static final DirectMethodHandleDesc MHD_METHODHANDLE_ASTYPE = MethodHandleDesc.ofMethod(Kind.VIRTUAL, CD_MethodHandle, "asType", MethodTypeDesc.of(CD_MethodHandle, CD_MethodType)); diff --git a/src/java.base/share/classes/java/lang/constant/ConstantUtils.java b/src/java.base/share/classes/java/lang/constant/ConstantUtils.java index 75bd6642dbc..b397664145f 100644 --- a/src/java.base/share/classes/java/lang/constant/ConstantUtils.java +++ b/src/java.base/share/classes/java/lang/constant/ConstantUtils.java @@ -39,7 +39,7 @@ class ConstantUtils { static final Constable[] EMPTY_CONSTABLE = new Constable[0]; static final int MAX_ARRAY_TYPE_DESC_DIMENSIONS = 255; - private static final Set pointyNames = Set.of("", ""); + private static final Set pointyNames = Set.of(ConstantDescs.INIT_NAME, ConstantDescs.CLASS_INIT_NAME); /** * Validates the correctness of a binary class name. In particular checks for the presence of diff --git a/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDesc.java b/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDesc.java index 7d7ec71ca6f..c725ccfb091 100644 --- a/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDesc.java +++ b/src/java.base/share/classes/java/lang/constant/DirectMethodHandleDesc.java @@ -231,7 +231,7 @@ public sealed interface DirectMethodHandleDesc /** * Returns the name of the method or field described by this nominal descriptor. - * For constructors, returns the reserved name {@code ""}. + * For constructors, returns the reserved name {@value ConstantDescs#INIT_NAME}. * * @return the name of the method or field */ diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java index 42b5339de9c..a1a9580ac33 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleInfo.java @@ -160,7 +160,8 @@ public interface MethodHandleInfo { /** * Returns the name of the cracked method handle's underlying member. - * This is {@code ""} if the underlying member was a constructor, + * This is {@value java.lang.constant.ConstantDescs#INIT_NAME} + * if the underlying member was a constructor, * else it is a simple method name or field name. * @return the simple name of the underlying member */ diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java index 68362980a04..baf5296739c 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandles.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandles.java @@ -712,7 +712,8 @@ public class MethodHandles { * (See the Java Virtual Machine Specification, section {@jvms 4.10.1.9}.) *

* The JVM represents constructors and static initializer blocks as internal methods - * with special names ({@code ""} and {@code ""}). + * with special names ({@value ConstantDescs#INIT_NAME} and {@value + * ConstantDescs#CLASS_INIT_NAME}). * The internal syntax of invocation instructions allows them to refer to such internal * methods as if they were normal methods, but the JVM bytecode verifier rejects them. * A lookup of such an internal method will produce a {@code NoSuchMethodException}. @@ -2768,7 +2769,7 @@ assertEquals("[x, y, z]", pb.command().toString()); if (refc.isArray()) { throw new NoSuchMethodException("no constructor for array class: " + refc.getName()); } - String name = ""; + String name = ConstantDescs.INIT_NAME; MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type); return getDirectConstructor(refc, ctor); } @@ -2964,7 +2965,8 @@ assertEquals("[x, y, z]", pb.command().toString()); * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if * the method's variable arity modifier bit ({@code 0x0080}) is set. *

- * (Note: JVM internal methods named {@code ""} are not visible to this API, + * (Note: JVM internal methods named {@value ConstantDescs#INIT_NAME} + * are not visible to this API, * even though the {@code invokespecial} instruction can refer to them * in special circumstances. Use {@link #findConstructor findConstructor} * to access instance initialization methods in a safe manner.) @@ -4002,7 +4004,7 @@ return mh1; !refc.isInterface() && refc != lookupClass().getSuperclass() && refc.isAssignableFrom(lookupClass())) { - assert(!method.getName().equals("")); // not this code path + assert(!method.getName().equals(ConstantDescs.INIT_NAME)); // not this code path // Per JVMS 6.5, desc. of invokespecial instruction: // If the method is in a superclass of the LC,