2

ライブラリの実装を理解しようとしていますが、一部のメソッドが動的にリンクされている方法に困惑しています。派生クラスのオブジェクトを使用する場合のディスパッチ メカニズムは認識していますが、オブジェクトがないと、それがどのように機能するのかわかりません。私が理解しようとしているライブラリは、gcc のlibitmです。

ヘッダー ファイルlibitm.hは、すべての ABI メソッドをクラスや構造体のないトップレベル メソッドとして宣言します。そして、それらのほとんどについて、私は独自の定義を見つけたので、それらについて質問する必要はなく、ここでは省略します. しかし、次の抜粋は 70 個のメソッドの宣言を示しており、その定義に困惑しています。

    typedef uint8_t  _ITM_TYPE_U1;
    typedef uint16_t _ITM_TYPE_U2;
    typedef uint32_t _ITM_TYPE_U4;
    typedef uint64_t _ITM_TYPE_U8;
    typedef float    _ITM_TYPE_F;
    typedef double   _ITM_TYPE_D;
    typedef long double _ITM_TYPE_E;
    typedef float _Complex _ITM_TYPE_CF;
    typedef double _Complex _ITM_TYPE_CD;
    typedef long double _Complex _ITM_TYPE_CE;

    #define ITM_BARRIERS(T) \
      extern _ITM_TYPE_##T _ITM_R##T(const _ITM_TYPE_##T *) ITM_REGPARM;    \
      extern _ITM_TYPE_##T _ITM_RaR##T(const _ITM_TYPE_##T *) ITM_REGPARM;  \
      extern _ITM_TYPE_##T _ITM_RaW##T(const _ITM_TYPE_##T *) ITM_REGPARM;  \
      extern _ITM_TYPE_##T _ITM_RfW##T(const _ITM_TYPE_##T *) ITM_REGPARM;  \
      extern void _ITM_W##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) ITM_REGPARM;   \
      extern void _ITM_WaR##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) ITM_REGPARM; \
      extern void _ITM_WaW##T (_ITM_TYPE_##T *, _ITM_TYPE_##T) ITM_REGPARM;

    ITM_BARRIERS(U1)
    ITM_BARRIERS(U2)
    ITM_BARRIERS(U4)
    ITM_BARRIERS(U8)
    ITM_BARRIERS(F)
    ITM_BARRIERS(D)
    ITM_BARRIERS(E)
    ITM_BARRIERS(CF)
    ITM_BARRIERS(CD)
    ITM_BARRIERS(CE)

ファイルdispatch.hでは、構造体 abi_dispatch が宣言されています。これは、TM アルゴリズムの特定のディスパッチのベースとして使用されます。この構造体では、上記の 70 個のメソッドの宣言が純粋な仮想メソッドとして作成されます。次の抜粋は、メソッドと構造体のマクロ定義を示しています。

#define ITM_READ_M(T, LSMOD, M, M2)                                         \
  M _ITM_TYPE_##T ITM_REGPARM ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr) \
  {                                                                         \
    return load(ptr, abi_dispatch::LSMOD);                                  \
  }

#define ITM_READ_M_PV(T, LSMOD, M, M2)                                      \
  M _ITM_TYPE_##T ITM_REGPARM ITM_##LSMOD##T##M2 (const _ITM_TYPE_##T *ptr) \
  = 0;

#define ITM_WRITE_M(T, LSMOD, M, M2)                         \
  M void ITM_REGPARM ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr, \
                     _ITM_TYPE_##T val)  \
  {                                                          \
    store(ptr, val, abi_dispatch::LSMOD);                    \
  }

#define ITM_WRITE_M_PV(T, LSMOD, M, M2)                      \
  M void ITM_REGPARM ITM_##LSMOD##T##M2 (_ITM_TYPE_##T *ptr, \
                     _ITM_TYPE_##T val)  \
  = 0;

#define CREATE_DISPATCH_METHODS_T(T, M, M2) \
  ITM_READ_M(T, R, M, M2)                \
  ITM_READ_M(T, RaR, M, M2)              \
  ITM_READ_M(T, RaW, M, M2)              \
  ITM_READ_M(T, RfW, M, M2)              \
  ITM_WRITE_M(T, W, M, M2)               \
  ITM_WRITE_M(T, WaR, M, M2)             \
  ITM_WRITE_M(T, WaW, M, M2)
#define CREATE_DISPATCH_METHODS_T_PV(T, M, M2) \
  ITM_READ_M_PV(T, R, M, M2)                \
  ITM_READ_M_PV(T, RaR, M, M2)              \
  ITM_READ_M_PV(T, RaW, M, M2)              \
  ITM_READ_M_PV(T, RfW, M, M2)              \
  ITM_WRITE_M_PV(T, W, M, M2)               \
  ITM_WRITE_M_PV(T, WaR, M, M2)             \
  ITM_WRITE_M_PV(T, WaW, M, M2)

#define CREATE_DISPATCH_METHODS(M, M2)  \
  CREATE_DISPATCH_METHODS_T (U1, M, M2) \
  CREATE_DISPATCH_METHODS_T (U2, M, M2) \
  CREATE_DISPATCH_METHODS_T (U4, M, M2) \
  CREATE_DISPATCH_METHODS_T (U8, M, M2) \
  CREATE_DISPATCH_METHODS_T (F, M, M2)  \
  CREATE_DISPATCH_METHODS_T (D, M, M2)  \
  CREATE_DISPATCH_METHODS_T (E, M, M2)  \
  CREATE_DISPATCH_METHODS_T (CF, M, M2) \
  CREATE_DISPATCH_METHODS_T (CD, M, M2) \
  CREATE_DISPATCH_METHODS_T (CE, M, M2)
#define CREATE_DISPATCH_METHODS_PV(M, M2)  \
  CREATE_DISPATCH_METHODS_T_PV (U1, M, M2) \
  CREATE_DISPATCH_METHODS_T_PV (U2, M, M2) \
  CREATE_DISPATCH_METHODS_T_PV (U4, M, M2) \
  CREATE_DISPATCH_METHODS_T_PV (U8, M, M2) \
  CREATE_DISPATCH_METHODS_T_PV (F, M, M2)  \
  CREATE_DISPATCH_METHODS_T_PV (D, M, M2)  \
  CREATE_DISPATCH_METHODS_T_PV (E, M, M2)  \
  CREATE_DISPATCH_METHODS_T_PV (CF, M, M2) \
  CREATE_DISPATCH_METHODS_T_PV (CD, M, M2) \
  CREATE_DISPATCH_METHODS_T_PV (CE, M, M2)

struct abi_dispatch
{
public:
  enum ls_modifier { NONTXNAL, R, RaR, RaW, RfW, W, WaR, WaW };

public:
  CREATE_DISPATCH_METHODS_PV(virtual, )
}

abi_dispatch の派生構造体は、たとえばmethod-mlまたはmethod-gl にあります。CREATE_DISPATCH_METHODS(virtual, ) と上記のマクロを使用して、70 の読み取り/書き込みメソッドを生成し、それらをテンプレート関数の読み込み/保存にマップします。

私の大きな疑問は次のとおりです。ランタイム システムは、ライブラリ関数の 1 つが呼び出されたときに、どのメソッド定義 (method-gl または method-ml のもの) を使用する必要があるかをどのように認識しますか? 読み取り/書き込みメソッドの定義では、言及されている abi_dispatch オブジェクトはありません。スレッド ローカル ストレージに abi-dispatch オブジェクトが存在しますが、これがどのように適合するかはわかりません。

助けてくれてありがとう。

4

1 に答える 1