Annotation of OpenXM_contrib2/asir2000/gc/tests/test_cpp.cc, Revision 1.1
1.1 ! noro 1: /****************************************************************************
! 2: Copyright (c) 1994 by Xerox Corporation. All rights reserved.
! 3:
! 4: THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
! 5: OR IMPLIED. ANY USE IS AT YOUR OWN RISK.
! 6:
! 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
! 15:
! 16: usage: test_cpp number-of-iterations
! 17:
! 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
! 20: collector.
! 21:
! 22: A recommended value for number-of-iterations is 10, which will take a
! 23: few minutes to complete.
! 24:
! 25: ***************************************************************************/
! 26:
! 27: #include "gc_cpp.h"
! 28: #include <stdio.h>
! 29: #include <stdlib.h>
! 30: #include <string.h>
! 31: #define USE_STD_ALLOCATOR
! 32: #ifdef USE_STD_ALLOCATOR
! 33: # include "gc_allocator.h"
! 34: #elif __GNUC__
! 35: # include "new_gc_alloc.h"
! 36: #else
! 37: # include "gc_alloc.h"
! 38: #endif
! 39: extern "C" {
! 40: #include "private/gc_priv.h"
! 41: }
! 42: #ifdef MSWIN32
! 43: # include <windows.h>
! 44: #endif
! 45: #ifdef GC_NAME_CONFLICT
! 46: # define USE_GC UseGC
! 47: struct foo * GC;
! 48: #else
! 49: # define USE_GC GC
! 50: #endif
! 51:
! 52:
! 53: #define my_assert( e ) \
! 54: if (! (e)) { \
! 55: GC_printf1( "Assertion failure in " __FILE__ ", line %d: " #e "\n", \
! 56: __LINE__ ); \
! 57: exit( 1 ); }
! 58:
! 59:
! 60: class A {public:
! 61: /* An uncollectable class. */
! 62:
! 63: A( int iArg ): i( iArg ) {}
! 64: void Test( int iArg ) {
! 65: my_assert( i == iArg );}
! 66: int i;};
! 67:
! 68:
! 69: class B: public gc, public A {public:
! 70: /* A collectable class. */
! 71:
! 72: B( int j ): A( j ) {}
! 73: ~B() {
! 74: my_assert( deleting );}
! 75: static void Deleting( int on ) {
! 76: deleting = on;}
! 77: static int deleting;};
! 78:
! 79: int B::deleting = 0;
! 80:
! 81:
! 82: class C: public gc_cleanup, public A {public:
! 83: /* A collectable class with cleanup and virtual multiple inheritance. */
! 84:
! 85: C( int levelArg ): A( levelArg ), level( levelArg ) {
! 86: nAllocated++;
! 87: if (level > 0) {
! 88: left = new C( level - 1 );
! 89: right = new C( level - 1 );}
! 90: else {
! 91: left = right = 0;}}
! 92: ~C() {
! 93: this->A::Test( level );
! 94: nFreed++;
! 95: my_assert( level == 0 ?
! 96: left == 0 && right == 0 :
! 97: level == left->level + 1 && level == right->level + 1 );
! 98: left = right = 0;
! 99: level = -123456;}
! 100: static void Test() {
! 101: my_assert( nFreed <= nAllocated && nFreed >= .8 * nAllocated );}
! 102:
! 103: static int nFreed;
! 104: static int nAllocated;
! 105: int level;
! 106: C* left;
! 107: C* right;};
! 108:
! 109: int C::nFreed = 0;
! 110: int C::nAllocated = 0;
! 111:
! 112:
! 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. */
! 116:
! 117: D( int iArg ): i( iArg ) {
! 118: nAllocated++;}
! 119: static void CleanUp( void* obj, void* data ) {
! 120: D* self = (D*) obj;
! 121: nFreed++;
! 122: my_assert( self->i == (int) (long) data );}
! 123: static void Test() {
! 124: my_assert( nFreed >= .8 * nAllocated );}
! 125:
! 126: int i;
! 127: static int nFreed;
! 128: static int nAllocated;};
! 129:
! 130: int D::nFreed = 0;
! 131: int D::nAllocated = 0;
! 132:
! 133:
! 134: class E: public gc_cleanup {public:
! 135: /* A collectable class with clean-up for use by F. */
! 136:
! 137: E() {
! 138: nAllocated++;}
! 139: ~E() {
! 140: nFreed++;}
! 141:
! 142: static int nFreed;
! 143: static int nAllocated;};
! 144:
! 145: int E::nFreed = 0;
! 146: int E::nAllocated = 0;
! 147:
! 148:
! 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. */
! 152:
! 153: F() {
! 154: nAllocated++;}
! 155: ~F() {
! 156: nFreed++;}
! 157: static void Test() {
! 158: my_assert( nFreed >= .8 * nAllocated );
! 159: my_assert( 2 * nFreed == E::nFreed );}
! 160:
! 161: E e;
! 162: static int nFreed;
! 163: static int nAllocated;};
! 164:
! 165: int F::nFreed = 0;
! 166: int F::nAllocated = 0;
! 167:
! 168:
! 169: long Disguise( void* p ) {
! 170: return ~ (long) p;}
! 171:
! 172: void* Undisguise( long i ) {
! 173: return (void*) ~ i;}
! 174:
! 175:
! 176: #ifdef MSWIN32
! 177: int APIENTRY WinMain(
! 178: HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int cmdShow )
! 179: {
! 180: int argc;
! 181: char* argv[ 3 ];
! 182:
! 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;}
! 186:
! 187: #else
! 188: # ifdef MACOS
! 189: int main() {
! 190: # else
! 191: int main( int argc, char* argv[] ) {
! 192: # endif
! 193: #endif
! 194:
! 195: # if defined(MACOS) // MacOS
! 196: char* argv_[] = {"test_cpp", "10"}; // doesn't
! 197: argv = argv_; // have a
! 198: argc = sizeof(argv_)/sizeof(argv_[0]); // commandline
! 199: # endif
! 200: int i, iters, n;
! 201: # ifdef USE_STD_ALLOCATOR
! 202: int *x = gc_allocator<int>().allocate(1);
! 203: int **xptr = traceable_allocator<int *>().allocate(1);
! 204: # else
! 205: # ifdef __GNUC__
! 206: int *x = (int *)gc_alloc::allocate(sizeof(int));
! 207: # else
! 208: int *x = (int *)alloc::allocate(sizeof(int));
! 209: # endif
! 210: # endif
! 211: *x = 29;
! 212: # ifdef USE_STD_ALLOCATOR
! 213: *xptr = x;
! 214: x = 0;
! 215: # endif
! 216: if (argc != 2 || (0 >= (n = atoi( argv[ 1 ] )))) {
! 217: GC_printf0( "usage: test_cpp number-of-iterations\n" );
! 218: exit( 1 );}
! 219:
! 220: for (iters = 1; iters <= n; iters++) {
! 221: GC_printf1( "Starting iteration %d\n", iters );
! 222:
! 223: /* Allocate some uncollectable As and disguise their pointers.
! 224: Later we'll check to see if the objects are still there. We're
! 225: checking to make sure these objects really are uncollectable. */
! 226: long as[ 1000 ];
! 227: long bs[ 1000 ];
! 228: for (i = 0; i < 1000; i++) {
! 229: as[ i ] = Disguise( new (NoGC) A( i ) );
! 230: bs[ i ] = Disguise( new (NoGC) B( i ) );}
! 231:
! 232: /* Allocate a fair number of finalizable Cs, Ds, and Fs.
! 233: Later we'll check to make sure they've gone away. */
! 234: for (i = 0; i < 1000; i++) {
! 235: C* c = new C( 2 );
! 236: C c1( 2 ); /* stack allocation should work too */
! 237: D* d = ::new (USE_GC, D::CleanUp, (void*)(long)i) D( i );
! 238: F* f = new F;
! 239: if (0 == i % 10) delete c;}
! 240:
! 241: /* Allocate a very large number of collectable As and Bs and
! 242: drop the references to them immediately, forcing many
! 243: collections. */
! 244: for (i = 0; i < 1000000; i++) {
! 245: A* a = new (USE_GC) A( i );
! 246: B* b = new B( i );
! 247: b = new (USE_GC) B( i );
! 248: if (0 == i % 10) {
! 249: B::Deleting( 1 );
! 250: delete b;
! 251: B::Deleting( 0 );}
! 252: # ifdef FINALIZE_ON_DEMAND
! 253: GC_invoke_finalizers();
! 254: # endif
! 255: }
! 256:
! 257: /* Make sure the uncollectable As and Bs are still there. */
! 258: for (i = 0; i < 1000; i++) {
! 259: A* a = (A*) Undisguise( as[ i ] );
! 260: B* b = (B*) Undisguise( bs[ i ] );
! 261: a->Test( i );
! 262: delete a;
! 263: b->Test( i );
! 264: B::Deleting( 1 );
! 265: delete b;
! 266: B::Deleting( 0 );
! 267: # ifdef FINALIZE_ON_DEMAND
! 268: GC_invoke_finalizers();
! 269: # endif
! 270:
! 271: }
! 272:
! 273: /* Make sure most of the finalizable Cs, Ds, and Fs have
! 274: gone away. */
! 275: C::Test();
! 276: D::Test();
! 277: F::Test();}
! 278:
! 279: # ifdef USE_STD_ALLOCATOR
! 280: x = *xptr;
! 281: # endif
! 282: my_assert (29 == x[0]);
! 283: GC_printf0( "The test appears to have succeeded.\n" );
! 284: return( 0 );}
! 285:
! 286:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>