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/gc_priv.h"
45 #ifdef GC_NAME_CONFLICT
53 #define my_assert( e ) \
55 GC_printf1( "Assertion failure in " __FILE__ ", line %d: " #e "\n", \
61 /* An uncollectable class. */
63 A( int iArg
): i( iArg
) {}
64 void Test( int iArg
) {
65 my_assert( i
== iArg
);}
69 class B
: public gc
, public A
{public:
70 /* A collectable class. */
74 my_assert( deleting
);}
75 static void Deleting( int on
) {
77 static int deleting
;};
82 class C
: public gc_cleanup
, public A
{public:
83 /* A collectable class with cleanup and virtual multiple inheritance. */
85 C( int levelArg
): A( levelArg
), level( levelArg
) {
88 left
= new C( level
- 1 );
89 right
= new C( level
- 1 );}
93 this->A::Test( level
);
95 my_assert( level
== 0 ?
96 left
== 0 && right
== 0 :
97 level
== left
->level
+ 1 && level
== right
->level
+ 1 );
101 my_assert( nFreed
<= nAllocated
&& nFreed
>= .8 * nAllocated
);}
104 static int nAllocated
;
110 int C::nAllocated
= 0;
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. */
117 D( int iArg
): i( iArg
) {
119 static void CleanUp( void* obj
, void* data
) {
122 my_assert( self
->i
== (int) (long) data
);}
124 my_assert( nFreed
>= .8 * nAllocated
);}
128 static int nAllocated
;};
131 int D::nAllocated
= 0;
134 class E
: public gc_cleanup
{public:
135 /* A collectable class with clean-up for use by F. */
143 static int nAllocated
;};
146 int E::nAllocated
= 0;
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. */
158 my_assert( nFreed
>= .8 * nAllocated
);
159 my_assert( 2 * nFreed
== E::nFreed
);}
163 static int nAllocated
;};
166 int F::nAllocated
= 0;
169 long Disguise( void* p
) {
172 void* Undisguise( long i
) {
177 int APIENTRY
WinMain(
178 HINSTANCE instance
, HINSTANCE prev
, LPSTR cmd
, int cmdShow
)
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;}
191 int main( int argc
, char* argv
[] ) {
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
203 # ifdef USE_STD_ALLOCATOR
204 int *x
= gc_allocator
<int>().allocate(1);
205 int **xptr
= traceable_allocator
<int *>().allocate(1);
208 int *x
= (int *)gc_alloc::allocate(sizeof(int));
210 int *x
= (int *)alloc::allocate(sizeof(int));
214 # ifdef USE_STD_ALLOCATOR
218 if (argc
!= 2 || (0 >= (n
= atoi( argv
[ 1 ] )))) {
219 GC_printf0( "usage: test_cpp number-of-iterations\nAssuming 10 iters\n" );
222 for (iters
= 1; iters
<= n
; iters
++) {
223 GC_printf1( "Starting iteration %d\n", iters
);
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. */
230 for (i
= 0; i
< 1000; i
++) {
231 as
[ i
] = Disguise( new (NoGC
) A( i
) );
232 bs
[ i
] = Disguise( new (NoGC
) B( i
) );}
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
++) {
238 C
c1( 2 ); /* stack allocation should work too */
239 D
* d
= ::new (USE_GC
, D::CleanUp
, (void*)(long)i
) D( i
);
241 if (0 == i
% 10) delete c
;}
243 /* Allocate a very large number of collectable As and Bs and
244 drop the references to them immediately, forcing many
246 for (i
= 0; i
< 1000000; i
++) {
247 A
* a
= new (USE_GC
) A( i
);
249 b
= new (USE_GC
) B( i
);
254 # ifdef FINALIZE_ON_DEMAND
255 GC_invoke_finalizers();
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
] );
269 # ifdef FINALIZE_ON_DEMAND
270 GC_invoke_finalizers();
275 /* Make sure most of the finalizable Cs, Ds, and Fs have
281 # ifdef USE_STD_ALLOCATOR
284 my_assert (29 == x
[0]);
285 GC_printf0( "The test appears to have succeeded.\n" );