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"
40 #ifdef GC_NAME_CONFLICT
48 #define my_assert( e ) \
50 GC_printf1( "Assertion failure in " __FILE__ ", line %d: " #e "\n", \
56 /* An uncollectable class. */
58 A( int iArg
): i( iArg
) {}
59 void Test( int iArg
) {
60 my_assert( i
== iArg
);}
64 class B
: public gc
, public A
{public:
65 /* A collectable class. */
69 my_assert( deleting
);}
70 static void Deleting( int on
) {
72 static int deleting
;};
77 class C
: public gc_cleanup
, public A
{public:
78 /* A collectable class with cleanup and virtual multiple inheritance. */
80 C( int levelArg
): A( levelArg
), level( levelArg
) {
83 left
= new C( level
- 1 );
84 right
= new C( level
- 1 );}
88 this->A::Test( level
);
90 my_assert( level
== 0 ?
91 left
== 0 && right
== 0 :
92 level
== left
->level
+ 1 && level
== right
->level
+ 1 );
96 my_assert( nFreed
<= nAllocated
&& nFreed
>= .8 * nAllocated
);}
99 static int nAllocated
;
105 int C::nAllocated
= 0;
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. */
112 D( int iArg
): i( iArg
) {
114 static void CleanUp( void* obj
, void* data
) {
117 my_assert( self
->i
== (int) (long) data
);}
119 my_assert( nFreed
>= .8 * nAllocated
);}
123 static int nAllocated
;};
126 int D::nAllocated
= 0;
129 class E
: public gc_cleanup
{public:
130 /* A collectable class with clean-up for use by F. */
138 static int nAllocated
;};
141 int E::nAllocated
= 0;
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. */
153 my_assert( nFreed
>= .8 * nAllocated
);
154 my_assert( 2 * nFreed
== E::nFreed
);}
158 static int nAllocated
;};
161 int F::nAllocated
= 0;
164 long Disguise( void* p
) {
167 void* Undisguise( long i
) {
172 int APIENTRY
WinMain(
173 HINSTANCE instance
, HINSTANCE prev
, LPSTR cmd
, int cmdShow
)
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;}
186 int main( int argc
, char* argv
[] ) {
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
196 # if !defined(__GNUC__) && !defined(MACOS)
197 int *x
= (int *)alloc::allocate(sizeof(int));
202 if (argc
!= 2 || (0 >= (n
= atoi( argv
[ 1 ] )))) {
203 GC_printf0( "usage: test_cpp number-of-iterations\n" );
206 for (iters
= 1; iters
<= n
; iters
++) {
207 GC_printf1( "Starting iteration %d\n", iters
);
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. */
214 for (i
= 0; i
< 1000; i
++) {
215 as
[ i
] = Disguise( new (NoGC
) A( i
) );
216 bs
[ i
] = Disguise( new (NoGC
) B( i
) );}
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
++) {
222 C
c1( 2 ); /* stack allocation should work too */
223 D
* d
= ::new (USE_GC
, D::CleanUp
, (void*) i
) D( i
);
225 if (0 == i
% 10) delete c
;}
227 /* Allocate a very large number of collectable As and Bs and
228 drop the references to them immediately, forcing many
230 for (i
= 0; i
< 1000000; i
++) {
231 A
* a
= new (USE_GC
) A( i
);
233 b
= new (USE_GC
) B( i
);
238 # ifdef FINALIZE_ON_DEMAND
239 GC_invoke_finalizers();
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
] );
253 # ifdef FINALIZE_ON_DEMAND
254 GC_invoke_finalizers();
259 /* Make sure most of the finalizable Cs, Ds, and Fs have
265 # if !defined(__GNUC__) && !defined(MACOS)
266 my_assert (29 == x
[3]);
268 GC_printf0( "The test appears to have succeeded.\n" );