参照カウント

Xtalでは参照カウント方式を採用しています。
そのためアチコチで参照カウントが上げ下げされているのですが、ちょっと問題に思っていることがあります。

今回の説明に必要な部分だけを、説明にいいように変形して抜き出したコードが次になります。

enum{
  TYPE_NULL = 0,

  //...

  TYPE_INT = 4,

  //...

  TYPE_BASE = 8,

  //...
};

struct Any{
  int_t type;
  
  union{
    Base* pvalue;
    int_t ivalue;
  };
};

struct Base{
  uint_t ref_count;
};

整数は

Any intv = {TYPE_INT, 100};

として持たれ、オブジェクトは

Any objv = {TYPE_BASE, new Base()};

として持たれるという実装になってます。

これだと、参照カウントは次のようにifで分岐をする必要が出てしまいます。

Any any = foo();

// anyに入っているのがTYPE_BASEのときだけ
if(any.type==TYPE_BASE){
  any.pvalue->ref_count++;
}

分岐は最近のCPUだと遅いので、if文無しで参照カウントする方法を考えていました。
このたび思いついたのが次の方法です。

// ((any.type>>3)&1) は、
// typeがTYPE_BASE(=8)以上ならば、1となり、
// それ未満なら0となる。
// よって、mask1は、typeがTYPE_BASE以上ならば0xffffffffとなり、
// それ未満なら0x00000000となる。
uint_t mask1 = 0-((any.type>>3)&1); 

// mask1を反転
uint_t mask2 = ~mask1;

uint_t dummy;

// typeがTYPE_BASE以上ならばany.pvalue->ref_countアドレスが、
// それ未満ならdummyローカル変数へのアドレスが入る
uint_t* address = reinterpret_cast<uint_t*>(
  (mask1 & (reinterpret_cast<uint_t>(any.pvalue) + offsetof(Base, ref_count))) |
  (mask2 & reinterpret_cast<uint_t>(&dummy))
);

// 参照カウンタをインクリメント
++*address;

うーんもっといい方法はないもんか。