On 28/04/2020 21:44, Maurizio Cimadamore wrote:

On 28/04/2020 19:09, Mandy Chung wrote:
On 4/28/20 12:58 AM, fo...@univ-mlv.fr wrote:




        I don't think you need to store all the values into static fields, you can directly do a ldc + aaload with the right index right where you need it,


    I think this is what you are thinking as reported in JDK-8243492:
http://cr.openjdk.java.net/~mchung/jdk15/webrevs/8239578/webrev.01-accessor/


if the accessors are declared ACC_STATIC, yes !


Thanks for catching this and this way will not be hit JDK-824349.

Here is the revised patch:
http://cr.openjdk.java.net/~mchung/jdk15/webrevs/8239578/webrev.02/

Maurizio - do you mind remerge MemoryAccessVarHandleGenerator.java with webrev.02?

I'll take care of that

Not going down this road, sorry :-)

I've added the changes (see attached patch), and all benchmarks are several order of magnitude slower. I think this is mostly caused by the fact that the addOffset/multiplyOffset handle are no  longer cached in static constants.

While I understand that there might be better ways to generate the code, I'd strongly prefer to leave the code as per last iteration. I can't honestly see in which way having 3-4 static fields in a synthetic VarHandle class is going to hurt (but I can see how much it hurts by not having said fields).

Cheers
Maurizio


Maurizio


thanks
Mandy
diff -r 148c3b3445c6 src/java.base/share/classes/java/lang/invoke/MemoryAccessVarHandleGenerator.java
--- a/src/java.base/share/classes/java/lang/invoke/MemoryAccessVarHandleGenerator.java	Mon Apr 27 13:01:54 2020 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/MemoryAccessVarHandleGenerator.java	Wed Apr 29 02:09:58 2020 +0100
@@ -54,11 +54,9 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.ACC_SUPER;
 import static jdk.internal.org.objectweb.asm.Opcodes.ALOAD;
 import static jdk.internal.org.objectweb.asm.Opcodes.ARETURN;
-import static jdk.internal.org.objectweb.asm.Opcodes.ASTORE;
 import static jdk.internal.org.objectweb.asm.Opcodes.BIPUSH;
 import static jdk.internal.org.objectweb.asm.Opcodes.CHECKCAST;
 import static jdk.internal.org.objectweb.asm.Opcodes.GETFIELD;
-import static jdk.internal.org.objectweb.asm.Opcodes.GETSTATIC;
 import static jdk.internal.org.objectweb.asm.Opcodes.H_INVOKESTATIC;
 import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_0;
 import static jdk.internal.org.objectweb.asm.Opcodes.ICONST_1;
@@ -73,7 +71,6 @@
 import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD;
 import static jdk.internal.org.objectweb.asm.Opcodes.NEWARRAY;
 import static jdk.internal.org.objectweb.asm.Opcodes.PUTFIELD;
-import static jdk.internal.org.objectweb.asm.Opcodes.PUTSTATIC;
 import static jdk.internal.org.objectweb.asm.Opcodes.RETURN;
 import static jdk.internal.org.objectweb.asm.Opcodes.DUP;
 import static jdk.internal.org.objectweb.asm.Opcodes.SIPUSH;
@@ -192,7 +189,7 @@
             cw.visitField(ACC_PRIVATE | ACC_FINAL, "dim" + i, "J", null, null);
         }
 
-        addStaticInitializer(cw);
+        addClassDataAccessors(cw);
 
         addConstructor(cw);
 
@@ -210,44 +207,58 @@
         return cw.toByteArray();
     }
 
-    void addStaticInitializer(ClassWriter cw) {
-        // carrier and intermediate
-        cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "carrier", Class.class.descriptorString(), null, null);
-        cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "intermediate", Class[].class.descriptorString(), null, null);
-        cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "addHandle", MethodHandle.class.descriptorString(), null, null);
-        cw.visitField(ACC_PRIVATE | ACC_STATIC | ACC_FINAL, "mulHandle", MethodHandle.class.descriptorString(), null, null);
-
-        MethodVisitor mv = cw.visitMethod(Opcodes.ACC_STATIC, "<clinit>", "()V", null, null);
-        mv.visitCode();
-        // extract class data in static final fields
+    void addClassDataAccessors(ClassWriter cw) {
+        // BSM to load class data
         MethodType mtype = MethodType.methodType(Object.class, MethodHandles.Lookup.class, String.class, Class.class);
         Handle bsm = new Handle(H_INVOKESTATIC, Type.getInternalName(MethodHandles.class), "classData",
-                    mtype.descriptorString(), false);
+                mtype.descriptorString(), false);
         ConstantDynamic dynamic = new ConstantDynamic("classData", Object[].class.descriptorString(), bsm);
+
+        // static method to get carrierType
+        MethodVisitor mv = cw.visitMethod(ACC_FINAL | ACC_STATIC, "carrierType",
+                MethodType.methodType(Class.class).descriptorString(), null, null);
+        mv.visitCode();
         mv.visitLdcInsn(dynamic);
-        mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Object[].class));
-        mv.visitVarInsn(ASTORE, 0);
-        mv.visitVarInsn(ALOAD, 0);
         mv.visitInsn(ICONST_0);
         mv.visitInsn(AALOAD);
         mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Class.class));
