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 ***************************************************************************/
32 # include "gc_alloc.h"
42 #define my_assert( e ) \
44 GC_printf1( "Assertion failure in " __FILE__ ", line %d: " #e "\n", \
50 /* An uncollectable class. */
52 A( int iArg
): i( iArg
) {}
53 void Test( int iArg
) {
54 my_assert( i
== iArg
);}
58 class B
: public gc
, public A
{public:
59 /* A collectable class. */
63 my_assert( deleting
);}
64 static void Deleting( int on
) {
66 static int deleting
;};
71 class C
: public gc_cleanup
, public A
{public:
72 /* A collectable class with cleanup and virtual multiple inheritance. */
74 C( int levelArg
): A( levelArg
), level( levelArg
) {
77 left
= new C( level
- 1 );
78 right
= new C( level
- 1 );}
82 this->A::Test( level
);
84 my_assert( level
== 0 ?
85 left
== 0 && right
== 0 :
86 level
== left
->level
+ 1 && level
== right
->level
+ 1 );
90 my_assert( nFreed
<= nAllocated
&& nFreed
>= .8 * nAllocated
);}
93 static int nAllocated
;
99 int C::nAllocated
= 0;
102 class D
: public gc
{public:
103 /* A collectable class with a static member function to be used as
104 an explicit clean-up function supplied to ::new. */
106 D( int iArg
): i( iArg
) {
108 static void CleanUp( void* obj
, void* data
) {
111 my_assert( self
->i
== (int) (long) data
);}
113 my_assert( nFreed
>= .8 * nAllocated
);}
117 static int nAllocated
;};
120 int D::nAllocated
= 0;
123 class E
: public gc_cleanup
{public:
124 /* A collectable class with clean-up for use by F. */
132 static int nAllocated
;};
135 int E::nAllocated
= 0;
138 class F
: public E
{public:
139 /* A collectable class with clean-up, a base with clean-up, and a
140 member with clean-up. */
147 my_assert( nFreed
>= .8 * nAllocated
);
148 my_assert( 2 * nFreed
== E::nFreed
);}
152 static int nAllocated
;};
155 int F::nAllocated
= 0;
158 long Disguise( void* p
) {
161 void* Undisguise( long i
) {
166 int APIENTRY
WinMain(
167 HINSTANCE instance
, HINSTANCE prev
, LPSTR cmd
, int cmdShow
)
172 for (argc
= 1; argc
< sizeof( argv
) / sizeof( argv
[ 0 ] ); argc
++) {
173 argv
[ argc
] = strtok( argc
== 1 ? cmd
: 0, " \t" );
174 if (0 == argv
[ argc
]) break;}
180 int main( int argc
, char* argv
[] ) {
184 # if defined(MACOS) // MacOS
185 char* argv_
[] = {"test_cpp", "10"}; // doesn't
186 argv
= argv_
; // have a
187 argc
= sizeof(argv_
)/sizeof(argv_
[0]); // commandline
190 # if !defined(__GNUC__) && !defined(MACOS)
191 int *x
= (int *)alloc::allocate(sizeof(int));
196 if (argc
!= 2 || (0 >= (n
= atoi( argv
[ 1 ] )))) {
197 GC_printf0( "usage: test_cpp number-of-iterations\n" );
200 for (iters
= 1; iters
<= n
; iters
++) {
201 GC_printf1( "Starting iteration %d\n", iters
);
203 /* Allocate some uncollectable As and disguise their pointers.
204 Later we'll check to see if the objects are still there. We're
205 checking to make sure these objects really are uncollectable. */
208 for (i
= 0; i
< 1000; i
++) {
209 as
[ i
] = Disguise( new (NoGC
) A( i
) );
210 bs
[ i
] = Disguise( new (NoGC
) B( i
) );}
212 /* Allocate a fair number of finalizable Cs, Ds, and Fs.
213 Later we'll check to make sure they've gone away. */
214 for (i
= 0; i
< 1000; i
++) {
216 C
c1( 2 ); /* stack allocation should work too */
217 D
* d
= ::new (GC
, D::CleanUp
, (void*) i
) D( i
);
219 if (0 == i
% 10) delete c
;}
221 /* Allocate a very large number of collectable As and Bs and
222 drop the references to them immediately, forcing many
224 for (i
= 0; i
< 1000000; i
++) {
225 A
* a
= new (GC
) A( i
);
232 # ifdef FINALIZE_ON_DEMAND
233 GC_invoke_finalizers();
237 /* Make sure the uncollectable As and Bs are still there. */
238 for (i
= 0; i
< 1000; i
++) {
239 A
* a
= (A
*) Undisguise( as
[ i
] );
240 B
* b
= (B
*) Undisguise( bs
[ i
] );
247 # ifdef FINALIZE_ON_DEMAND
248 GC_invoke_finalizers();
253 /* Make sure most of the finalizable Cs, Ds, and Fs have
259 # if !defined(__GNUC__) && !defined(MACOS)
260 my_assert (29 == x
[3]);
262 GC_printf0( "The test appears to have succeeded.\n" );