2012-05-02 8 views
16

क्या आज के जेवीएम में जावा वर्चुअल मशीन के NOP ऑपोड का कोई व्यावहारिक उपयोग है? यदि हां, तो कुछ परिदृश्य क्या हैं जिनमें NOP एस बाइटकोड में उत्पन्न होगा?जेवीएम बाइटकोड में एनओपी क्या है?

मुझे जावा कोड का एक उदाहरण देखने में भी दिलचस्पी होगी जो NOP एस के साथ बाइटकोड में संकलित है।


अद्यतन

BCEL के MethodGen वर्ग कहते हैं,

जबकि कोड जनरेट यह एनओपी संचालन सम्मिलित करने के लिए आवश्यक हो सकता है।

मैं अनुमान लगा रहा हूँ अन्य Bytecode पीढ़ी पुस्तकालयों, एक ही नाव में हैं के रूप में स्वीकार जवाब में बताया गया था।

+0

आमतौर पर इसका उपयोग डीबग कोड में किया जाता है ताकि किसी ऐसे चीज़ पर ब्रेकपॉइंट्स की अनुमति दी जा सके जो बाइटकोड में अनुवाद न करे, जैसे '{'। – vcsjones

+0

क्या आपका मतलब है कि यह जावा फ़ाइल को 'javac -g' के साथ संकलित करते समय बाइटकोड में दिखाई देगा? – jbranchaud

+0

मुझे विश्वास नहीं है कि 'जावैक' ऐसा करेगा। लेकिन अन्य कंपाइलर और डिबगर्स उस कार्यक्षमता का उपयोग कर सकते हैं। – vcsjones

उत्तर

12

कुछ NOP बाईटकोड उपयोग के मामलों class फ़ाइल परिवर्तनों, अनुकूलन और टूल के माध्यम से स्थिर विश्लेषण के लिए कर रहे हैं इस तरह के Apache BCEL, ASM, FindBugs, PMD, आदि विश्लेषण और अनुकूलन प्रयोजनों के लिए NOP के कुछ ऐसे उपयोग पर अपाचे BCEL manual छूता है के रूप में ।

एक जेवीएम NOP जेईटी अनुकूलन के लिए बाइटकोड का उपयोग कर सकता है ताकि यह सुनिश्चित किया जा सके कि सिंक्रनाइज़ेशन सुरक्षित बिंदुओं पर कोड ब्लॉक false sharing से बचने के लिए ठीक से गठबंधन किए गए हैं।

जेडीके javac कंपाइलर का उपयोग करके संकलित कुछ नमूना कोड के लिए NOP बाइटकोड्स, यह एक दिलचस्प चुनौती है। हालांकि, मुझे संदेह है कि संकलक class फ़ाइल NOP बाइटकोड the bytecode instruction stream is only single-byte aligned से उत्पन्न करेगा। मैं इस तरह के एक उदाहरण को देखने के लिए उत्सुक होगा, लेकिन मैं किसी के बारे में नहीं सोच सकता।

1

प्रोसेसर पाइपलाइन अनुकूलन के लिए अक्सर कोई ऑप्स नहीं जोड़ा जाता है। मुझे यकीन नहीं है कि जावा वर्तमान में किस हद तक उनका उपयोग करता है।

Wikipedia से

:

एक एनओपी सबसे अधिक समय प्रयोजनों के लिए प्रयोग किया जाता है, खतरों को रोकने के लिए, स्मृति संरेखण के लिए मजबूर करने के लिए एक शाखा देरी स्लॉट पर कब्जा करने के लिए, या एक जगह-धारक के रूप में बदला जाएगा कार्यक्रम में विकास (या रिफैक्टरिंग के दौरान हटाए गए निर्देशों को प्रतिस्थापित करने के लिए समस्याग्रस्त या समय लेने वाली) में सक्रिय निर्देशों के बाद। कुछ मामलों में, एनओपी में मामूली दुष्प्रभाव हो सकते हैं; उदाहरण के लिए, मोटोरोला 68000 प्रोसेसर की श्रृंखला पर, एनओपी ओपोड पाइपलाइन के सिंक्रनाइज़ेशन का कारण बनता है।

+6

यह एक भौतिक मशीन ऑपोड में समझ में आता है, लेकिन * वर्चुअल * मशीन ऑपोड के लिए ऐसी चीज़ का उपयोग क्या होगा? –

