Annotation of OpenXM_contrib2/asir2000/gc5.3/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: #ifndef __GNUC__
! 32: # include "gc_alloc.h"
! 33: #endif
! 34: extern "C" {
! 35: #include "gc_priv.h"
! 36: }
! 37: #ifdef MSWIN32
! 38: # include <windows.h>
! 39: #endif
! 40: #ifdef GC_NAME_CONFLICT
! 41: # define USE_GC UseGC
! 42: struct foo * GC;
! 43: #else
! 44: # define USE_GC GC
! 45: #endif
! 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:
! 55: class 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:
! 64: class 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:
! 74: int B::deleting = 0;
! 75:
! 76:
! 77: class 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:
! 104: int C::nFreed = 0;
! 105: int C::nAllocated = 0;
! 106:
! 107:
! 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. */
! 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:
! 125: int D::nFreed = 0;
! 126: int D::nAllocated = 0;
! 127:
! 128:
! 129: class 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:
! 140: int E::nFreed = 0;
! 141: int E::nAllocated = 0;
! 142:
! 143:
! 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. */
! 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:
! 160: int F::nFreed = 0;
! 161: int F::nAllocated = 0;
! 162:
! 163:
! 164: long Disguise( void* p ) {
! 165: return ~ (long) p;}
! 166:
! 167: void* Undisguise( long i ) {
! 168: return (void*) ~ i;}
! 169:
! 170:
! 171: #ifdef MSWIN32
! 172: int 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 */
! 223: D* d = ::new (USE_GC, D::CleanUp, (void*) i) D( i );
! 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++) {
! 231: A* a = new (USE_GC) A( i );
! 232: B* b = new B( i );
! 233: b = new (USE_GC) B( i );
! 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:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>