-        mv.visitFieldInsn(PUTSTATIC, implClassName, "carrier", Class.class.descriptorString());
-        mv.visitVarInsn(ALOAD, 0);
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        // static method to get the types of "intermediate" parameter
+        mv = cw.visitMethod(ACC_FINAL | ACC_STATIC, "intermediateTypes",
+                MethodType.methodType(Class[].class).descriptorString(), null, null);
+        mv.visitCode();
+        mv.visitLdcInsn(dynamic);
         mv.visitInsn(ICONST_1);
         mv.visitInsn(AALOAD);
         mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Class[].class));
-        mv.visitFieldInsn(PUTSTATIC, implClassName, "intermediate", Class[].class.descriptorString());
-        mv.visitVarInsn(ALOAD, 0);
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        // static method to get the MemoruAddressProxy::addOffsets handle
+        mv = cw.visitMethod(ACC_FINAL | ACC_STATIC, "addHandle",
+                MethodType.methodType(MethodHandle.class).descriptorString(), null, null);
+        mv.visitCode();
+        mv.visitLdcInsn(dynamic);
         mv.visitInsn(ICONST_2);
         mv.visitInsn(AALOAD);
         mv.visitTypeInsn(CHECKCAST, Type.getInternalName(MethodHandle.class));
-        mv.visitFieldInsn(PUTSTATIC, implClassName, "addHandle", MethodHandle.class.descriptorString());
-        mv.visitVarInsn(ALOAD, 0);
+        mv.visitInsn(ARETURN);
+        mv.visitMaxs(0, 0);
+        mv.visitEnd();
+
+        // static method to get the MemoruAddressProxy::multiplyOffsets handle
+        mv = cw.visitMethod(ACC_FINAL | ACC_STATIC, "mulHandle",
+                MethodType.methodType(MethodHandle.class).descriptorString(), null, null);
+        mv.visitCode();
+        mv.visitLdcInsn(dynamic);
         mv.visitInsn(ICONST_3);
         mv.visitInsn(AALOAD);
         mv.visitTypeInsn(CHECKCAST, Type.getInternalName(MethodHandle.class));
-        mv.visitFieldInsn(PUTSTATIC, implClassName, "mulHandle", MethodHandle.class.descriptorString());
-        mv.visitInsn(Opcodes.RETURN);
+        mv.visitInsn(ARETURN);
         mv.visitMaxs(0, 0);
         mv.visitEnd();
     }
@@ -287,8 +298,10 @@
         mv.visitFieldInsn(GETFIELD, Type.getInternalName(VarHandle.AccessMode.class), "at", VarHandle.AccessType.class.descriptorString());
         mv.visitLdcInsn(Type.getType(MemoryAddressProxy.class));
         mv.visitTypeInsn(CHECKCAST, Type.getInternalName(Class.class));
-        mv.visitFieldInsn(GETSTATIC, implClassName, "carrier", Class.class.descriptorString());
-        mv.visitFieldInsn(GETSTATIC, implClassName, "intermediate", Class[].class.descriptorString());
+        mv.visitMethodInsn(INVOKESTATIC, implClassName, "carrierType",
+                MethodType.methodType(Class.class).descriptorString(), false);
+        mv.visitMethodInsn(INVOKESTATIC, implClassName, "intermediateTypes",
+                MethodType.methodType(Class[].class).descriptorString(), false);
 
         mv.visitMethodInsn(INVOKEVIRTUAL, Type.getInternalName(VarHandle.AccessType.class),
                 "accessModeType", MethodType.methodType(MethodType.class, Class.class, Class.class, Class[].class).toMethodDescriptorString(), false);
@@ -331,15 +344,16 @@
             mv.visitFieldInsn(GETFIELD, Type.getInternalName(BASE_CLASS), "offset", "J");
             for (int i = 0 ; i < dimensions ; i++) {
                 // load ADD MH
-                mv.visitFieldInsn(GETSTATIC, implClassName, "addHandle", MethodHandle.class.descriptorString());
+                mv.visitMethodInsn(INVOKESTATIC, implClassName, "addHandle",
+                        MethodType.methodType(MethodHandle.class).descriptorString(), false);
 
                 //fixup stack so that ADD MH ends up bottom
                 mv.visitInsn(Opcodes.DUP_X2);
                 mv.visitInsn(Opcodes.POP);
 
                 // load MUL MH
-                mv.visitFieldInsn(GETSTATIC, implClassName, "mulHandle", MethodHandle.class.descriptorString());
-                mv.visitTypeInsn(CHECKCAST, Type.getInternalName(MethodHandle.class));
+                mv.visitMethodInsn(INVOKESTATIC, implClassName, "mulHandle",
+                        MethodType.methodType(MethodHandle.class).descriptorString(), false);
 
                 mv.visitVarInsn(ALOAD, 0); // load recv
                 mv.visitTypeInsn(CHECKCAST, implClassName);
@@ -403,7 +417,8 @@
     void addCarrierAccessor(ClassWriter cw) {
         MethodVisitor mv = cw.visitMethod(ACC_FINAL, "carrier", "()Ljava/lang/Class;", null, null);
         mv.visitCode();
-        mv.visitFieldInsn(GETSTATIC, implClassName, "carrier", Class.class.descriptorString());
+        mv.visitMethodInsn(INVOKESTATIC, implClassName, "carrierType",
+                MethodType.methodType(Class.class).descriptorString(), false);
         mv.visitInsn(ARETURN);
         mv.visitMaxs(0, 0);
         mv.visitEnd();

Reply via email to