<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      SSCLI中GC源碼分析(1) - EE與BCL之間的調用接口FCall

      首先在SSCLI2.0源代碼的\clr\src\vm\comutilnative.cpp文件中的GCInterface類的CollectGeneration方法上下個斷點,該宏方法主要實現了一個調用轉換:

      /*==============================CollectGeneration===============================
      **Action: Collects all generations <= args->generation
      **Returns: void
      **Arguments: args->generation:  The maximum generation to collect
      **Exceptions: Argument exception if args->generation is < 0 or > GetMaxGeneration();
      ==============================================================================*/
      FCIMPL1(void, GCInterface::CollectGeneration, INT32 generation)
      {
          CONTRACTL
          {
              MODE_COOPERATIVE;
              DISABLED(GC_TRIGGERS);  // can't use this in an FCALL because we're in forbid gc mode until we setup a H_M_F.
              THROWS;
              SO_TOLERANT;
          }
          CONTRACTL_END;
      
          //We've already checked this in GC.cs, so we'll just assert it here.
          _ASSERTE(generation >= -1);
      
          //We don't need to check the top end because the GC will take care of that.
          HELPER_METHOD_FRAME_BEGIN_0();
      
          GCHeap::GetGCHeap()->GarbageCollect(generation);
      
          if (g_TrapReturningThreads)
          {
              GetThread()->PulseGCMode();
          }
          HELPER_METHOD_FRAME_END();
      }
      FCIMPLEND

      這個方法提供了從BCL中調用SSCLI虛擬執行引擎內部功能的一個接口。在SSCLI實現版本中,這種調用轉換的方式叫做FCall。

      在不會被JIT的代碼中,譬如一些Helper代碼片段或者stubs中,經常會使用一些調用轉換來協調不同功能的組件。這樣在Runtime中,就不會出現是一個非常大的、包含了所有功能的Heap。

      使用這種非常有效的調用轉換,可以讓托管高級語言,譬如C#,在用戶代碼中調用Runtime中的內部功能。使用這種調用,只需要給實現的方法加上MethodImplOptions.InternalCall的屬性即可。

      而FCall會使用sscli20\clr\src\vm\ecall.cpp中的ECFunc結構體,來完成從托管方法到Runtime內部實現的C++方法的轉換:

      struct ECFunc {
          UINT_PTR            m_dwFlags;
      
      #ifndef DACCESS_COMPILE
          LPVOID              m_pImplementation;
      #else
          TADDR               m_pImplementation;
      #endif
          PTR_MethodDesc      m_pMD;               // for reverse mapping
      
          PTR_ECFunc          m_pNext;             // linked list for hash table
      
          LPCUTF8             m_wszMethodName;
          LPHARDCODEDMETASIG  m_wszMethodSig;      // Optional field. It is valid only if HasSignature() is set.
      
          bool                IsEndOfArray()  { LEAF_CONTRACT; return !!(m_dwFlags & FCFuncFlag_EndOfArray); }
          bool                HasSignature()  { LEAF_CONTRACT; return !!(m_dwFlags & FCFuncFlag_HasSignature); }
          bool                IsUnreferenced(){ LEAF_CONTRACT; return !!(m_dwFlags & FCFuncFlag_Unreferenced); }
          CorInfoIntrinsics   IntrinsicID()   { LEAF_CONTRACT; return (CorInfoIntrinsics)((INT8)(m_dwFlags >> 16)); }
          int                 DynamicID()     { LEAF_CONTRACT; return (int)              ((INT8)(m_dwFlags >> 24)); }
      
          ECFunc*             NextInArray()
          { 
              LEAF_CONTRACT; 
              
              return (ECFunc*)((BYTE*)this + 
                  (HasSignature() ? sizeof(ECFunc) : offsetof(ECFunc, m_wszMethodSig)));
          }
      };

      m_wszMethodName表示的是BCL中對應的方法。m_pImplementation表示的是Runtime中對應的方法。可以看到,在這種轉換中,不涉及到任何關于參數傳遞或者是類型檢查之類的邏輯,因為FCall調用的方法,完全是Runtime內部實現的。

      在Method.cpp文件中的MethodClassification枚舉類型中,還列出了其他SSCLI執行引擎中對Method分類的:

      // Used in MethodDesc
      enum MethodClassification
      {
          mcIL        = 0, // IL
          mcFCall     = 1, // FCall (also includes tlbimped ctor, Delegate ctor)
          mcNDirect   = 2, // N/Direct
          mcEEImpl    = 3, // special method; implementation provided by EE (like Delegate Invoke)
          mcArray     = 4, // Array ECall
          mcInstantiated = 5, // Instantiated generic methods, including descriptors
                              // for both shared and unshared code (see InstantiatedMethodDesc)
      
          mcDynamic       = 7, // for method dewsc with no metadata behind
          mcCount,
      };

      在SSCLI的對象內存布局中,由于MethodDesc結構是幾個不同的類型的聚合體,所以這里使用一個三個bit位的flag來表示MethodDesc是使用的那種類型。在MethodClassfication中,并不表示方法是JITed或者是NON-JITed。因為是否被JIT過,只有在方法第一次被執行的時候才能夠知道。同時,由于托管進程中的線程都需要修改這三個BIT位,所以這個標識被放在可以被線程同步范圍的內存地址上。

      MethodClassification這個結構會在MethodDesc中被使用到,來標識一個Method類型。同時,MethodDesc中有一個16bit的flag(MethodClassification)來表示一個MethodDesc所有的屬性。可以參考前面章節中關于MethodDesc的介紹。

      這里,還有一點需要注意的是,在調用GCHeap類中的GarbageCollect方法之前,下面的代碼會在Stack中安裝一個棧幀:

      //We don't need to check the top end because the GC will take care of that.
      HELPER_METHOD_FRAME_BEGIN_0();
      
      GCHeap::GetGCHeap()->GarbageCollect(generation);
      
      if (g_TrapReturningThreads)
      {
          GetThread()->PulseGCMode();
      }
      HELPER_METHOD_FRAME_END();

      在上面的方法中,HELPER_METHOD_FRAME_BEGIN_0()方法HELPER_METHOD_FRAME_END()成對使用,用來在GCHeap中放置HelperMethodFrame棧幀。這個棧幀的主要功能,是允許加入Jit Helper或者是標識FCall的相關信息到棧中,來方便程序對Stack的遍歷。下面是這個Frame的構造函數:

      // Lazy initialization of HelperMethodFrame.  Need to
      // call InsureInit to complete initialization
      // If this is an FCall, the second param is the entry point for the FCALL.
      // The MethodDesc will be looked up form this (lazily), and this method
      // will be used in stack reporting, if this is not an FCall pass a 0
      HelperMethodFrame(void* fCallFtnEntry, struct LazyMachState* ms, unsigned attribs = 0)
      {
          WRAPPER_CONTRACT;
           INDEBUG(memset(&m_Attribs, 0xCC, sizeof(HelperMethodFrame) - offsetof(HelperMethodFrame, m_Attribs));)
           m_Attribs = attribs;
           LazyInit(fCallFtnEntry, ms);
      }

      順便提一下,這個地方使用了Lazy initialization技術,Lazy initialization是一種延遲初始化對象的策略,譬如說計算一個值,或者是一個Process的計算代價比較昂貴而且也不是經常使用的情況下,就在第一次使用的時候初始化。實現的方式,主要是用一個Flag來標識這個過程是否已經開始。這也算是一種設計模式。可以在Wikipedia找到關于這個技術的比較詳細的說明:

      http://en.wikipedia.org/wiki/Lazy_initialization

      最后,在comutilnative.cpp文件中,還是實現了許多其他的BCL和Runtime之間調用的類和方法,主要包括一下類:

      image

      posted on 2009-09-11 11:13  lbq1221119  閱讀(2600)  評論(20)    收藏  舉報

      導航

      主站蜘蛛池模板: 国产精品视频一区二区噜| 国产午夜福利片在线观看| 中文字幕一区二区人妻| 亚洲精品中文字幕码专区| 亚洲爆乳精品无码一区二区| 激情综合五月丁香亚洲| 国产不卡av一区二区| 国产精品黄色片| 日本精品中文字幕在线不卡| 麻豆蜜桃伦理一区二区三区| 久久波多野结衣av| 国内熟女中文字幕第一页| 亚洲精品日韩在线丰满| 亚洲人妻中文字幕一区| 国产成人一区二区三区免费| 午夜性色一区二区三区不卡视频| 久久这里有精品国产电影网| 亚洲欧美综合一区二区三区| 92国产精品午夜福利| 久久精品国产蜜臀av| 亚洲中文久久久久久精品国产| 亚洲色av天天天天天天| 国产精品自拍三级在线观看| 久久久无码人妻精品无码| 亚洲天堂成年人在线视频| 国产中文字幕精品免费| 国产精品午夜福利资源| 伊人久久大香线蕉av色婷婷色| 国产伦精品一区二区三区妓女| 精品国产一区二区在线视| 在线亚洲高清揄拍自拍一品区| 国产成人精品一区二区三| 欧美野外伦姧在线观看| 福利一区二区视频在线| 久久大香萑太香蕉av黄软件| 午夜福利92国语| 国产三级精品三级在线观看| 国产成人久久777777| 美乳丰满人妻无码视频| 国产美女裸身网站免费观看视频| 伊人色综合一区二区三区影院视频|