]> gcc.gnu.org Git - gcc.git/blame - boehm-gc/test_cpp.cc
Daily bump.
[gcc.git] / boehm-gc / test_cpp.cc
CommitLineData
73ffefd0
TT
1/****************************************************************************
2Copyright (c) 1994 by Xerox Corporation. All rights reserved.
3
4THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
5OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
6
7Permission is hereby granted to use or copy this program for any
8purpose, provided the above notices are retained on all copies.
9Permission to modify the code and to distribute modified code is
10granted, provided the above notices are retained, and a notice that
11the code was modified is included with the above copyright notice.
12****************************************************************************
13Last 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
16usage: test_cpp number-of-iterations
17
18This program tries to test the specific C++ functionality provided by
19gc_c++.h that isn't tested by the more general test routines of the
20collector.
21
22A recommended value for number-of-iterations is 10, which will take a
23few 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
34extern "C" {
35#include "gc_priv.h"
36}
37#ifdef MSWIN32
38# include <windows.h>
39#endif
93002327
BM
40#ifdef GC_NAME_CONFLICT
41# define USE_GC UseGC
42 struct foo * GC;
43#else
44# define USE_GC GC
45#endif
73ffefd0
TT
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
55class 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
64class 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
74int B::deleting = 0;
75
76
77class 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
104int C::nFreed = 0;
105int C::nAllocated = 0;
106
107
108class 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
125int D::nFreed = 0;
126int D::nAllocated = 0;
127
128
129class 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
140int E::nFreed = 0;
141int E::nAllocated = 0;
142
143
144class 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
160int F::nFreed = 0;
161int F::nAllocated = 0;
162
163
164long Disguise( void* p ) {
165 return ~ (long) p;}
166
167void* Undisguise( long i ) {
168 return (void*) ~ i;}
169
170
171#ifdef MSWIN32
172int 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 */
93002327 223 D* d = ::new (USE_GC, D::CleanUp, (void*) i) D( i );
73ffefd0
TT
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++) {
93002327 231 A* a = new (USE_GC) A( i );
73ffefd0 232 B* b = new B( i );
93002327 233 b = new (USE_GC) B( i );
73ffefd0
TT
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
This page took 0.158777 seconds and 5 git commands to generate.