mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
265 lines
6 KiB
D
265 lines
6 KiB
D
|
|
module traits_getPointerBitmap;
|
|
|
|
import core.stdc.stdio;
|
|
|
|
// version = RTInfo;
|
|
// debug = LOG;
|
|
|
|
version(RTInfo)
|
|
import gc.rtinfo;
|
|
else
|
|
enum bool RTInfoMark__Monitor = false; // is __monitor GC allocated?
|
|
|
|
|
|
enum bytesPerPtr = (size_t.sizeof);
|
|
enum bytesPerBitmapWord = bytesPerPtr * bytesPerPtr * 8;
|
|
|
|
template allocatedSize(T)
|
|
{
|
|
static if (is (T == class))
|
|
enum allocatedSize = __traits(classInstanceSize, T);
|
|
else
|
|
enum allocatedSize = T.sizeof;
|
|
}
|
|
|
|
bool testBit(const(size_t)* p, size_t biti)
|
|
{
|
|
enum BITS_SHIFT = (size_t.sizeof == 8 ? 6 : 5);
|
|
enum BITS_MASK = (bytesPerPtr - 1);
|
|
|
|
return (p[biti >> BITS_SHIFT] & (1 << (biti & BITS_MASK))) != 0;
|
|
}
|
|
|
|
void __testType(T)(size_t[] expected)
|
|
{
|
|
// check compile time info
|
|
enum bits = (T.sizeof + bytesPerPtr - 1) / bytesPerPtr;
|
|
enum words = (T.sizeof + bytesPerBitmapWord - 1) / bytesPerBitmapWord;
|
|
version(RTInfo)
|
|
enum info = RTInfoImpl2!(Unqual!T); // we want the array, not the pointer
|
|
else
|
|
enum info = __traits(getPointerBitmap,T); // we want the array, not the pointer
|
|
|
|
debug(LOG) writef("%-20s:", T.stringof);
|
|
debug(LOG) writef(" CT:%s", info);
|
|
debug(LOG) writef(" EXP:%d %s", allocatedSize!T, expected);
|
|
assert(info[0] == allocatedSize!T);
|
|
assert(info[1..$] == expected);
|
|
assert(words == expected.length);
|
|
|
|
debug(LOG) writeln();
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
struct S(T, aliasTo = void)
|
|
{
|
|
static if(!is(aliasTo == void))
|
|
{
|
|
aliasTo a;
|
|
alias a this;
|
|
}
|
|
|
|
size_t x;
|
|
T t = void;
|
|
void* p;
|
|
|
|
}
|
|
|
|
template tOff(T)
|
|
{
|
|
enum tOff = T.t.offsetof / bytesPerPtr;
|
|
}
|
|
|
|
template pOff(T)
|
|
{
|
|
enum pOff = T.p.offsetof / bytesPerPtr;
|
|
}
|
|
|
|
class C(T, aliasTo = void)
|
|
{
|
|
static if(!is(aliasTo == void))
|
|
{
|
|
aliasTo a;
|
|
alias a this;
|
|
}
|
|
|
|
size_t x;
|
|
T t = void;
|
|
void* p;
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
|
|
void _testType(T)(size_t[] expected)
|
|
{
|
|
__testType!(T)(expected);
|
|
__testType!(const(T))(expected);
|
|
__testType!(immutable(T))(expected);
|
|
version(RTInfo) {} else // Unqual does not work with shared(T[N])
|
|
__testType!(shared(T))(expected);
|
|
}
|
|
|
|
void testType(T)(size_t[] expected)
|
|
{
|
|
_testType!(T)(expected);
|
|
|
|
// generate bit pattern for S!T
|
|
assert(expected.length == 1);
|
|
size_t[] sexp;
|
|
|
|
sexp ~= (expected[0] << tOff!(S!T)) | (1 << pOff!((S!T)));
|
|
_testType!(S!T)(sexp);
|
|
|
|
// prepend Object
|
|
sexp[0] = (expected[0] << tOff!(S!(T, Object))) | (1 << pOff!(S!(T, Object))) | 1;
|
|
_testType!(S!(T, Object))(sexp);
|
|
|
|
// prepend string
|
|
sexp[0] = (expected[0] << tOff!(S!(T, string))) | (1 << pOff!(S!(T, string))) | 2; // arr ptr
|
|
_testType!(S!(T, string))(sexp);
|
|
|
|
// generate bit pattern for C!T
|
|
C!T ct = null;
|
|
size_t mutexBit = (RTInfoMark__Monitor ? 2 : 0);
|
|
size_t ctpOff = ct.p.offsetof / bytesPerPtr;
|
|
size_t cttOff = ct.t.offsetof / bytesPerPtr;
|
|
sexp[0] = (expected[0] << cttOff) | (1 << ctpOff) | mutexBit;
|
|
_testType!(C!(T))(sexp);
|
|
|
|
C!(T, string) cts = null;
|
|
size_t ctspOff = cts.p.offsetof / bytesPerPtr;
|
|
size_t ctstOff = cts.t.offsetof / bytesPerPtr;
|
|
// generate bit pattern for C!T
|
|
sexp[0] = (expected[0] << ctstOff) | (1 << ctspOff) | mutexBit | 0b1000; // arr ptr
|
|
_testType!(C!(T, string))(sexp);
|
|
}
|
|
|
|
///////////////////////////////////////
|
|
alias void[2*size_t.sizeof] void2;
|
|
alias size_t[3] int3;
|
|
alias size_t*[3] pint3;
|
|
alias string[3] sint3;
|
|
alias string[3][2] sint3_2;
|
|
alias int delegate() dg;
|
|
alias int function() fn;
|
|
alias typeof(null) NullType;
|
|
|
|
// span multiple bitmap elements
|
|
struct Large
|
|
{
|
|
size_t[30] data1;
|
|
void* p1;
|
|
size_t[1] val1;
|
|
|
|
size_t[28] data2;
|
|
void* p2;
|
|
size_t[3] val2;
|
|
|
|
size_t[16] data3;
|
|
void* p3;
|
|
size_t[15] val3;
|
|
}
|
|
|
|
class N
|
|
{
|
|
struct Nested
|
|
{
|
|
// no outer for structs
|
|
size_t x;
|
|
void* p1;
|
|
Large* s;
|
|
|
|
void foo() {} // need member fnction to not be POD
|
|
}
|
|
class CNested
|
|
{
|
|
// implicit vtptr,monitor
|
|
size_t x;
|
|
void* p1;
|
|
size_t y;
|
|
// implicit outer
|
|
}
|
|
class CNestedDerived : CNested
|
|
{
|
|
size_t[3] z;
|
|
void* p;
|
|
}
|
|
}
|
|
|
|
union U
|
|
{
|
|
size_t[4] data;
|
|
Large*[] arr; // { length, ptr }
|
|
|
|
struct
|
|
{
|
|
size_t d1;
|
|
size_t d2;
|
|
size_t d3;
|
|
void* p;
|
|
}
|
|
}
|
|
|
|
void testRTInfo()
|
|
{
|
|
testType!(bool) ([ 0b0 ]);
|
|
testType!(ubyte) ([ 0b0 ]);
|
|
testType!(short) ([ 0b0 ]);
|
|
testType!(int) ([ 0b0 ]);
|
|
testType!(long) ([ 0b00 ]);
|
|
testType!(double) ([ 0b00 ]);
|
|
testType!(dg) ([ 0b01 ]);
|
|
testType!(fn) ([ 0b0 ]);
|
|
testType!(S!fn) ([ 0b100 ]);
|
|
testType!(NullType) ([ 0b0 ]);
|
|
static if (__traits(compiles, __vector(float[4])))
|
|
testType!(__vector(float[4])) ([ 0b00 ]);
|
|
|
|
testType!(Object[int]) ([ 0b1 ]);
|
|
testType!(Object[]) ([ 0b10 ]);
|
|
testType!(string) ([ 0b10 ]);
|
|
|
|
testType!(int3) ([ 0b000 ]);
|
|
testType!(pint3) ([ 0b111 ]);
|
|
testType!(sint3) ([ 0b101010 ]);
|
|
testType!(sint3_2) ([ 0b101010101010 ]);
|
|
testType!(void2) ([ 0b11 ]);
|
|
testType!(U) ([ 0b1010 ]);
|
|
|
|
version(D_LP64)
|
|
_testType!(Large) ([ 0x1000_0000__4000_0000, 0x0001_0000 ]);
|
|
else
|
|
_testType!(Large) ([ 0x4000_0000, 0x1000_0000, 0x0001_0000 ]);
|
|
|
|
_testType!(N.CNested) ([ 0b101000 ]);
|
|
_testType!(N.CNestedDerived) ([ 0b1000101000 ]);
|
|
|
|
testType!(N.Nested) ([ 0b110 ]);
|
|
|
|
struct SFNested
|
|
{
|
|
size_t[2] d;
|
|
void* p1;
|
|
fn f;
|
|
// implicite outer
|
|
|
|
void foo() {} // need member fnction to not be POD
|
|
}
|
|
|
|
class CFNested
|
|
{
|
|
// implicit vtptr,monitor
|
|
size_t[2] d;
|
|
void* p1;
|
|
// implicite outer
|
|
}
|
|
|
|
testType!(SFNested) ([ 0b10100 ]);
|
|
_testType!(CFNested) ([ 0b110000 ]);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
testRTInfo();
|
|
}
|