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

Reply via email to