+0

मैं उत्तर की सराहना करता हूं, लेकिन यह सवाल विशेष रूप से जेवीएम के बारे में है। – jbranchaud

2

यहाँ कुछ कोड से एक उदाहरण मैं पर काम कर रहा है वह जगह है जहाँ nop निर्देश (के रूप में ग्रहण के लिए Bytecode विजुअलाइज़र द्वारा देखी) जहां बाइट कोड में रखा

मूल कोड

public abstract class Wrapper<T extends Wrapper<T,E>,E> 
    implements Supplier<Optional<E>>, Consumer<E> 
{ 
    /** The wrapped object. */ 
    protected Optional<E> inner; 

    /* 
    * (non-Javadoc) 
    * @see java.lang.Object#equals(java.lang.Object) 
    */ 
    /** 
    * A basic equals method that will compare the wrapped object to 
    * whatever you throw at it, whether it is wrapped or not. 
    */ 
    @Override 
    public boolean equals(final Object that) 
    { 
    return this==that 
     ||LambdaUtils.castAndMap(that,Wrapper.class,afterCast 
      -> inner.equals(afterCast.inner)) 
     .orElseGet(() 
      -> LambdaUtils.castAndMap(that,Optional.class,afterCast 
       -> inner.equals(afterCast)) 
      .orElseGet(() 
       -> Optional.ofNullable(that).map(thatobj 
        -> that.equals(inner.get())) 
       .orElseGet(() 
        -> false))); 
    } 
} 

बराबर (ऑब्जेक्ट) विधि के लिए अनुवादित बाइट कोड

public boolean equals(java.lang.Object arg0) { 
    /* L27 */ 
    0 aload_0;    /* this */ 
    1 aload_1;    /* that */ 
    2 if_acmpeq 36; 
    /* L28 */ 
    5 aload_1;    /* that */ 
    6 ldc 1; 
    8 aload_0;    /* this */ 
    9 invokedynamic 29;  /* java.util.function.Function apply(ext.cat.wcutils.collections.Wrapper arg0) */ 
    12 nop; 
    13 nop; 
    14 invokestatic 30;  /* java.util.Optional ext.cat.wcutils.util.LambdaUtils.castAndMap(java.lang.Object arg0, java.lang.Class arg1, java.util.function.Function arg2) */ 
    /* L30 */ 
    17 aload_0;    /* this */ 
    18 aload_1;    /* that */ 
    19 invokedynamic 39;  /* java.util.function.Supplier get(ext.cat.wcutils.collections.Wrapper arg0, java.lang.Object arg1) */ 
    22 nop; 
    23 nop; 
    24 invokevirtual 40;  /* java.lang.Object orElseGet(java.util.function.Supplier arg0) */ 
    27 checkcast 46;   /* java.lang.Boolean */ 
    30 invokevirtual 48;  /* boolean booleanValue() */ 
    /* L37 */ 
    33 ifne 5; 
    /* L27 */ 
    36 iconst_0; 
    37 ireturn; 
    38 iconst_1; 
    39 ireturn; 
} 

मुझे यकीन नहीं है कि उन्हें क्यों डाला जाएगा। मुझे उम्मीद है कि वे प्रदर्शन को प्रतिकूल रूप से प्रभावित नहीं करेंगे।

+3

कोई 'एनओपी' नहीं है, यह आपके द्वारा उपयोग किए गए बाइटकोड विजुअलाइज़र में बस एक बग है। 'Invokedynamic 'निर्देश में पांच बाइट होते हैं, अंतिम दो शून्य प्रति विनिर्देशन होते हैं। जाहिर है, बाइटकोड विजुअलाइज़र यह नहीं जानता है और 'invokedynamic 'निर्देश को केवल तीन बाइट्स रखने के लिए मानता है और दो शून्य बाइट्स को' nop' निर्देशों के रूप में गलत व्याख्या करता है। [जेवीएम स्पेक इनवोकैडीनामिक] देखें (https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.invokedynamic)। – Holger

+0

मुझे लगता है कि समझ में आता है। मैं ग्रहण नियॉन के लिए बाइटकोड विजुअलाइज़र को अद्यतन के लिए इंतजार कर रहा हूं। शायद हमें डेवलपर को बताना चाहिए। – HesNotTheStig

संबंधित मुद्दे