hotspot/test/compiler/unsafe/JdkInternalMiscUnsafeAccessTestInt.java
changeset 35103 d19354bcbfa6
child 36316 7a83de7aabca
equal deleted inserted replaced
35102:c5f050e1f982 35103:d19354bcbfa6
       
     1 /*
       
     2  * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  */
       
    23 
       
    24 /*
       
    25  * @test
       
    26  * @bug 8143628
       
    27  * @summary Test unsafe access for int
       
    28  * @modules java.base/jdk.internal.misc
       
    29  * @run testng/othervm -Diters=100   -Xint                   JdkInternalMiscUnsafeAccessTestInt
       
    30  * @run testng/othervm -Diters=20000 -XX:TieredStopAtLevel=1 JdkInternalMiscUnsafeAccessTestInt
       
    31  * @run testng/othervm -Diters=20000 -XX:-TieredCompilation  JdkInternalMiscUnsafeAccessTestInt
       
    32  * @run testng/othervm -Diters=20000                         JdkInternalMiscUnsafeAccessTestInt
       
    33  */
       
    34 
       
    35 import org.testng.annotations.Test;
       
    36 
       
    37 import java.lang.reflect.Field;
       
    38 
       
    39 import static org.testng.Assert.*;
       
    40 
       
    41 public class JdkInternalMiscUnsafeAccessTestInt {
       
    42     static final int ITERS = Integer.getInteger("iters", 1);
       
    43 
       
    44     static final jdk.internal.misc.Unsafe UNSAFE;
       
    45 
       
    46     static final long V_OFFSET;
       
    47 
       
    48     static final Object STATIC_V_BASE;
       
    49 
       
    50     static final long STATIC_V_OFFSET;
       
    51 
       
    52     static int ARRAY_OFFSET;
       
    53 
       
    54     static int ARRAY_SHIFT;
       
    55 
       
    56     static {
       
    57         try {
       
    58             Field f = jdk.internal.misc.Unsafe.class.getDeclaredField("theUnsafe");
       
    59             f.setAccessible(true);
       
    60             UNSAFE = (jdk.internal.misc.Unsafe) f.get(null);
       
    61         } catch (Exception e) {
       
    62             throw new RuntimeException("Unable to get Unsafe instance.", e);
       
    63         }
       
    64 
       
    65         try {
       
    66             Field staticVField = JdkInternalMiscUnsafeAccessTestInt.class.getDeclaredField("static_v");
       
    67             STATIC_V_BASE = UNSAFE.staticFieldBase(staticVField);
       
    68             STATIC_V_OFFSET = UNSAFE.staticFieldOffset(staticVField);
       
    69         } catch (Exception e) {
       
    70             throw new RuntimeException(e);
       
    71         }
       
    72 
       
    73         try {
       
    74             Field vField = JdkInternalMiscUnsafeAccessTestInt.class.getDeclaredField("v");
       
    75             V_OFFSET = UNSAFE.objectFieldOffset(vField);
       
    76         } catch (Exception e) {
       
    77             throw new RuntimeException(e);
       
    78         }
       
    79 
       
    80         ARRAY_OFFSET = UNSAFE.arrayBaseOffset(int[].class);
       
    81         int ascale = UNSAFE.arrayIndexScale(int[].class);
       
    82         ARRAY_SHIFT = 31 - Integer.numberOfLeadingZeros(ascale);
       
    83     }
       
    84 
       
    85     static int static_v;
       
    86 
       
    87     int v;
       
    88 
       
    89     @Test
       
    90     public void testFieldInstance() {
       
    91         JdkInternalMiscUnsafeAccessTestInt t = new JdkInternalMiscUnsafeAccessTestInt();
       
    92         for (int c = 0; c < ITERS; c++) {
       
    93             testAccess(t, V_OFFSET);
       
    94         }
       
    95     }
       
    96 
       
    97     @Test
       
    98     public void testFieldStatic() {
       
    99         for (int c = 0; c < ITERS; c++) {
       
   100             testAccess(STATIC_V_BASE, STATIC_V_OFFSET);
       
   101         }
       
   102     }
       
   103 
       
   104     @Test
       
   105     public void testArray() {
       
   106         int[] array = new int[10];
       
   107         for (int c = 0; c < ITERS; c++) {
       
   108             for (int i = 0; i < array.length; i++) {
       
   109                 testAccess(array, (((long) i) << ARRAY_SHIFT) + ARRAY_OFFSET);
       
   110             }
       
   111         }
       
   112     }
       
   113 
       
   114     @Test
       
   115     public void testArrayOffHeap() {
       
   116         int size = 10;
       
   117         long address = UNSAFE.allocateMemory(size << ARRAY_SHIFT);
       
   118         try {
       
   119             for (int c = 0; c < ITERS; c++) {
       
   120                 for (int i = 0; i < size; i++) {
       
   121                     testAccess(null, (((long) i) << ARRAY_SHIFT) + address);
       
   122                 }
       
   123             }
       
   124         } finally {
       
   125             UNSAFE.freeMemory(address);
       
   126         }
       
   127     }
       
   128 
       
   129     @Test
       
   130     public void testArrayOffHeapDirect() {
       
   131         int size = 10;
       
   132         long address = UNSAFE.allocateMemory(size << ARRAY_SHIFT);
       
   133         try {
       
   134             for (int c = 0; c < ITERS; c++) {
       
   135                 for (int i = 0; i < size; i++) {
       
   136                     testAccess((((long) i) << ARRAY_SHIFT) + address);
       
   137                 }
       
   138             }
       
   139         } finally {
       
   140             UNSAFE.freeMemory(address);
       
   141         }
       
   142     }
       
   143 
       
   144     static void testAccess(Object base, long offset) {
       
   145         // Plain
       
   146         {
       
   147             UNSAFE.putInt(base, offset, 1);
       
   148             int x = UNSAFE.getInt(base, offset);
       
   149             assertEquals(x, 1, "set int value");
       
   150         }
       
   151 
       
   152         // Volatile
       
   153         {
       
   154             UNSAFE.putIntVolatile(base, offset, 2);
       
   155             int x = UNSAFE.getIntVolatile(base, offset);
       
   156             assertEquals(x, 2, "putVolatile int value");
       
   157         }
       
   158 
       
   159         // Lazy
       
   160         {
       
   161             UNSAFE.putOrderedInt(base, offset, 1);
       
   162             int x = UNSAFE.getIntVolatile(base, offset);
       
   163             assertEquals(x, 1, "putRelease int value");
       
   164         }
       
   165 
       
   166         // Unaligned
       
   167         {
       
   168             UNSAFE.putIntUnaligned(base, offset, 2);
       
   169             int x = UNSAFE.getIntUnaligned(base, offset);
       
   170             assertEquals(x, 2, "putUnaligned int value");
       
   171         }
       
   172 
       
   173         {
       
   174             UNSAFE.putIntUnaligned(base, offset, 1, true);
       
   175             int x = UNSAFE.getIntUnaligned(base, offset, true);
       
   176             assertEquals(x, 1, "putUnaligned big endian int value");
       
   177         }
       
   178 
       
   179         {
       
   180             UNSAFE.putIntUnaligned(base, offset, 2, false);
       
   181             int x = UNSAFE.getIntUnaligned(base, offset, false);
       
   182             assertEquals(x, 2, "putUnaligned little endian int value");
       
   183         }
       
   184 
       
   185         UNSAFE.putInt(base, offset, 1);
       
   186 
       
   187         // Compare
       
   188         {
       
   189             boolean r = UNSAFE.compareAndSwapInt(base, offset, 1, 2);
       
   190             assertEquals(r, true, "success compareAndSwap int");
       
   191             int x = UNSAFE.getInt(base, offset);
       
   192             assertEquals(x, 2, "success compareAndSwap int value");
       
   193         }
       
   194 
       
   195         {
       
   196             boolean r = UNSAFE.compareAndSwapInt(base, offset, 1, 3);
       
   197             assertEquals(r, false, "failing compareAndSwap int");
       
   198             int x = UNSAFE.getInt(base, offset);
       
   199             assertEquals(x, 2, "failing compareAndSwap int value");
       
   200         }
       
   201 
       
   202         // Compare set and get
       
   203         {
       
   204             int o = UNSAFE.getAndSetInt(base, offset, 1);
       
   205             assertEquals(o, 2, "getAndSet int");
       
   206             int x = UNSAFE.getInt(base, offset);
       
   207             assertEquals(x, 1, "getAndSet int value");
       
   208         }
       
   209 
       
   210         UNSAFE.putInt(base, offset, 1);
       
   211 
       
   212         // get and add, add and get
       
   213         {
       
   214             int o = UNSAFE.getAndAddInt(base, offset, 2);
       
   215             assertEquals(o, 1, "getAndAdd int");
       
   216             int x = UNSAFE.getInt(base, offset);
       
   217             assertEquals(x, 1 + 2, "weakCompareAndSwapRelease int");
       
   218         }
       
   219     }
       
   220 
       
   221     static void testAccess(long address) {
       
   222         // Plain
       
   223         {
       
   224             UNSAFE.putInt(address, 1);
       
   225             int x = UNSAFE.getInt(address);
       
   226             assertEquals(x, 1, "set int value");
       
   227         }
       
   228     }
       
   229 }