1 /****************************************************************************
2 Copyright (c) 1994 by Xerox Corporation. All rights reserved.
4 THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5 OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
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
16 usage: test_cpp number-of-iterations
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
22 A recommended value for number-of-iterations is 10, which will take a
23 few minutes to complete.
25 ***************************************************************************/
31 #define USE_STD_ALLOCATOR
32 #ifdef USE_STD_ALLOCATOR
33 # include "gc_allocator.h"
35 # include "new_gc_alloc.h"
37 # include "gc_alloc.h"
40 # include "private/gcconfig.h"
41 GC_API void GC_printf(const char *format, ...);
42 /* Use GC private output to reach the same log file. */
43 /* Don't include gc_priv.h, since that may include Windows system */
44 /* header files that don't take kindly to this context. */
49 #ifdef GC_NAME_CONFLICT
57 #define my_assert( e ) \
59 GC_printf( "Assertion failure in " __FILE__ ", line %d: " #e "\n", \
65 /* An uncollectable class. */
67 A( int iArg ): i( iArg ) {}
68 void Test( int iArg ) {
69 my_assert( i == iArg );}
73 class B: public gc, public A {public:
74 /* A collectable class. */
78 my_assert( deleting );}
79 static void Deleting( int on ) {
81 static int deleting;};
86 class C: public gc_cleanup, public A {public:
87 /* A collectable class with cleanup and virtual multiple inheritance. */
89 C( int levelArg ): A( levelArg ), level( levelArg ) {
92 left = new C( level - 1 );
93 right = new C( level - 1 );}
97 this->A::Test( level );
99 my_assert( level == 0 ?
100 left == 0 && right == 0 :
101 level == left->level + 1 && level == right->level + 1 );
105 my_assert( nFreed <= nAllocated && nFreed >= .8 * nAllocated );}
108 static int nAllocated;
114 int C::nAllocated = 0;
117 class D: public gc {public:
118 /* A collectable class with a static member function to be used as
119 an explicit clean-up function supplied to ::new. */
121 D( int iArg ): i( iArg ) {
123 static void CleanUp( void* obj, void* data ) {
126 my_assert( self->i == (int) (GC_word) data );}
128 my_assert( nFreed >= .8 * nAllocated );}
132 static int nAllocated;};
135 int D::nAllocated = 0;
138 class E: public gc_cleanup {public:
139 /* A collectable class with clean-up for use by F. */
147 static int nAllocated;};
150 int E::nAllocated = 0;
153 class F: public E {public:
154 /* A collectable class with clean-up, a base with clean-up, and a
155 member with clean-up. */
162 my_assert( nFreed >= .8 * nAllocated );
163 my_assert( 2 * nFreed == E::nFreed );}
167 static int nAllocated;};
170 int F::nAllocated = 0;
173 GC_word Disguise( void* p ) {
174 return ~ (GC_word) p;}
176 void* Undisguise( GC_word i ) {
181 int APIENTRY WinMain(
182 HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int cmdShow )
187 for (argc = 1; argc < sizeof( argv ) / sizeof( argv[ 0 ] ); argc++) {
188 argv[ argc ] = strtok( argc == 1 ? cmd : 0, " \t" );
189 if (0 == argv[ argc ]) break;}
195 int main( int argc, char* argv[] ) {
201 # if defined(MACOS) // MacOS
202 char* argv_[] = {"test_cpp", "10"}; // doesn't
203 argv = argv_; // have a
204 argc = sizeof(argv_)/sizeof(argv_[0]); // commandline
207 # ifdef USE_STD_ALLOCATOR
208 int *x = gc_allocator<int>().allocate(1);
209 int *xio = gc_allocator_ignore_off_page<int>().allocate(1);
210 int **xptr = traceable_allocator<int *>().allocate(1);
213 int *x = (int *)gc_alloc::allocate(sizeof(int));
215 int *x = (int *)alloc::allocate(sizeof(int));
219 # ifdef USE_STD_ALLOCATOR
223 if (argc != 2 || (0 >= (n = atoi( argv[ 1 ] )))) {
224 GC_printf( "usage: test_cpp number-of-iterations\nAssuming 10 iters\n" );
227 for (iters = 1; iters <= n; iters++) {
228 GC_printf( "Starting iteration %d\n", iters );
230 /* Allocate some uncollectable As and disguise their pointers.
231 Later we'll check to see if the objects are still there. We're
232 checking to make sure these objects really are uncollectable. */
235 for (i = 0; i < 1000; i++) {
236 as[ i ] = Disguise( new (NoGC) A( i ) );
237 bs[ i ] = Disguise( new (NoGC) B( i ) );}
239 /* Allocate a fair number of finalizable Cs, Ds, and Fs.
240 Later we'll check to make sure they've gone away. */
241 for (i = 0; i < 1000; i++) {
243 C c1( 2 ); /* stack allocation should work too */
244 D* d = ::new (USE_GC, D::CleanUp, (void*)(GC_word)i) D( i );
246 if (0 == i % 10) delete c;}
248 /* Allocate a very large number of collectable As and Bs and
249 drop the references to them immediately, forcing many
251 for (i = 0; i < 1000000; i++) {
252 A* a = new (USE_GC) A( i );
254 b = new (USE_GC) B( i );
259 # ifdef FINALIZE_ON_DEMAND
260 GC_invoke_finalizers();
264 /* Make sure the uncollectable As and Bs are still there. */
265 for (i = 0; i < 1000; i++) {
266 A* a = (A*) Undisguise( as[ i ] );
267 B* b = (B*) Undisguise( bs[ i ] );
274 # ifdef FINALIZE_ON_DEMAND
275 GC_invoke_finalizers();
280 /* Make sure most of the finalizable Cs, Ds, and Fs have
286 # ifdef USE_STD_ALLOCATOR
289 my_assert (29 == x[0]);
290 GC_printf( "The test appears to have succeeded.\n" );