Class Instance allocations
Justin Johansson
no at spam.com
Wed Jan 13 07:29:35 PST 2010
I understand your quandary.
For me "Win32" == "32 bits" == "4 bytes" == "sizeof(ubiquitous machine
register)".
So why on earth, since Visual Studio 2001 (and before?), was the default
alignment set to 8 bytes for the M$ C/C++ compiler code generation
option? This I just do not understand (so, of course, enlightenment is
welcome).
Beers for the New Years,
Justin Johansson
bearophile wrote:
> This page says "The pointer returned from new() must be to memory aligned to the default alignment. This is 8 on win32 systems.":
> http://www.digitalmars.com/d/2.0/memory.html
>
> Is that true? Is this required by the tag bits added by the GC scans? Does std.c.stdlib.malloc always return aligned to 8 on Windows?
>
> Below in the same page, in the Mark/Release section:
>
> class Foo {
> ...
> new(size_t sz)
> { void *p;
> p = &buffer[bufindex];
> bufindex += sz;
> if (bufindex > buffer.length)
> throw new OutOfMemory;
> return p;
> }
> ...
>
> If sz is not a multiple of 8 then new() can return a pointer not aligned to 8:
>
> import std.outofmemory: OutOfMemoryException;
> import std.gc: addRange, removeRange;
> import std.c.stdlib: malloc, free;
> import std.c.stdio: printf;
>
> class Foo {
> static void[] buffer;
> static int bufIndex;
> static const int bufSize = 100;
> int x; //**********
>
> static this() {
> void* p = malloc(bufSize);
> if (!p)
> throw new OutOfMemoryException;
> addRange(p, p + bufSize);
> buffer = p[0 .. bufSize];
> }
>
> static ~this() {
> if (buffer.length) {
> removeRange(buffer.ptr);
> free(buffer.ptr);
> buffer = null;
> }
> }
>
> new(size_t sz) {
> void* p = &buffer[bufIndex];
> bufIndex += sz;
> if (bufIndex > buffer.length)
> throw new OutOfMemoryException;
> printf("%d %d\n", cast(size_t)p, cast(size_t)p % 8); // ******
> return p;
> }
>
> delete(void* p) {
> assert(0);
> }
>
> static int mark() {
> return bufIndex;
> }
>
> static void release(int i) {
> bufIndex = i;
> }
> }
>
> void main() {
> int m = Foo.mark();
> Foo f1 = new Foo; // allocate
> Foo f2 = new Foo; // allocate
> Foo.release(m); // deallocate f1 and f2
> }
>
> Output, f2 reference is now always aligned to 4 bytes:
> 1382368 0
> 1382380 4
>
> So, does the new() in this class (that has that extra "x" field) need to be fixed to be sure the pointers it returns are aligned to 8?
>
> The Foo class in the Mark/Release section has some other little bugs, that I think I have fixed here. D docs need something like the Andrei's book machinery, where D code snippets are actually run (Python docs too run their snippets).
>
> Bye,
> bearophile
More information about the Digitalmars-d
mailing list