Annotation of OpenXM_contrib/gc/test_cpp.cc, Revision 1.1
1.1 ! maekawa 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:
! 41:
! 42: #define my_assert( e ) \
! 43: if (! (e)) { \
! 44: GC_printf1( "Assertion failure in " __FILE__ ", line %d: " #e "\n", \
! 45: __LINE__ ); \
! 46: exit( 1 ); }
! 47:
! 48:
! 49: class A {public:
! 50: /* An uncollectable class. */
! 51:
! 52: A( int iArg ): i( iArg ) {}
! 53: void Test( int iArg ) {
! 54: my_assert( i == iArg );}
! 55: int i;};
! 56:
! 57:
! 58: class B: public gc, public A {public:
! 59: /* A collectable class. */
! 60:
! 61: B( int j ): A( j ) {}
! 62: ~B() {
! 63: my_assert( deleting );}
! 64: static void Deleting( int on ) {
! 65: deleting = on;}
! 66: static int deleting;};
! 67:
! 68: int B::deleting = 0;
! 69:
! 70:
! 71: class C: public gc_cleanup, public A {public:
! 72: /* A collectable class with cleanup and virtual multiple inheritance. */
! 73:
! 74: C( int levelArg ): A( levelArg ), level( levelArg ) {
! 75: nAllocated++;
! 76: if (level > 0) {
! 77: left = new C( level - 1 );
! 78: right = new C( level - 1 );}
! 79: else {
! 80: left = right = 0;}}
! 81: ~C() {
! 82: this->A::Test( level );
! 83: nFreed++;
! 84: my_assert( level == 0 ?
! 85: left == 0 && right == 0 :
! 86: level == left->level + 1 && level == right->level + 1 );
! 87: left = right = 0;
! 88: level = -123456;}
! 89: static void Test() {
! 90: my_assert( nFreed <= nAllocated && nFreed >= .8 * nAllocated );}
! 91:
! 92: static int nFreed;
! 93: static int nAllocated;
! 94: int level;
! 95: C* left;
! 96: C* right;};
! 97:
! 98: int C::nFreed = 0;
! 99: int C::nAllocated = 0;
! 100:
! 101:
! 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. */
! 105:
! 106: D( int iArg ): i( iArg ) {
! 107: nAllocated++;}
! 108: static void CleanUp( void* obj, void* data ) {
! 109: D* self = (D*) obj;
! 110: nFreed++;
! 111: my_assert( self->i == (int) (long) data );}
! 112: static void Test() {
! 113: my_assert( nFreed >= .8 * nAllocated );}
! 114:
! 115: int i;
! 116: static int nFreed;
! 117: static int nAllocated;};
! 118:
! 119: int D::nFreed = 0;
! 120: int D::nAllocated = 0;
! 121:
! 122:
! 123: class E: public gc_cleanup {public:
! 124: /* A collectable class with clean-up for use by F. */
! 125:
! 126: E() {
! 127: nAllocated++;}
! 128: ~E() {
! 129: nFreed++;}
! 130:
! 131: static int nFreed;
! 132: static int nAllocated;};
! 133:
! 134: int E::nFreed = 0;
! 135: int E::nAllocated = 0;
! 136:
! 137:
! 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. */
! 141:
! 142: F() {
! 143: nAllocated++;}
! 144: ~F() {
! 145: nFreed++;}
! 146: static void Test() {
! 147: my_assert( nFreed >= .8 * nAllocated );
! 148: my_assert( 2 * nFreed == E::nFreed );}
! 149:
! 150: E e;
! 151: static int nFreed;
! 152: static int nAllocated;};
! 153:
! 154: int F::nFreed = 0;
! 155: int F::nAllocated = 0;
! 156:
! 157:
! 158: long Disguise( void* p ) {
! 159: return ~ (long) p;}
! 160:
! 161: void* Undisguise( long i ) {
! 162: return (void*) ~ i;}
! 163:
! 164:
! 165: #ifdef MSWIN32
! 166: int APIENTRY WinMain(
! 167: HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int cmdShow )
! 168: {
! 169: int argc;
! 170: char* argv[ 3 ];
! 171:
! 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;}
! 175:
! 176: #else
! 177: # ifdef MACOS
! 178: int main() {
! 179: # else
! 180: int main( int argc, char* argv[] ) {
! 181: # endif
! 182: #endif
! 183:
! 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
! 188: # endif
! 189: int i, iters, n;
! 190: # if !defined(__GNUC__) && !defined(MACOS)
! 191: int *x = (int *)alloc::allocate(sizeof(int));
! 192:
! 193: *x = 29;
! 194: x -= 3;
! 195: # endif
! 196: if (argc != 2 || (0 >= (n = atoi( argv[ 1 ] )))) {
! 197: GC_printf0( "usage: test_cpp number-of-iterations\n" );
! 198: exit( 1 );}
! 199:
! 200: for (iters = 1; iters <= n; iters++) {
! 201: GC_printf1( "Starting iteration %d\n", iters );
! 202:
! 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. */
! 206: long as[ 1000 ];
! 207: long bs[ 1000 ];
! 208: for (i = 0; i < 1000; i++) {
! 209: as[ i ] = Disguise( new (NoGC) A( i ) );
! 210: bs[ i ] = Disguise( new (NoGC) B( i ) );}
! 211:
! 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++) {
! 215: C* c = new C( 2 );
! 216: C c1( 2 ); /* stack allocation should work too */
! 217: D* d = ::new (GC, D::CleanUp, (void*) i) D( i );
! 218: F* f = new F;
! 219: if (0 == i % 10) delete c;}
! 220:
! 221: /* Allocate a very large number of collectable As and Bs and
! 222: drop the references to them immediately, forcing many
! 223: collections. */
! 224: for (i = 0; i < 1000000; i++) {
! 225: A* a = new (GC) A( i );
! 226: B* b = new B( i );
! 227: b = new (GC) B( i );
! 228: if (0 == i % 10) {
! 229: B::Deleting( 1 );
! 230: delete b;
! 231: B::Deleting( 0 );}
! 232: # ifdef FINALIZE_ON_DEMAND
! 233: GC_invoke_finalizers();
! 234: # endif
! 235: }
! 236:
! 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 ] );
! 241: a->Test( i );
! 242: delete a;
! 243: b->Test( i );
! 244: B::Deleting( 1 );
! 245: delete b;
! 246: B::Deleting( 0 );
! 247: # ifdef FINALIZE_ON_DEMAND
! 248: GC_invoke_finalizers();
! 249: # endif
! 250:
! 251: }
! 252:
! 253: /* Make sure most of the finalizable Cs, Ds, and Fs have
! 254: gone away. */
! 255: C::Test();
! 256: D::Test();
! 257: F::Test();}
! 258:
! 259: # if !defined(__GNUC__) && !defined(MACOS)
! 260: my_assert (29 == x[3]);
! 261: # endif
! 262: GC_printf0( "The test appears to have succeeded.\n" );
! 263: return( 0 );}
! 264:
! 265:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>