< prev index next >

test/compiler/unsafe/UnsafeGetConstantField.java

Print this page




  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * @test
  28  * @summary tests on constant folding of unsafe get operations
  29  * @library /testlibrary /../../test/lib
  30  * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions
  31  *                   -Xbatch -XX:-TieredCompilation
  32  *                   -XX:+FoldStableValues
  33  *                   -XX:+UseUnalignedAccesses
  34  *                   java.lang.invoke.UnsafeGetConstantField
  35  * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions
  36  *                   -Xbatch -XX:-TieredCompilation
  37  *                   -XX:+FoldStableValues
  38  *                   -XX:-UseUnalignedAccesses
  39  *                   java.lang.invoke.UnsafeGetConstantField
  40  */
  41 package java.lang.invoke;
  42 
  43 import jdk.internal.org.objectweb.asm.*;
  44 import jdk.test.lib.Asserts;
  45 import jdk.test.lib.Utils;
  46 import sun.misc.Unsafe;
  47 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  48 
  49 public class UnsafeGetConstantField {
  50     static final Class<?> THIS_CLASS = UnsafeGetConstantField.class;
  51 
  52     static final Unsafe U = Utils.getUnsafe();
  53 
  54     public static void main(String[] args) {
  55         testUnsafeGetAddress();
  56         testUnsafeGetField();


 163      *   final int f = -1;
 164      *   static final long FIELD_OFFSET;
 165      *   static final T1 t = new T1();
 166      *   static {
 167      *     FIELD_OFFSET = U.objectFieldOffset(T1.class.getDeclaredField("f"));
 168      *   }
 169      *   public Object testDirect()  { return t.f; }
 170      *   public Object testUnsafe()  { return U.getInt(t, FIELD_OFFSET); }
 171      * }
 172      */
 173     static class Generator {
 174         static final String FIELD_NAME = "f";
 175         static final String UNSAFE_NAME = internalName(Unsafe.class);
 176         static final String UNSAFE_DESC = descriptor(Unsafe.class);
 177 
 178         final JavaType type;
 179         final int flags;
 180         final boolean stable;
 181         final boolean hasDefaultValue;
 182         final String nameSuffix;

 183 
 184         final String className;
 185         final String classDesc;
 186         final String fieldDesc;
 187 
 188         Generator(JavaType t, int flags, boolean stable, boolean hasDefaultValue, String suffix) {
 189             this.type = t;
 190             this.flags = flags;
 191             this.stable = stable;
 192             this.hasDefaultValue = hasDefaultValue;
 193             this.nameSuffix = suffix;
 194 

 195             fieldDesc = type.desc();
 196             className = String.format("%s$Test%s%s__f=%d__s=%b__d=%b", internalName(THIS_CLASS), type.typeName,
 197                                       suffix, flags, stable, hasDefaultValue);
 198             classDesc = String.format("L%s;", className);
 199         }
 200 
 201         byte[] generateClassFile() {
 202             ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
 203             cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, className, null, "java/lang/Object",
 204                     new String[]{ internalName(Test.class) });
 205 
 206             // Declare fields
 207             cw.visitField(ACC_FINAL | ACC_STATIC, "t", classDesc, null, null).visitEnd();
 208             cw.visitField(ACC_FINAL | ACC_STATIC, "FIELD_OFFSET", "J", null, null).visitEnd();
 209             cw.visitField(ACC_FINAL | ACC_STATIC, "U", UNSAFE_DESC, null, null).visitEnd();
 210             if (isStatic()) {
 211                 cw.visitField(ACC_FINAL | ACC_STATIC, "STATIC_BASE", "Ljava/lang/Object;", null, null).visitEnd();
 212             }
 213 
 214             FieldVisitor fv = cw.visitField(flags, FIELD_NAME, fieldDesc, null, null);


 259 
 260             {   // <clinit>
 261                 MethodVisitor mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
 262                 mv.visitCode();
 263 
 264                 // Cache Unsafe instance
 265                 mv.visitMethodInsn(INVOKESTATIC, UNSAFE_NAME, "getUnsafe", "()"+UNSAFE_DESC, false);
 266                 mv.visitFieldInsn(PUTSTATIC, className, "U", UNSAFE_DESC);
 267 
 268                 // Create test object instance
 269                 mv.visitTypeInsn(NEW, className);
 270                 mv.visitInsn(DUP);
 271                 mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V", false);
 272                 mv.visitFieldInsn(PUTSTATIC, className, "t", classDesc);
 273 
 274                 // Compute field offset
 275                 getUnsafe(mv);
 276                 getField(mv);
 277                 mv.visitMethodInsn(INVOKEVIRTUAL, UNSAFE_NAME, (isStatic() ? "staticFieldOffset" : "objectFieldOffset"),
 278                         "(Ljava/lang/reflect/Field;)J", false);




 279                 mv.visitFieldInsn(PUTSTATIC, className, "FIELD_OFFSET", "J");
 280 
 281                 // Compute base offset for static field
 282                 if (isStatic()) {
 283                     getUnsafe(mv);
 284                     getField(mv);
 285                     mv.visitMethodInsn(INVOKEVIRTUAL, UNSAFE_NAME, "staticFieldBase", "(Ljava/lang/reflect/Field;)Ljava/lang/Object;", false);
 286                     mv.visitFieldInsn(PUTSTATIC, className, "STATIC_BASE", "Ljava/lang/Object;");
 287                     initField(mv);
 288                 }
 289 
 290                 mv.visitInsn(RETURN);
 291                 mv.visitMaxs(0, 0);
 292                 mv.visitEnd();
 293             }
 294 
 295             return cw.toByteArray();
 296         }
 297 
 298         Test generate() {




  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * @test
  28  * @summary tests on constant folding of unsafe get operations
  29  * @library /testlibrary /../../test/lib
  30  * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions
  31  *                   -Xbatch -XX:-TieredCompilation -Xverify:all
  32  *                   -XX:+FoldStableValues
  33  *                   -XX:+UseUnalignedAccesses
  34  *                   java.lang.invoke.UnsafeGetConstantField
  35  * @run main/bootclasspath -XX:+UnlockDiagnosticVMOptions
  36  *                   -Xbatch -XX:-TieredCompilation -Xverify:all
  37  *                   -XX:+FoldStableValues
  38  *                   -XX:-UseUnalignedAccesses
  39  *                   java.lang.invoke.UnsafeGetConstantField
  40  */
  41 package java.lang.invoke;
  42 
  43 import jdk.internal.org.objectweb.asm.*;
  44 import jdk.test.lib.Asserts;
  45 import jdk.test.lib.Utils;
  46 import sun.misc.Unsafe;
  47 import static jdk.internal.org.objectweb.asm.Opcodes.*;
  48 
  49 public class UnsafeGetConstantField {
  50     static final Class<?> THIS_CLASS = UnsafeGetConstantField.class;
  51 
  52     static final Unsafe U = Utils.getUnsafe();
  53 
  54     public static void main(String[] args) {
  55         testUnsafeGetAddress();
  56         testUnsafeGetField();


 163      *   final int f = -1;
 164      *   static final long FIELD_OFFSET;
 165      *   static final T1 t = new T1();
 166      *   static {
 167      *     FIELD_OFFSET = U.objectFieldOffset(T1.class.getDeclaredField("f"));
 168      *   }
 169      *   public Object testDirect()  { return t.f; }
 170      *   public Object testUnsafe()  { return U.getInt(t, FIELD_OFFSET); }
 171      * }
 172      */
 173     static class Generator {
 174         static final String FIELD_NAME = "f";
 175         static final String UNSAFE_NAME = internalName(Unsafe.class);
 176         static final String UNSAFE_DESC = descriptor(Unsafe.class);
 177 
 178         final JavaType type;
 179         final int flags;
 180         final boolean stable;
 181         final boolean hasDefaultValue;
 182         final String nameSuffix;
 183         final boolean useRawOffset;
 184 
 185         final String className;
 186         final String classDesc;
 187         final String fieldDesc;
 188 
 189         Generator(JavaType t, int flags, boolean stable, boolean hasDefaultValue, String suffix) {
 190             this.type = t;
 191             this.flags = flags;
 192             this.stable = stable;
 193             this.hasDefaultValue = hasDefaultValue;
 194             this.nameSuffix = suffix;
 195 
 196             useRawOffset = suffix.equals("Unaligned");
 197             fieldDesc = type.desc();
 198             className = String.format("%s$Test%s%s__f=%d__s=%b__d=%b", internalName(THIS_CLASS), type.typeName,
 199                                       suffix, flags, stable, hasDefaultValue);
 200             classDesc = String.format("L%s;", className);
 201         }
 202 
 203         byte[] generateClassFile() {
 204             ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_MAXS | ClassWriter.COMPUTE_FRAMES);
 205             cw.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC | Opcodes.ACC_SUPER, className, null, "java/lang/Object",
 206                     new String[]{ internalName(Test.class) });
 207 
 208             // Declare fields
 209             cw.visitField(ACC_FINAL | ACC_STATIC, "t", classDesc, null, null).visitEnd();
 210             cw.visitField(ACC_FINAL | ACC_STATIC, "FIELD_OFFSET", "J", null, null).visitEnd();
 211             cw.visitField(ACC_FINAL | ACC_STATIC, "U", UNSAFE_DESC, null, null).visitEnd();
 212             if (isStatic()) {
 213                 cw.visitField(ACC_FINAL | ACC_STATIC, "STATIC_BASE", "Ljava/lang/Object;", null, null).visitEnd();
 214             }
 215 
 216             FieldVisitor fv = cw.visitField(flags, FIELD_NAME, fieldDesc, null, null);


 261 
 262             {   // <clinit>
 263                 MethodVisitor mv = cw.visitMethod(ACC_STATIC, "<clinit>", "()V", null, null);
 264                 mv.visitCode();
 265 
 266                 // Cache Unsafe instance
 267                 mv.visitMethodInsn(INVOKESTATIC, UNSAFE_NAME, "getUnsafe", "()"+UNSAFE_DESC, false);
 268                 mv.visitFieldInsn(PUTSTATIC, className, "U", UNSAFE_DESC);
 269 
 270                 // Create test object instance
 271                 mv.visitTypeInsn(NEW, className);
 272                 mv.visitInsn(DUP);
 273                 mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V", false);
 274                 mv.visitFieldInsn(PUTSTATIC, className, "t", classDesc);
 275 
 276                 // Compute field offset
 277                 getUnsafe(mv);
 278                 getField(mv);
 279                 mv.visitMethodInsn(INVOKEVIRTUAL, UNSAFE_NAME, (isStatic() ? "staticFieldOffset" : "objectFieldOffset"),
 280                         "(Ljava/lang/reflect/Field;)J", false);
 281                 if (useRawOffset) {
 282                     mv.visitLdcInsn(1);
 283                     mv.visitInsn(LSHR);
 284                 }
 285                 mv.visitFieldInsn(PUTSTATIC, className, "FIELD_OFFSET", "J");
 286 
 287                 // Compute base offset for static field
 288                 if (isStatic()) {
 289                     getUnsafe(mv);
 290                     getField(mv);
 291                     mv.visitMethodInsn(INVOKEVIRTUAL, UNSAFE_NAME, "staticFieldBase", "(Ljava/lang/reflect/Field;)Ljava/lang/Object;", false);
 292                     mv.visitFieldInsn(PUTSTATIC, className, "STATIC_BASE", "Ljava/lang/Object;");
 293                     initField(mv);
 294                 }
 295 
 296                 mv.visitInsn(RETURN);
 297                 mv.visitMaxs(0, 0);
 298                 mv.visitEnd();
 299             }
 300 
 301             return cw.toByteArray();
 302         }
 303 
 304         Test generate() {


< prev index next >