gc.test.cc

Go to the documentation of this file.
00001 /*
00002    The lestes compiler suite
00003    Copyright (C) 2002, 2003, 2004, 2005 Miroslav Tichy
00004    Copyright (C) 2002, 2003, 2004, 2005 Petr Zika
00005    Copyright (C) 2002, 2003, 2004, 2005 Vojtech Hala
00006    Copyright (C) 2002, 2003, 2004, 2005 Jiri Kosina
00007    Copyright (C) 2002, 2003, 2004, 2005 Pavel Sanda
00008    Copyright (C) 2002, 2003, 2004, 2005 Jan Zouhar
00009    Copyright (C) 2002, 2003, 2004, 2005 Rudolf Thomas
00010 
00011    This program is free software; you can redistribute it and/or modify
00012    it under the terms of the GNU General Public License as published by
00013    the Free Software Foundation; version 2 of the License.
00014 
00015    This program is distributed in the hope that it will be useful,
00016    but WITHOUT ANY WARRANTY; without even the implied warranty of
00017    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00018    GNU General Public License for more details.
00019 
00020    See the full text of the GNU General Public License version 2, and
00021    the limitations in the file doc/LICENSE.
00022 
00023    By accepting the license the licensee waives any and all claims
00024    against the copyright holder(s) related in whole or in part to the
00025    work, its use, and/or the inability to use it.
00026  
00027  */
00028 /*! \file
00029   \brief Unit test.
00030 
00031   Unit test for garbage collector functionality.
00032   \author pt
00033 */
00034 #include <lestes/common.hh>
00035 
00036 package(lestes);
00037 package(std);
00038 package(mem);
00039 
00040 using namespace ::std;
00041 
00042 class a: public ::lestes::std::object {
00043 public:
00044         static ptr<a> create(void);
00045 protected:
00046         a(void);
00047         virtual void gc_mark(void);
00048 private:
00049         a(const a &);
00050         a &operator=(const a &);
00051 };
00052 
00053 a::a(void) {
00054 }
00055 
00056 void a::gc_mark(void)
00057 {
00058 	::lestes::std::object::gc_mark();
00059 }
00060 
00061 ptr<a> a::create(void)
00062 { 
00063         return new a();
00064 }
00065 
00066 class aa: public a {
00067 public:
00068         static ptr<aa> create(void);
00069 protected:
00070         aa(void);
00071         virtual void gc_mark(void);
00072 private:
00073         aa(const aa &);
00074         aa &operator=(const aa &);
00075 };
00076 
00077 aa::aa(void) {
00078 }
00079 
00080 void aa::gc_mark(void)
00081 {
00082         a::gc_mark();
00083 }
00084 
00085 ptr<aa> aa::create(void)
00086 { 
00087         return new aa();
00088 }
00089 
00090 class b: public ::lestes::std::object {
00091 public:
00092         static ptr<b> create(const ptr<a> &a_fa, const ptr<aa> &a_faa);
00093         void gc_mark(void);
00094 protected:
00095         b(const ptr<a> &a_fa, const ptr<aa> &a_faa);
00096 private:
00097         srp<a> fa;
00098         srp<aa> faa;
00099         b(const b &);
00100         b &operator=(const b &);
00101 };
00102 
00103 b::b(const ptr<a> &a_fa, const ptr<aa> &a_faa):
00104         fa(a_fa),
00105         faa(a_faa)
00106 {
00107 }
00108 
00109 ptr<b> b::create(const ptr<a> &a_fa, const ptr<aa> &a_faa)
00110 { 
00111         return new b(a_fa,a_faa);
00112 }
00113 
00114 void b::gc_mark(void)
00115 {
00116         fa.gc_mark();
00117         faa.gc_mark();
00118 	::lestes::std::object::gc_mark();
00119 }
00120 
00121 class c: public b {
00122 public:
00123         static ptr<c> create(const ptr<a> &a_fa, const ptr<aa> &a_faa, const ptr<a> &a_ga);
00124         void gc_mark(void);
00125 protected:
00126         c(const ptr<a> &a_fa, const ptr<aa> &a_faa, const ptr<a> &a_ga);
00127 private:
00128         srp<a> ga;
00129         c(const c &);
00130         c &operator=(const c &);
00131 };
00132 
00133 c::c(const ptr<a> &a_fa, const ptr<aa> &a_faa, const ptr<a> &a_ga):
00134                 b(a_fa,a_faa),
00135                 ga(a_ga)
00136 {
00137 }
00138 
00139 ptr<c> c::create(const ptr<a> &a_fa, const ptr<aa> &a_faa, const ptr<a> &a_ga)
00140 { 
00141         return new c(a_fa,a_faa,a_ga);
00142 }
00143 
00144 void c::gc_mark(void)
00145 {
00146         ga.gc_mark();
00147         b::gc_mark();
00148 }
00149 
00150 class d: public ::lestes::std::object {
00151 public:
00152         static ptr<d> create(const ptr<c> &a_fc, const ptr<c> &a_gc);
00153         void gc_mark(void);
00154 protected:
00155         d(const ptr<c> &a_fc, const ptr<c> &a_gc);
00156 private:
00157         srp<c> fc;
00158         srp<c> gc;
00159 };
00160 
00161 d::d(const ptr<c> &a_fc, const ptr<c> &a_gc):
00162         fc(a_fc),
00163         gc(a_gc)
00164 {
00165 }
00166 
00167 ptr<d> d::create(const ptr<c> &a_fc, const ptr<c> &a_gc)
00168 {
00169         return new d(a_fc, a_gc);
00170 }
00171 
00172 void d::gc_mark(void)
00173 {
00174         fc.gc_mark();
00175         gc.gc_mark();
00176 	::lestes::std::object::gc_mark();
00177 }
00178 
00179 class e: public ::lestes::std::object {
00180 public:
00181         static ptr<e> create(const ptr<e> &a_link);
00182         void link_set(const ptr<e> &a_link);
00183         void gc_mark(void);
00184 protected:
00185         e(const ptr<e> &a_link);
00186 private:
00187         srp<e> link;
00188 };
00189 
00190 e::e(const ptr<e> &a_link):
00191         link(a_link) 
00192 {
00193 }
00194 
00195 ptr<e> e::create(const ptr<e> &a_link)
00196 {
00197         return new e(a_link);
00198 }
00199 
00200 void e::link_set(const ptr<e> &a_link)
00201 {
00202         link = a_link;
00203 }
00204 
00205 void e::gc_mark(void)
00206 {
00207         link.gc_mark();
00208 	::lestes::std::object::gc_mark();
00209 }
00210 
00211 //! helper to assert count of live root pointers and keystones
00212 #define live(r,k) lassert(gc::live_roots() == (r + static_r) && gc::live_keystones() == (k + static_k))
00213 
00214 void gc_test(void)
00215 {
00216         // sweep the objects created before the test
00217         gc::run();
00218         
00219         // memorize static roots and keystones
00220         ulint static_r = gc::live_roots();
00221         ulint static_k = gc::live_keystones();
00222 
00223         // jtbs
00224         live(0,0);
00225         gc::run();
00226         live(0,0);
00227         
00228         // single ptr
00229         {
00230                 ptr<a> a1;
00231                 live(1,0);
00232                 gc::run();
00233                 live(1,0);
00234         }
00235         live(0,0);
00236         
00237         // single object
00238         {
00239                 ptr<a> a2(a::create());
00240                 live(1,1);
00241                 gc::run();
00242                 live(1,1);
00243                 a2 = NULL;
00244                 live(1,1);
00245                 gc::run();
00246                 live(1,0);
00247         }
00248         live(0,0);
00249         
00250         // more objects for one ptr
00251         {
00252                 ptr<a> a3(a::create());
00253                 live(1,1);
00254                 a3 = a::create();
00255                 a3 = a::create();
00256                 a3 = a::create();
00257                 live(1,4);
00258                 gc::run();
00259                 live(1,1);
00260         }
00261         live(0,1);
00262         gc::run();
00263         live(0,0);
00264 
00265         // one object for more ptr
00266         {
00267                 ptr<a> a4(a::create());
00268                 live(1,1);
00269                 {
00270                         ptr<a> a5(a4);
00271                         live(2,1);
00272                         a4 = NULL;
00273                         gc::run();
00274                         live(2,1);
00275                 }
00276                 live(1,1);
00277                 gc::run();
00278                 live(1,0);
00279         }
00280         live(0,0);
00281 
00282         // descendant in ancestor ptr
00283         {
00284                 ptr<a> a6(aa::create());
00285                 live(1,1);
00286                 gc::run();
00287                 live(1,1);
00288                 ptr<a> a7(a6);
00289                 live(2,1);
00290                 a6 = NULL;
00291                 gc::run();
00292                 live(2,1);
00293                 a7 = NULL;
00294                 gc::run();
00295                 live(2,0);
00296         }
00297         live(0,0);
00298 
00299         // one level empty structure
00300         {
00301                 ptr<b> b1(b::create(NULL,NULL));
00302                 live(1,1);
00303                 gc::run();
00304                 live(1,1);
00305                 b1 = NULL;
00306                 gc::run();
00307                 live(1,0);
00308         }
00309         live(0,0);
00310 
00311         // one level structure
00312         {
00313                 ptr<b> b1(b::create(a::create(),aa::create()));
00314                 live(1,3);
00315                 gc::run();
00316                 live(1,3);
00317                 b1 = NULL;
00318                 gc::run();
00319                 live(1,0);
00320         }
00321         live(0,0);
00322 
00323         // one level shared structure
00324         {
00325                 ptr<a> a8(a::create());
00326                 ptr<b> b1(b::create(a8,aa::create()));
00327                 live(2,3);
00328                 gc::run();
00329                 live(2,3);
00330                 b1 = NULL;
00331                 gc::run();
00332                 live(2,1);
00333         }
00334         gc::run();
00335         live(0,0);
00336 
00337         // one level inherited structure
00338         {
00339                 ptr<c> c1(c::create(a::create(),aa::create(),a::create()));
00340                 live(1,4);
00341                 gc::run();
00342                 live(1,4);
00343                 c1 = NULL;
00344                 gc::run();
00345                 live(1,0);
00346         }
00347         live(0,0);
00348 
00349         // two level structure
00350         {
00351                 ptr<c> c2(c::create(a::create(),aa::create(),a::create()));
00352                 ptr<c> c3(c::create(a::create(),aa::create(),a::create()));
00353                 ptr<d> d1(d::create(c2,c3));
00354                 live(3,9);
00355                 gc::run();
00356                 live(3,9);
00357                 c2 = c3 = NULL;
00358                 gc::run();
00359                 live(3,9);
00360                 d1 = NULL;
00361                 gc::run();
00362                 live(3,0);
00363         }
00364         live(0,0);
00365 
00366         // cyclic structure
00367         {
00368                 ptr<e> e1(e::create(NULL));
00369                 ptr<e> e2(e::create(e::create(e::create(e::create(e1)))));
00370                 e1->link_set(e2);
00371                 live(2,5);
00372                 gc::run();
00373                 live(2,5);
00374                 e2 = NULL;
00375                 gc::run();
00376                 live(2,5);
00377                 e1 = NULL;
00378                 gc::run();
00379                 live(2,0);
00380         }
00381         live(0,0);
00382 }
00383 
00384 end_package(mem);
00385 end_package(std);
00386 end_package(lestes);
00387 
00388 int main(void)
00389 {
00390 	::lestes::std::mem::gc_test();
00391         return 0;
00392 }
00393 /* vim: set ft=lestes : */

Generated on Mon Feb 12 18:22:34 2007 for lestes by doxygen 1.5.1-20070107