2016-12-27 19 views
8

Предположим, у меня есть этот код (это на самом деле не имеет значения, я думаю, но только в том случае, здесь есть):java9 присущий метод неясными

public class AtomicJDK9 { 

    static AtomicInteger ai = new AtomicInteger(0); 

    public static void main(String[] args) { 
     int sum = 0; 
     for (int i = 0; i < 30_000; ++i) { 
      sum += atomicIncrement(); 
     } 
     System.out.println(sum); 
    } 

    public static int atomicIncrement() { 
     ai.getAndAdd(12); 
     return ai.get(); 
    } 
} 

А вот как я ссылающегося на него (с помощью java9):

java -XX:+UnlockDiagnosticVMOptions 
     -XX:-TieredCompilation 
     -XX:+PrintIntrinsics 
     AtomicJDK9 

Что я пытаюсь выяснить, какие методы были заменены внутренним кодом. Первый один, который ударил (внутри Unsafe):

 @HotSpotIntrinsicCandidate 
     public final int getAndAddInt(Object o, long offset, int delta) { 
     int v; 
     do { 
      v = getIntVolatile(o, offset); 
     } while (!weakCompareAndSwapIntVolatile(o, offset, v, v + delta)); 
     return v; 
     } 

И этот метод действительно присутствует на выходе указанного выше вызова:

@ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic) 

Но весь выход странно (для меня это есть):

@ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic) 
@ 3 jdk.internal.misc.Unsafe::getIntVolatile (0 bytes) (intrinsic) 
@ 18 jdk.internal.misc.Unsafe::weakCompareAndSwapIntVolatile (11 bytes) (intrinsic) 
@ 7 jdk.internal.misc.Unsafe::compareAndSwapInt (0 bytes) (intrinsic) 
@ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic) 

Почему getAndAddInt присутствует дважды на выходе?

Также, если getAndAddInt действительно заменен внутренним вызовом, то почему существует необходимость в замене всех других встроенных методов в стек вызовов l они больше не будут использоваться. Я предполагаю, что это так же просто, как стек вызовов методов проходит по низу.

+1

Возможно, добавление '+ PrintCompilation' (или что-то новое унифицированное эквивалент протоколирования) и пролить свет на контекст. – the8472

ответ

7

Для иллюстрации логики компилятора я запускал JVM со следующими аргументами.

-XX:-TieredCompilation -XX:CICompilerCount=1 
    -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -XX:+PrintInlining 

И вот что он печатает.

337 29 java.util.concurrent.atomic.AtomicInteger::getAndAdd (12 bytes) 
       @ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic) 
337 30 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) 
       @ 3 jdk.internal.misc.Unsafe::getIntVolatile (0 bytes) (intrinsic) 
       @ 18 jdk.internal.misc.Unsafe::weakCompareAndSwapIntVolatile (11 bytes) (intrinsic) 
338 32 jdk.internal.misc.Unsafe::weakCompareAndSwapIntVolatile (11 bytes) 
       @ 7 jdk.internal.misc.Unsafe::compareAndSwapInt (0 bytes) (intrinsic) 
339 33 AtomicJDK9::atomicIncrement (16 bytes) 
       @ 5 java.util.concurrent.atomic.AtomicInteger::getAndAdd (12 bytes) inline (hot) 
       @ 8 jdk.internal.misc.Unsafe::getAndAddInt (27 bytes) (intrinsic) 
       @ 12 java.util.concurrent.atomic.AtomicInteger::get (5 bytes) accessor 
  • методы являются только для встроенных функций компилятора, но не для переводчика.
  • Каждый метод запускается в интерпретаторе до тех пор, пока он не будет considered hot.
  • AtomicInteger.getAndAdd называется не только вашим кодом, но и распространенным кодом JDK.
  • То есть AtomicInteger.getAndAdd достигает порога срабатывания чуть раньше, чем ваш AtomicJDK9.atomicIncrement. Затем getAndAdd отправляется в очередь компиляции, откуда и начинается первая внутренняя распечатка.
  • HotSpot JVM компилирует методы в фоновом режиме. Пока метод компилируется, выполнение продолжается в интерпретаторе.
  • В то время как AtomicInteger.getAndAdd интерпретируется, методы Unsafe.getAndAddInt и Unsafe.weakCompareAndSwapIntVolatile также достигают порога вызова и начинают компиляцию. Следующие 3 экземпляра печатаются при компиляции этих методов Unsafe.
  • Наконец, AtomicJDK9.atomicIncrement также достигает вызова threashold и начинает сбор. Последняя внутренняя распечатка соответствует вашему методу.

 Смежные вопросы

  • Нет связанных вопросов^_^