# HG changeset patch # User eldar # Date 1246712686 0 # Node ID 7d9db724ee1d192515da912bbb7769a63fedb1f7 # Parent d3f4f14d43a52b065c5b68ed517cce63dabbb986 QObject is now non GC'ed, to better integrate to Qt memory management diff -r d3f4f14d43a5 -r 7d9db724ee1d examples/desktop/systray/build.sh --- a/examples/desktop/systray/build.sh Fri Jul 03 20:53:07 2009 +0000 +++ b/examples/desktop/systray/build.sh Sat Jul 04 13:04:46 2009 +0000 @@ -1,4 +1,4 @@ #! /bin/bash ../../../tools/drcc/drcc systray.qrc > qrc_systray.d -ldmd main.d window.d qrc_systray.d -I../../../ -I../../../qt/d1 -L-L../../../lib -L-lqtdgui -L-lqtdcore -L-lQtCore -L-lQtGui -ofsystray +dmd main.d window.d qrc_systray.d -I../../../ -I../../../qt/d1 -L-L../../../lib -L-lqtdgui -L-lqtdcore -L-lQtCore -L-lQtGui -ofsystray diff -r d3f4f14d43a5 -r 7d9db724ee1d generator/dgenerator.cpp --- a/generator/dgenerator.cpp Fri Jul 03 20:53:07 2009 +0000 +++ b/generator/dgenerator.cpp Sat Jul 04 13:04:46 2009 +0000 @@ -2845,13 +2845,14 @@ const ComplexTypeEntry *ctype = static_cast(type->typeEntry()); if(ctype->isAbstract()) type_name = type_name + "_ConcreteWrapper"; -/* + s << INDENT << "scope " << arg_name << "_so = new StackObject!(" << type_name << ");" << endl << INDENT << "auto " << arg_name << "_d_ref = " << arg_name << "_so(" << arg_name <<", true);" << endl << INDENT << arg_name << "_d_ref.__no_real_delete = true;"; - */ +/* s << INDENT << "scope " << arg_name << "_d_ref = new " << type_name << "(" << arg_name <<", true);" << endl << INDENT << arg_name << "_d_ref.__no_real_delete = true;"; +*/ } s << endl; } diff -r d3f4f14d43a5 -r 7d9db724ee1d generator/typesystem_core-java.java --- a/generator/typesystem_core-java.java Fri Jul 03 20:53:07 2009 +0000 +++ b/generator/typesystem_core-java.java Sat Jul 04 13:04:46 2009 +0000 @@ -49,25 +49,30 @@ public bool __stackAllocated = false; public bool __qobject_is_deleting = false; -/* - new(uint size, void* p = null) + + new(size_t size, void* p = null) { if (!p) { p = malloc(size); if (!p) assert(false, "Out of memory"); + GC.addRange(p, size); } - return p; } delete(void* p) { - if (!(cast(typeof(this))p).__stackAllocated) - free(p); + if(p) + { + if (!(cast(typeof(this))p).__stackAllocated) { + free(p); + GC.removeRange(p); + } + } } -*/ + // list of QObjects references to prevent them from garbage collecting if they are managed by Qt private static QObject[] __gc_ref_list; diff -r d3f4f14d43a5 -r 7d9db724ee1d qt/QGlobal.d --- a/qt/QGlobal.d Fri Jul 03 20:53:07 2009 +0000 +++ b/qt/QGlobal.d Sat Jul 04 13:04:46 2009 +0000 @@ -586,30 +586,126 @@ mixin QT_END_NAMESPACE; -package import tango.stdc.stdlib; +package import tango.stdc.stdlib, + tango.core.Memory; -template sizeOf(C : Object) +private +struct Align +{ + ubyte a; + void* b; +} + +private +const PTR_ALIGN = Align.tupleof[1].alignof; + +version( X86 ) + const MEM_ALIGN = 8u; +else + static assert(false, "Unknown memory alignment for this platform."); + +private +template AlignPad(size_t base, size_t aligned) { - const sizeOf = sizeOfImpl!(C); + static if( aligned == 0 ) + const AlignPad = base; + else + const AlignPad = ((base+PTR_ALIGN-1)/PTR_ALIGN)*PTR_ALIGN + + aligned; } - -size_t sizeOfImpl(C)() + +template InstanceSize(T) +{ + static if( is( T == Object ) ) + const InstanceSize = 2*(void*).sizeof; + else + const InstanceSize = Max!( + AlignPad!( + InstanceSize!(Super!(T)), + InterfaceCount!(T)*(void*).sizeof), + + AlignPad!( + InstanceSizeImpl!(T, 0), + + InterfaceCount!(T)*(void*).sizeof)); +} + +private +template Super(T) +{ + static if( is( T S == super ) ) + alias First!(S) Super; + else + static assert(false, "Can't get super of "~T.mangleof); +} + +private +template First(T) { - size_t size; - - foreach (i, _; typeof(C.tupleof)) - { - auto newSize = C.tupleof[i].offsetof + C.tupleof[i].sizeof; - if (newSize > size) - size = newSize; - } - - return size; + alias T First; +} + +private +template First(T, Ts...) +{ + alias T First; +} + +private +template InstanceSizeImpl(T, size_t i) +{ + static if( i < T.tupleof.length ) + const InstanceSizeImpl = Max!( + T.tupleof[i].offsetof + T.tupleof[i].sizeof, + InstanceSizeImpl!(T, i+1)); + else + // This is necessary to account for classes without member + // variables. + const InstanceSizeImpl = 2*(void*).sizeof; +} + +private +template Max(size_t a, size_t b) +{ + static if( a > b ) + const Max = a; + else + const Max = b; +} + +template InstanceSizeAligned(T, size_t alignment=MEM_ALIGN) +{ + static if( alignment == 0 ) + const InstanceSizeAligned = InstanceSize!(T); + else + const uint InstanceSizeAligned + = InstanceSizeAlignImpl!(T, alignment).result; +} + +private +template InstanceSizeAlignedImpl(T, size_t alignment) +{ + private const base_size = InstanceSize!(T); + const result = ((base_size+alignment-1)/alignment)*alignment; +} + +private +template InterfaceCount(T) +{ + static if( is( T == Object ) ) + const InterfaceCount = 0u; + else static if( is( T S == super ) ) + const InterfaceCount = InterfaceCountImpl!(S); +} + +private +template InterfaceCountImpl(TBase, TInterfaces...) +{ + const InterfaceCountImpl = TInterfaces.length; } scope class StackObject(C) { - byte[sizeOf!(C)] data; + byte[InstanceSize!(C)] data; bool constructed; C opCall(A...)(A args) diff -r d3f4f14d43a5 -r 7d9db724ee1d qt/QGlobal.d.inc --- a/qt/QGlobal.d.inc Fri Jul 03 20:53:07 2009 +0000 +++ b/qt/QGlobal.d.inc Sat Jul 04 13:04:46 2009 +0000 @@ -580,4 +580,148 @@ const ushort QT_EDITION_EVALUATION = QT_EDITION_DESKTOP; mixin QT_END_NAMESPACE; + +package import tango.stdc.stdlib, + tango.core.Memory; + +private +struct Align +{ + ubyte a; + void* b; +} + +private +const PTR_ALIGN = Align.tupleof[1].alignof; + +version( X86 ) + const MEM_ALIGN = 8u; +else + static assert(false, "Unknown memory alignment for this platform."); + +private +template AlignPad(size_t base, size_t aligned) +{ + static if( aligned == 0 ) + const AlignPad = base; + else + const AlignPad = ((base+PTR_ALIGN-1)/PTR_ALIGN)*PTR_ALIGN + + aligned; +} + +template InstanceSize(T) +{ + static if( is( T == Object ) ) + const InstanceSize = 2*(void*).sizeof; + else + const InstanceSize = Max!( + AlignPad!( + InstanceSize!(Super!(T)), + InterfaceCount!(T)*(void*).sizeof), + + AlignPad!( + InstanceSizeImpl!(T, 0), + + InterfaceCount!(T)*(void*).sizeof)); +} + +private +template Super(T) +{ + static if( is( T S == super ) ) + alias First!(S) Super; + else + static assert(false, "Can't get super of "~T.mangleof); +} + +private +template First(T) +{ + alias T First; +} + +private +template First(T, Ts...) +{ + alias T First; +} + +private +template InstanceSizeImpl(T, size_t i) +{ + static if( i < T.tupleof.length ) + const InstanceSizeImpl = Max!( + T.tupleof[i].offsetof + T.tupleof[i].sizeof, + InstanceSizeImpl!(T, i+1)); + else + // This is necessary to account for classes without member + // variables. + const InstanceSizeImpl = 2*(void*).sizeof; +} + +private +template Max(size_t a, size_t b) +{ + static if( a > b ) + const Max = a; + else + const Max = b; +} + +template InstanceSizeAligned(T, size_t alignment=MEM_ALIGN) +{ + static if( alignment == 0 ) + const InstanceSizeAligned = InstanceSize!(T); + else + const uint InstanceSizeAligned + = InstanceSizeAlignImpl!(T, alignment).result; +} + +private +template InstanceSizeAlignedImpl(T, size_t alignment) +{ + private const base_size = InstanceSize!(T); + const result = ((base_size+alignment-1)/alignment)*alignment; +} + +private +template InterfaceCount(T) +{ + static if( is( T == Object ) ) + const InterfaceCount = 0u; + else static if( is( T S == super ) ) + const InterfaceCount = InterfaceCountImpl!(S); +} + +private +template InterfaceCountImpl(TBase, TInterfaces...) +{ + const InterfaceCountImpl = TInterfaces.length; +} + +scope class StackObject(C) +{ + byte[InstanceSize!(C)] data; + bool constructed; + + C opCall(A...)(A args) + { + assert(!constructed); + + auto r = new(&data)C(args); + r.__stackAllocated = true; + constructed = true; + + return r; + } + + ~this() + { + if (constructed) + { + auto obj = cast(C)&data; + delete obj; + } + } +} + mixin QT_END_HEADER;