package org.openjdk;

import org.openjdk.jmh.annotations.*;
import sun.misc.Unsafe;

import java.lang.reflect.Field;
import java.util.concurrent.TimeUnit;

@Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
@Fork(3)
@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class BadMDOPolicy {

    public static final Unsafe U;
    public static final long OFF;

    static {
        try {
            Field unsafeField = Unsafe.class.getDeclaredField("theUnsafe");
            unsafeField.setAccessible(true);
            U = (Unsafe) unsafeField.get(null);
        } catch (Exception e) {
            throw new AssertionError(e);
        }

        OFF = U.allocateMemory(100);
    }

    @Benchmark
    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    public void test() {
        U.putOrderedInt(null, OFF, 42);
    }

    /*
       -XX:+TieredCompilation

       Compiled with C1, because for org.openjdk.BadMDOPolicy.test()V, mdo->num_blocks = 3,
       lower than SimpleThresholdPolicy threshold. C1 intrinsic for putOrdered is not as
       efficient as the one in C2.

                                0x00007f5845444420: mov    %eax,-0x14000(%rsp)
              3.69%             0x00007f5845444427: push   %rbp
                                0x00007f5845444428: sub    $0x40,%rsp         ;*getstatic U {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - org.openjdk.BadMDOPolicy::test@0 (line 35)
              3.55%             0x00007f584544442c: movabs $0x0,%rsi          ;   {oop(NULL)}
                                0x00007f5845444436: mov    $0x2a,%edi
                                0x00007f584544443b: movabs $0x7f5798002d80,%rbx
                                0x00007f5845444445: mov    %edi,(%rsi,%rbx,1)
              3.74%             0x00007f5845444448: lock addl $0x0,-0x40(%rsp)
             71.83%   94.66%    0x00007f584544444e: add    $0x40,%rsp
                                0x00007f5845444452: pop    %rbp
                                0x00007f5845444453: test   %eax,0x14083ba7(%rip)        # 0x00007f58594c8000
                                                                              ;   {poll_return}
              3.99%             0x00007f5845444459: retq

        -XX:-TieredCompilation

        Compiled with C2, full intrinsic is in order:

             14.84%   12.78%    0x00007f58859ef500: sub    $0x18,%rsp
              0.04%    0.04%    0x00007f58859ef507: mov    %rbp,0x10(%rsp)
              0.09%    0.07%    0x00007f58859ef50c: movabs $0x7f57e4004720,%r10
             15.11%   17.17%    0x00007f58859ef516: movl   $0x2a,(%r10)       ;*invokevirtual putOrderedInt {reexecute=0 rethrow=0 return_oop=0}
                                                                              ; - org.openjdk.BadMDOPolicy::test@9 (line 35)
                       0.02%    0x00007f58859ef51d: add    $0x10,%rsp
                                0x00007f58859ef521: pop    %rbp
             37.05%   33.12%    0x00007f58859ef522: test   %eax,0xe07bad8(%rip)        # 0x00007f5893a6b000
                                                                              ;   {poll_return}
              0.05%             0x00007f58859ef528: retq

     */

}