2016-12-27 11 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 

मैं क्या पता लगाने की कोशिश कर रहा हूं कि आंतरिक कोड द्वारा किन तरीकों को प्रतिस्थापित किया गया है। पहले एक है कि (असुरक्षित अंदर) मारा जाता है:

 @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 वर्तमान में दो बार उत्पादन में है?

अगर प्राप्त करें और वास्तव में एक आंतरिक कॉल द्वारा प्रतिस्थापित किया गया है, तो कॉल स्टैक एल के नीचे अन्य सभी आंतरिक तरीकों को को बदलने की आवश्यकता क्यों है, अब उनका उपयोग नहीं किया जाएगा। मुझे लगता है कि यह आसान है क्योंकि विधि कॉल के ढेर को नीचे से घुमाया जाता है।

+1

शायद '+ प्रिंटकंपिलेशन '(या जो भी नया एकीकृत एकीकृत समीकरण है) जोड़ रहा है और संदर्भ पर प्रकाश डाला गया है। – 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 
  • तरीके केवल संकलक के लिए intrinsics हैं, लेकिन दुभाषिया के लिए नहीं।
  • प्रत्येक विधि दुभाषिया में तब तक शुरू होती है जब तक यह considered hot न हो।
  • AtomicInteger.getAndAdd न केवल आपके कोड से, बल्कि सामान्य जेडीके कोड से भी कहा जाता है।
  • वह है, AtomicInteger.getAndAdd आपके AtomicJDK9.atomicIncrement से थोड़ा पहले आवंटन थ्रेसहोल्ड तक पहुंचता है। फिर getAndAdd संकलन कतार में सबमिट किया गया है, और यही वह जगह है जहां पहला आंतरिक प्रिंटआउट आता है।
  • हॉटस्पॉट जेवीएम पृष्ठभूमि में विधियों को संकलित करता है। जबकि एक विधि संकलित की जा रही है, निष्पादन दुभाषिया में जारी है।
  • जबकि AtomicInteger.getAndAdd का अर्थ है, Unsafe.getAndAddInt और Unsafe.weakCompareAndSwapIntVolatile विधियां भी आमंत्रण दहलीज तक पहुंचती हैं और संकलन शुरू करती हैं। इन Unsafe विधियों को संकलित करते समय अगले 3 इंट्रिनिक्स मुद्रित किए जाते हैं।
  • अंत में, AtomicJDK9.atomicIncrement भी आमंत्रण threashold तक पहुंचता है और संकलन शुरू करता है। अंतिम आंतरिक प्रिंटआउट आपकी विधि से मेल खाता है।
संबंधित मुद्दे