Obtaining aligned addresses and aligned spaces for objects
Ali Çehreli
acehreli at yahoo.com
Wed Jun 29 10:29:07 PDT 2011
On Wed, 29 Jun 2011 10:47:39 -0400, Steven Schveighoffer wrote:
> On Wed, 29 Jun 2011 01:42:37 -0400, Ali Çehreli <acehreli at yahoo.com>
> wrote:
>> On a related note, why doesn't __traits(classInstanceSize, T) consider
>> the padding bytes? If I'm not mistaken struct sizes do include the
>> padding bytes. The following class has the very odd size of 17! Is that
>> by design?
>
> Probably it's because classes are intended to occupy their own memory
> block, so the pad doesn't matter, you can't put two in the same block
> anyways.
You also say a block is 16 bytes below but the following program seems to
be able to put objects at 24 byte intervals.
>
> If you want to do it, I think it should be possible.
Actually I don't care. :) I am just trying to find out the right way of
placing objects in memory. I am just trying to cover all aspects of it.
> But I don't think
> it would work great if you put two classes in the same block without
> significant compiler/GC changes.
>
> That being said, given that all GC blocks are at least 16-byte aligned,
> the same should hold true for any class instance.
I am able to place class objects at 24 byte intervals with the following
program, which indicates that some objects straddle block boundaries. Is
that fine? Is the following method sufficient. Am I doing things
unnecessarily complicated?
import std.stdio;
import core.memory;
import std.conv;
class C
{
char c;
this(char c)
{
this.c = c;
}
}
T * alignedAddress(T)(T * candidate)
{
return cast(T*)((cast(size_t)candidate + T.alignof - 1)
/ T.alignof * T.alignof);
}
void * alignedAddress(T)(void * candidate)
{
return alignedAddress(cast(T*)candidate);
}
size_t alignedSpace(T)()
{
static if (is (T == class)) {
size_t size = __traits(classInstanceSize, T);
} else {
size_t size = T.sizeof;
}
return cast(size_t)alignedAddress(cast(T*)size);
}
void main()
{
size_t size = __traits(classInstanceSize, C);
size_t alignedSize = alignedSpace!C();
writeln("instance size: ", size);
writeln("alignment : ", C.alignof);
writeln("aligned size : ", alignedSize);
/* Inputs to use to make objects */
string inputs = "hello world";
/* Raw memory */
void * chunk = GC.calloc(inputs.length * alignedSize);
C[] variables;
/* Make objects */
foreach (i, c; inputs) {
void * candidateAddress = chunk + (i * alignedSize);
/* I don't think anymore that I need to call alignedAddress()
* below. Still... */
void * objectAddress = alignedAddress!C(candidateAddress);
writefln("candidate: %s addr: %s",
candidateAddress, objectAddress);
variables ~= emplace!C(objectAddress[0..size], c);
/*
* It might make more sense to pass
* objectAddress[0..alignedSize] above, but I can't. (Please
* see http://d.puremagic.com/issues/show_bug.cgi?id=6204 )
*/
}
/* Use the objects */
foreach (v; variables) {
writeln(v.c, '.');
}
}
Here is an output:
instance size: 17
alignment : 8
aligned size : 24
candidate: 7F11467A2E00 addr: 7F11467A2E00
candidate: 7F11467A2E18 addr: 7F11467A2E18
candidate: 7F11467A2E30 addr: 7F11467A2E30
candidate: 7F11467A2E48 addr: 7F11467A2E48
candidate: 7F11467A2E60 addr: 7F11467A2E60
candidate: 7F11467A2E78 addr: 7F11467A2E78
candidate: 7F11467A2E90 addr: 7F11467A2E90
candidate: 7F11467A2EA8 addr: 7F11467A2EA8
candidate: 7F11467A2EC0 addr: 7F11467A2EC0
candidate: 7F11467A2ED8 addr: 7F11467A2ED8
candidate: 7F11467A2EF0 addr: 7F11467A2EF0
h.
e.
l.
l.
o.
.
w.
o.
r.
l.
d.
>
> -Steve
Ali
More information about the Digitalmars-d-learn
mailing list