On Thu, 13 Jun 2024 14:31:06 GMT, David M. Lloyd <d...@openjdk.org> wrote:
> Issue [JDK-8164908](https://bugs.openjdk.org/browse/JDK-8164908) added > support for functionality required to continue to support IIOP and custom > serializers in light of additional module-based restrictions on reflection. > It was expected that these libraries would use `sun.misc.Unsafe` in order to > access fields of serializable classes. However, with JEP 471, the methods > necessary to do this are being removed. > > To allow these libraries to continue to function, it is proposed to add two > methods to `sun.reflect.ReflectionFactory` which will allow serialization > libraries to acquire a method handle to generated `readObject`/`writeObject` > methods which set or get the fields of the serializable class using the > serialization `GetField`/`PutField` mechanism. These generated methods should > be used by serialization libraries to serialize and deserialize classes which > do not have a `readObject`/`writeObject` method or which use > `ObjectInputStream.defaultReadObject`/`ObjectOutputStream.defaultWriteObject` > to supplement default serialization. > > It is also proposed to add methods which allow for the reading of > serialization-specific private static final fields from classes which have > them. > > With the addition of these methods, serialization libraries no longer need to > rely on `Unsafe` for serialization/deserialization activities. > cc: @AlanBateman Since [JDK‑8331724], this can use the implementation classes in `jdk.internal.constant` to speed up default (de)serialization code generation startup. [JDK‑8331724]: https://bugs.openjdk.org/browse/JDK-8331724 Relevant issue: - https://github.com/openjdk/jdk/pull/15364 src/java.base/share/classes/jdk/internal/reflect/SerializationBytecodeGenerator.java line 55: > 53: // build an anonymous+hidden nestmate to perform the read > operation > 54: List<MethodHandle> setters = new ArrayList<>(); > 55: byte[] bytes = ClassFile.of().build(CD_Genearted_readObject, > classBuilder -> classBuilder.withMethod("readObject", Suggestion: byte[] bytes = ClassFile.of().build(CD_Generated_readObject, classBuilder -> classBuilder.withMethod("readObject", src/java.base/share/classes/jdk/internal/reflect/SerializationBytecodeGenerator.java line 239: > 237: > 238: private static final ClassDesc CD_Generated_writeObject = > ClassDesc.of("jdk.internal.reflect", "Generated$$writeObject"); > 239: private static final ClassDesc CD_Genearted_readObject = > ClassDesc.of("jdk.internal.reflect", "Generated$$readObject"); It might be better to use `ReferenceClassDescImpl.ofValidated(String)` here, or at least `ClassDesc.ofDescriptor(String)` to avoid binary to internal name conversion: Suggestion: private static final ClassDesc CD_ObjectInputStream = ReferenceClassDescImpl.ofValidated("Ljava/io/ObjectInputStream;"); private static final ClassDesc CD_ObjectInputStream_GetField = ReferenceClassDescImpl.ofValidated("Ljava/io/ObjectInputStream$GetField;"); private static final ClassDesc CD_ObjectOutputStream = ReferenceClassDescImpl.ofValidated("Ljava/io/ObjectOutputStream;"); private static final ClassDesc CD_ObjectOutputStream_PutField = ReferenceClassDescImpl.ofValidated("Ljava/io/ObjectOutputStream$PutField;"); private static final ClassDesc CD_Generated_writeObject = ReferenceClassDescImpl.ofValidated("Ljdk/internal/reflect/Generated$$writeObject;"); private static final ClassDesc CD_Generated_readObject = ReferenceClassDescImpl.ofValidated("Ljdk/internal/reflect/Generated$$readObject;"); src/java.base/share/classes/jdk/internal/reflect/SerializationBytecodeGenerator.java line 263: > 261: private static final MethodTypeDesc > MTD_ObjectOutputStream_PutField_put_L = > MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String, > ConstantDescs.CD_Object); > 262: private static final MethodTypeDesc > MTD_ObjectOutputStream_PutField_put_S = > MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String, > ConstantDescs.CD_short); > 263: private static final MethodTypeDesc > MTD_ObjectOutputStream_PutField_put_Z = > MethodTypeDesc.of(ConstantDescs.CD_void, ConstantDescs.CD_String, > ConstantDescs.CD_boolean); Using `MethodTypeDescImpl.ofTrusted(…)` or at least `MethodTypeDescImpl.ofValidated(…)` here avoids array copying: Suggestion: private static final MethodTypeDesc MTD_ObjectInputStream_readFields = MethodTypeDescImpl.ofValidated(CD_ObjectInputStream_GetField); private static final MethodTypeDesc MTD_ObjectInputStream_GetField_get_B = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_byte, ConstantDescs.CD_String, ConstantDescs.CD_byte); private static final MethodTypeDesc MTD_ObjectInputStream_GetField_get_C = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_char, ConstantDescs.CD_String, ConstantDescs.CD_char); private static final MethodTypeDesc MTD_ObjectInputStream_GetField_get_D = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_double, ConstantDescs.CD_String, ConstantDescs.CD_double); private static final MethodTypeDesc MTD_ObjectInputStream_GetField_get_F = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_float, ConstantDescs.CD_String, ConstantDescs.CD_float); private static final MethodTypeDesc MTD_ObjectInputStream_GetField_get_I = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_int, ConstantDescs.CD_String, ConstantDescs.CD_int); private static final MethodTypeDesc MTD_ObjectInputStream_GetField_get_J = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_long, ConstantDescs.CD_String, ConstantDescs.CD_long); private static final MethodTypeDesc MTD_ObjectInputStream_GetField_get_L = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_Object, ConstantDescs.CD_String, ConstantDescs.CD_Object); private static final MethodTypeDesc MTD_ObjectInputStream_GetField_get_S = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_short, ConstantDescs.CD_String, ConstantDescs.CD_short); private static final MethodTypeDesc MTD_ObjectInputStream_GetField_get_Z = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_boolean, ConstantDescs.CD_String, ConstantDescs.CD_boolean); private static final MethodTypeDesc MTD_ObjectOutputStream_putFields = MethodTypeDescImpl.ofValidated(CD_ObjectOutputStream_PutField); private static final MethodTypeDesc MTD_ObjectOutputStream_PutField_put_B = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_void, ConstantDescs.CD_String, ConstantDescs.CD_byte); private static final MethodTypeDesc MTD_ObjectOutputStream_PutField_put_C = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_void, ConstantDescs.CD_String, ConstantDescs.CD_char); private static final MethodTypeDesc MTD_ObjectOutputStream_PutField_put_D = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_void, ConstantDescs.CD_String, ConstantDescs.CD_double); private static final MethodTypeDesc MTD_ObjectOutputStream_PutField_put_F = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_void, ConstantDescs.CD_String, ConstantDescs.CD_float); private static final MethodTypeDesc MTD_ObjectOutputStream_PutField_put_I = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_void, ConstantDescs.CD_String, ConstantDescs.CD_int); private static final MethodTypeDesc MTD_ObjectOutputStream_PutField_put_J = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_void, ConstantDescs.CD_String, ConstantDescs.CD_long); private static final MethodTypeDesc MTD_ObjectOutputStream_PutField_put_L = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_void, ConstantDescs.CD_String, ConstantDescs.CD_Object); private static final MethodTypeDesc MTD_ObjectOutputStream_PutField_put_S = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_void, ConstantDescs.CD_String, ConstantDescs.CD_short); private static final MethodTypeDesc MTD_ObjectOutputStream_PutField_put_Z = MethodTypeDescImpl.ofValidated(ConstantDescs.CD_void, ConstantDescs.CD_String, ConstantDescs.CD_boolean); ------------- PR Review: https://git.openjdk.org/jdk/pull/19702#pullrequestreview-2149053446 PR Comment: https://git.openjdk.org/jdk/pull/19702#issuecomment-2175793616 PR Review Comment: https://git.openjdk.org/jdk/pull/19702#discussion_r1659368798 PR Review Comment: https://git.openjdk.org/jdk/pull/19702#discussion_r1659368645 PR Review Comment: https://git.openjdk.org/jdk/pull/19702#discussion_r1659372351