Annotation of OpenXM_contrib2/asir2000/gc/tests/test_cpp.cc, Revision 1.2
1.1 noro 1: /****************************************************************************
2: Copyright (c) 1994 by Xerox Corporation. All rights reserved.
3:
4: THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5: OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
6:
7: Permission is hereby granted to use or copy this program for any
8: purpose, provided the above notices are retained on all copies.
9: Permission to modify the code and to distribute modified code is
10: granted, provided the above notices are retained, and a notice that
11: the code was modified is included with the above copyright notice.
12: ****************************************************************************
13: Last modified on Mon Jul 10 21:06:03 PDT 1995 by ellis
14: modified on December 20, 1994 7:27 pm PST by boehm
15:
16: usage: test_cpp number-of-iterations
17:
18: This program tries to test the specific C++ functionality provided by
19: gc_c++.h that isn't tested by the more general test routines of the
20: collector.
21:
22: A recommended value for number-of-iterations is 10, which will take a
23: few minutes to complete.
24:
25: ***************************************************************************/
26:
27: #include "gc_cpp.h"
28: #include <stdio.h>
29: #include <stdlib.h>
30: #include <string.h>
31: #define USE_STD_ALLOCATOR
32: #ifdef USE_STD_ALLOCATOR
33: # include "gc_allocator.h"
34: #elif __GNUC__
35: # include "new_gc_alloc.h"
36: #else
37: # include "gc_alloc.h"
38: #endif
39: extern "C" {
40: #include "private/gc_priv.h"
41: }
42: #ifdef MSWIN32
43: # include <windows.h>
44: #endif
45: #ifdef GC_NAME_CONFLICT
46: # define USE_GC UseGC
47: struct foo * GC;
48: #else
49: # define USE_GC GC
50: #endif
51:
52:
53: #define my_assert( e ) \
54: if (! (e)) { \
55: GC_printf1( "Assertion failure in " __FILE__ ", line %d: " #e "\n", \
56: __LINE__ ); \
57: exit( 1 ); }
58:
59:
60: class A {public:
61: /* An uncollectable class. */
62:
63: A( int iArg ): i( iArg ) {}
64: void Test( int iArg ) {
65: my_assert( i == iArg );}
66: int i;};
67:
68:
69: class B: public gc, public A {public:
70: /* A collectable class. */
71:
72: B( int j ): A( j ) {}
73: ~B() {
74: my_assert( deleting );}
75: static void Deleting( int on ) {
76: deleting = on;}
77: static int deleting;};
78:
79: int B::deleting = 0;
80:
81:
82: class C: public gc_cleanup, public A {public:
83: /* A collectable class with cleanup and virtual multiple inheritance. */
84:
85: C( int levelArg ): A( levelArg ), level( levelArg ) {
86: nAllocated++;
87: if (level > 0) {
88: left = new C( level - 1 );
89: right = new C( level - 1 );}
90: else {
91: left = right = 0;}}
92: ~C() {
93: this->A::Test( level );
94: nFreed++;
95: my_assert( level == 0 ?
96: left == 0 && right == 0 :
97: level == left->level + 1 && level == right->level + 1 );
98: left = right = 0;
99: level = -123456;}
100: static void Test() {
101: my_assert( nFreed <= nAllocated && nFreed >= .8 * nAllocated );}
102:
103: static int nFreed;
104: static int nAllocated;
105: int level;
106: C* left;
107: C* right;};
108:
109: int C::nFreed = 0;
110: int C::nAllocated = 0;
111:
112:
113: class D: public gc {public:
114: /* A collectable class with a static member function to be used as
115: an explicit clean-up function supplied to ::new. */
116:
117: D( int iArg ): i( iArg ) {
118: nAllocated++;}
119: static void CleanUp( void* obj, void* data ) {
120: D* self = (D*) obj;
121: nFreed++;
122: my_assert( self->i == (int) (long) data );}
123: static void Test() {
124: my_assert( nFreed >= .8 * nAllocated );}
125:
126: int i;
127: static int nFreed;
128: static int nAllocated;};
129:
130: int D::nFreed = 0;
131: int D::nAllocated = 0;
132:
133:
134: class E: public gc_cleanup {public:
135: /* A collectable class with clean-up for use by F. */
136:
137: E() {
138: nAllocated++;}
139: ~E() {
140: nFreed++;}
141:
142: static int nFreed;
143: static int nAllocated;};
144:
145: int E::nFreed = 0;
146: int E::nAllocated = 0;
147:
148:
149: class F: public E {public:
150: /* A collectable class with clean-up, a base with clean-up, and a
151: member with clean-up. */
152:
153: F() {
154: nAllocated++;}
155: ~F() {
156: nFreed++;}
157: static void Test() {
158: my_assert( nFreed >= .8 * nAllocated );
159: my_assert( 2 * nFreed == E::nFreed );}
160:
161: E e;
162: static int nFreed;
163: static int nAllocated;};
164:
165: int F::nFreed = 0;
166: int F::nAllocated = 0;
167:
168:
169: long Disguise( void* p ) {
170: return ~ (long) p;}
171:
172: void* Undisguise( long i ) {
173: return (void*) ~ i;}
174:
175:
176: #ifdef MSWIN32
177: int APIENTRY WinMain(
178: HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int cmdShow )
179: {
180: int argc;
181: char* argv[ 3 ];
182:
183: for (argc = 1; argc < sizeof( argv ) / sizeof( argv[ 0 ] ); argc++) {
184: argv[ argc ] = strtok( argc == 1 ? cmd : 0, " \t" );
185: if (0 == argv[ argc ]) break;}
186:
187: #else
188: # ifdef MACOS
189: int main() {
190: # else
191: int main( int argc, char* argv[] ) {
192: # endif
193: #endif
194:
1.2 ! noro 195: GC_init();
! 196:
1.1 noro 197: # if defined(MACOS) // MacOS
198: char* argv_[] = {"test_cpp", "10"}; // doesn't
199: argv = argv_; // have a
200: argc = sizeof(argv_)/sizeof(argv_[0]); // commandline
201: # endif
202: int i, iters, n;
203: # ifdef USE_STD_ALLOCATOR
204: int *x = gc_allocator<int>().allocate(1);
205: int **xptr = traceable_allocator<int *>().allocate(1);
206: # else
207: # ifdef __GNUC__
208: int *x = (int *)gc_alloc::allocate(sizeof(int));
209: # else
210: int *x = (int *)alloc::allocate(sizeof(int));
211: # endif
212: # endif
213: *x = 29;
214: # ifdef USE_STD_ALLOCATOR
215: *xptr = x;
216: x = 0;
217: # endif
218: if (argc != 2 || (0 >= (n = atoi( argv[ 1 ] )))) {
1.2 ! noro 219: GC_printf0( "usage: test_cpp number-of-iterations\nAssuming 10 iters\n" );
! 220: n = 10;}
1.1 noro 221:
222: for (iters = 1; iters <= n; iters++) {
223: GC_printf1( "Starting iteration %d\n", iters );
224:
225: /* Allocate some uncollectable As and disguise their pointers.
226: Later we'll check to see if the objects are still there. We're
227: checking to make sure these objects really are uncollectable. */
228: long as[ 1000 ];
229: long bs[ 1000 ];
230: for (i = 0; i < 1000; i++) {
231: as[ i ] = Disguise( new (NoGC) A( i ) );
232: bs[ i ] = Disguise( new (NoGC) B( i ) );}
233:
234: /* Allocate a fair number of finalizable Cs, Ds, and Fs.
235: Later we'll check to make sure they've gone away. */
236: for (i = 0; i < 1000; i++) {
237: C* c = new C( 2 );
238: C c1( 2 ); /* stack allocation should work too */
239: D* d = ::new (USE_GC, D::CleanUp, (void*)(long)i) D( i );
240: F* f = new F;
241: if (0 == i % 10) delete c;}
242:
243: /* Allocate a very large number of collectable As and Bs and
244: drop the references to them immediately, forcing many
245: collections. */
246: for (i = 0; i < 1000000; i++) {
247: A* a = new (USE_GC) A( i );
248: B* b = new B( i );
249: b = new (USE_GC) B( i );
250: if (0 == i % 10) {
251: B::Deleting( 1 );
252: delete b;
253: B::Deleting( 0 );}
254: # ifdef FINALIZE_ON_DEMAND
255: GC_invoke_finalizers();
256: # endif
257: }
258:
259: /* Make sure the uncollectable As and Bs are still there. */
260: for (i = 0; i < 1000; i++) {
261: A* a = (A*) Undisguise( as[ i ] );
262: B* b = (B*) Undisguise( bs[ i ] );
263: a->Test( i );
264: delete a;
265: b->Test( i );
266: B::Deleting( 1 );
267: delete b;
268: B::Deleting( 0 );
269: # ifdef FINALIZE_ON_DEMAND
270: GC_invoke_finalizers();
271: # endif
272:
273: }
274:
275: /* Make sure most of the finalizable Cs, Ds, and Fs have
276: gone away. */
277: C::Test();
278: D::Test();
279: F::Test();}
280:
281: # ifdef USE_STD_ALLOCATOR
282: x = *xptr;
283: # endif
284: my_assert (29 == x[0]);
285: GC_printf0( "The test appears to have succeeded.\n" );
286: return( 0 );}
287:
288:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>