これまでxnew で生成されたオブジェクトは16byteアライメントを持っていてもいなくても、関係なくmallocで取得したメモリに配置していました。

普通のnewも同様に、関係なく配置します。

なのでアライメントの問題はどうしようもないだろう、と思っていたのですが、

ゲームにおいては、16byteアライメントを持つことはよくありうる、といったこともあり、対応することにしました。

どうやって対応するか、この一週間悩んでやっと実装できました。

xnewで生成されたオブジェクトは、16byteアライメントを持つメンバがある場合16byteアライメントを保障します。

持たないオブジェクトに関してはこれまでどおりです。

#include <xmmintrin.h> struct Vec128{ __m128 a; }; struct Spr{ Vec128 v; }; XTAL_BIND(Spr){ it->def_var( "v" , &Spr::v); } void test(){ Spr* p = new Spr(); _mm_add_ps(p->v.a, p->v.a); SmartPtr<Spr> s = xnew<Spr>(); _mm_add_ps(s->v.a, s->v.a); }

-



今回の実装の余波

AllocatorLibは次のようなインターフェイスと変更となりました。

class AllocatorLib{ public : virtual ~AllocatorLib(){} virtual void * malloc(std:: size_t size); virtual void free( void * p, std:: size_t size); virtual void * malloc_align(std:: size_t size, std:: size_t alignment); virtual void free_align( void * p, std:: size_t size, std:: size_t alignment); virtual void out_of_memory(){} };

malloc_align, free_alignが増えています。

ただし、これらは実装しなくてもかまいません。デフォルトの実装でmallocを使って整列するメモリを返すようになっています。

memalignなど、もっと効率のよい関数がある場合にオーバーライドしてください。

-

また、RefCountingBase, Baseという基底クラスも修正しました。

仮想関数はすべてon_という接頭をつけた名前にリネームし、非仮想関数としました。

たとえばvirtual void rawmember();はvoid on_rawmember();となります。

デストラクタも非仮想とし、仮想関数を排除しました。

ただし、特別な仕組みを導入したため、それらは仮想関数と同様にオーバーライドできます。