Annotation of OpenXM_contrib/gc/test_cpp.cc, Revision 1.1.1.2
1.1 maekawa 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: #ifndef __GNUC__
32: # include "gc_alloc.h"
33: #endif
34: extern "C" {
35: #include "gc_priv.h"
36: }
37: #ifdef MSWIN32
38: # include <windows.h>
39: #endif
1.1.1.2 ! maekawa 40: #ifdef GC_NAME_CONFLICT
! 41: # define USE_GC UseGC
! 42: struct foo * GC;
! 43: #else
! 44: # define USE_GC GC
! 45: #endif
1.1 maekawa 46:
47:
48: #define my_assert( e ) \
49: if (! (e)) { \
50: GC_printf1( "Assertion failure in " __FILE__ ", line %d: " #e "\n", \
51: __LINE__ ); \
52: exit( 1 ); }
53:
54:
55: class A {public:
56: /* An uncollectable class. */
57:
58: A( int iArg ): i( iArg ) {}
59: void Test( int iArg ) {
60: my_assert( i == iArg );}
61: int i;};
62:
63:
64: class B: public gc, public A {public:
65: /* A collectable class. */
66:
67: B( int j ): A( j ) {}
68: ~B() {
69: my_assert( deleting );}
70: static void Deleting( int on ) {
71: deleting = on;}
72: static int deleting;};
73:
74: int B::deleting = 0;
75:
76:
77: class C: public gc_cleanup, public A {public:
78: /* A collectable class with cleanup and virtual multiple inheritance. */
79:
80: C( int levelArg ): A( levelArg ), level( levelArg ) {
81: nAllocated++;
82: if (level > 0) {
83: left = new C( level - 1 );
84: right = new C( level - 1 );}
85: else {
86: left = right = 0;}}
87: ~C() {
88: this->A::Test( level );
89: nFreed++;
90: my_assert( level == 0 ?
91: left == 0 && right == 0 :
92: level == left->level + 1 && level == right->level + 1 );
93: left = right = 0;
94: level = -123456;}
95: static void Test() {
96: my_assert( nFreed <= nAllocated && nFreed >= .8 * nAllocated );}
97:
98: static int nFreed;
99: static int nAllocated;
100: int level;
101: C* left;
102: C* right;};
103:
104: int C::nFreed = 0;
105: int C::nAllocated = 0;
106:
107:
108: class D: public gc {public:
109: /* A collectable class with a static member function to be used as
110: an explicit clean-up function supplied to ::new. */
111:
112: D( int iArg ): i( iArg ) {
113: nAllocated++;}
114: static void CleanUp( void* obj, void* data ) {
115: D* self = (D*) obj;
116: nFreed++;
117: my_assert( self->i == (int) (long) data );}
118: static void Test() {
119: my_assert( nFreed >= .8 * nAllocated );}
120:
121: int i;
122: static int nFreed;
123: static int nAllocated;};
124:
125: int D::nFreed = 0;
126: int D::nAllocated = 0;
127:
128:
129: class E: public gc_cleanup {public:
130: /* A collectable class with clean-up for use by F. */
131:
132: E() {
133: nAllocated++;}
134: ~E() {
135: nFreed++;}
136:
137: static int nFreed;
138: static int nAllocated;};
139:
140: int E::nFreed = 0;
141: int E::nAllocated = 0;
142:
143:
144: class F: public E {public:
145: /* A collectable class with clean-up, a base with clean-up, and a
146: member with clean-up. */
147:
148: F() {
149: nAllocated++;}
150: ~F() {
151: nFreed++;}
152: static void Test() {
153: my_assert( nFreed >= .8 * nAllocated );
154: my_assert( 2 * nFreed == E::nFreed );}
155:
156: E e;
157: static int nFreed;
158: static int nAllocated;};
159:
160: int F::nFreed = 0;
161: int F::nAllocated = 0;
162:
163:
164: long Disguise( void* p ) {
165: return ~ (long) p;}
166:
167: void* Undisguise( long i ) {
168: return (void*) ~ i;}
169:
170:
171: #ifdef MSWIN32
172: int APIENTRY WinMain(
173: HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int cmdShow )
174: {
175: int argc;
176: char* argv[ 3 ];
177:
178: for (argc = 1; argc < sizeof( argv ) / sizeof( argv[ 0 ] ); argc++) {
179: argv[ argc ] = strtok( argc == 1 ? cmd : 0, " \t" );
180: if (0 == argv[ argc ]) break;}
181:
182: #else
183: # ifdef MACOS
184: int main() {
185: # else
186: int main( int argc, char* argv[] ) {
187: # endif
188: #endif
189:
190: # if defined(MACOS) // MacOS
191: char* argv_[] = {"test_cpp", "10"}; // doesn't
192: argv = argv_; // have a
193: argc = sizeof(argv_)/sizeof(argv_[0]); // commandline
194: # endif
195: int i, iters, n;
196: # if !defined(__GNUC__) && !defined(MACOS)
197: int *x = (int *)alloc::allocate(sizeof(int));
198:
199: *x = 29;
200: x -= 3;
201: # endif
202: if (argc != 2 || (0 >= (n = atoi( argv[ 1 ] )))) {
203: GC_printf0( "usage: test_cpp number-of-iterations\n" );
204: exit( 1 );}
205:
206: for (iters = 1; iters <= n; iters++) {
207: GC_printf1( "Starting iteration %d\n", iters );
208:
209: /* Allocate some uncollectable As and disguise their pointers.
210: Later we'll check to see if the objects are still there. We're
211: checking to make sure these objects really are uncollectable. */
212: long as[ 1000 ];
213: long bs[ 1000 ];
214: for (i = 0; i < 1000; i++) {
215: as[ i ] = Disguise( new (NoGC) A( i ) );
216: bs[ i ] = Disguise( new (NoGC) B( i ) );}
217:
218: /* Allocate a fair number of finalizable Cs, Ds, and Fs.
219: Later we'll check to make sure they've gone away. */
220: for (i = 0; i < 1000; i++) {
221: C* c = new C( 2 );
222: C c1( 2 ); /* stack allocation should work too */
1.1.1.2 ! maekawa 223: D* d = ::new (USE_GC, D::CleanUp, (void*) i) D( i );
1.1 maekawa 224: F* f = new F;
225: if (0 == i % 10) delete c;}
226:
227: /* Allocate a very large number of collectable As and Bs and
228: drop the references to them immediately, forcing many
229: collections. */
230: for (i = 0; i < 1000000; i++) {
1.1.1.2 ! maekawa 231: A* a = new (USE_GC) A( i );
1.1 maekawa 232: B* b = new B( i );
1.1.1.2 ! maekawa 233: b = new (USE_GC) B( i );
1.1 maekawa 234: if (0 == i % 10) {
235: B::Deleting( 1 );
236: delete b;
237: B::Deleting( 0 );}
238: # ifdef FINALIZE_ON_DEMAND
239: GC_invoke_finalizers();
240: # endif
241: }
242:
243: /* Make sure the uncollectable As and Bs are still there. */
244: for (i = 0; i < 1000; i++) {
245: A* a = (A*) Undisguise( as[ i ] );
246: B* b = (B*) Undisguise( bs[ i ] );
247: a->Test( i );
248: delete a;
249: b->Test( i );
250: B::Deleting( 1 );
251: delete b;
252: B::Deleting( 0 );
253: # ifdef FINALIZE_ON_DEMAND
254: GC_invoke_finalizers();
255: # endif
256:
257: }
258:
259: /* Make sure most of the finalizable Cs, Ds, and Fs have
260: gone away. */
261: C::Test();
262: D::Test();
263: F::Test();}
264:
265: # if !defined(__GNUC__) && !defined(MACOS)
266: my_assert (29 == x[3]);
267: # endif
268: GC_printf0( "The test appears to have succeeded.\n" );
269: return( 0 );}
270:
271:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>