changeset 184:7d9db724ee1d

QObject is now non GC'ed, to better integrate to Qt memory management
author eldar
date Sat, 04 Jul 2009 13:04:46 +0000
parents d3f4f14d43a5
children 4fcf7ba2a791
files examples/desktop/systray/build.sh generator/dgenerator.cpp generator/typesystem_core-java.java qt/QGlobal.d qt/QGlobal.d.inc
diffstat 5 files changed, 271 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- 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
--- 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<const ComplexTypeEntry *>(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;
             }
--- 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;
     
--- 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)
--- 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;