From 83e0a2cefcbc88bdbc19bcf98cc3a1f1cf307d63 Mon Sep 17 00:00:00 2001 From: ivmai Date: Wed, 20 Apr 2011 21:25:18 +0000 Subject: [PATCH] 2011-04-20 Ivan Maidanski * misc.c (GC_parse_mem_size_arg): Allow 'k', 'M', 'G' suffixes in heap size specifier; return 0 if not a valid one. * include/gc_cpp.h: Explicitly define inline one-argument delete operator for Cygwin (as a workaround). * include/gc_cpp.h: Reformat the code. * tests/test_cpp.cc: Ditto. * tests/test_cpp.cc (main): Suppress compiler warnings about "assigned value is unused". --- ChangeLog | 11 +++++++ include/gc_cpp.h | 76 ++++++++++++++++++++++++----------------------- misc.c | 30 +++++++++++++++++-- tests/test_cpp.cc | 58 ++++++++++++++++++++---------------- 4 files changed, 110 insertions(+), 65 deletions(-) diff --git a/ChangeLog b/ChangeLog index ffc1aa2c..5dda048c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2011-04-20 Ivan Maidanski + + * misc.c (GC_parse_mem_size_arg): Allow 'k', 'M', 'G' suffixes in + heap size specifier; return 0 if not a valid one. + * include/gc_cpp.h: Explicitly define inline one-argument delete + operator for Cygwin (as a workaround). + * include/gc_cpp.h: Reformat the code. + * tests/test_cpp.cc: Ditto. + * tests/test_cpp.cc (main): Suppress compiler warnings about + "assigned value is unused". + 2011-04-19 Ivan Maidanski * misc.c (GC_parse_mem_size_arg): New function. diff --git a/include/gc_cpp.h b/include/gc_cpp.h index ff77a1fd..302fdc2d 100644 --- a/include/gc_cpp.h +++ b/include/gc_cpp.h @@ -244,9 +244,9 @@ inline void* operator new( classes derived from "gc_cleanup" or containing members derived from "gc_cleanup". */ -# ifdef GC_PLACEMENT_DELETE - inline void operator delete( void*, GCPlacement, GCCleanUpFunc, void * ); -# endif +#ifdef GC_PLACEMENT_DELETE + inline void operator delete( void*, GCPlacement, GCCleanUpFunc, void * ); +#endif #ifdef _MSC_VER /** This ensures that the system default operator new[] doesn't get @@ -255,27 +255,26 @@ inline void* operator new( * There seems to be no way to redirect new in this environment without * including this everywhere. */ -#if _MSC_VER > 1020 - void *operator new[]( size_t size ); +# if _MSC_VER > 1020 + void *operator new[]( size_t size ); - void operator delete[](void* obj); -#endif + void operator delete[](void* obj); +# endif - void* operator new( size_t size); + void* operator new(size_t size); - void operator delete(void* obj); + void operator delete(void* obj); - // This new operator is used by VC++ in case of Debug builds ! - void* operator new( size_t size, + // This new operator is used by VC++ in case of Debug builds ! + void* operator new( size_t size, int ,//nBlockUse, const char * szFileName, int nLine ); #endif /* _MSC_VER */ - #ifdef GC_OPERATOR_NEW_ARRAY -inline void* operator new[]( + inline void* operator new[]( size_t size, GCPlacement gcp, GCCleanUpFunc cleanup = 0, @@ -317,30 +316,26 @@ inline void gc::operator delete( void* obj ) { #endif #ifdef GC_OPERATOR_NEW_ARRAY - -inline void* gc::operator new[]( size_t size ) { + inline void* gc::operator new[]( size_t size ) { return gc::operator new( size );} -inline void* gc::operator new[]( size_t size, GCPlacement gcp ) { + inline void* gc::operator new[]( size_t size, GCPlacement gcp ) { return gc::operator new( size, gcp );} -inline void* gc::operator new[]( size_t size, void *p ) { + inline void* gc::operator new[]( size_t size, void *p ) { return p;} -inline void gc::operator delete[]( void* obj ) { + inline void gc::operator delete[]( void* obj ) { gc::operator delete( obj );} -#ifdef GC_PLACEMENT_DELETE - inline void gc::operator delete[]( void*, void* ) {} - - inline void gc::operator delete[]( void* p, GCPlacement gcp ) { - gc::operator delete(p); } - -#endif +# ifdef GC_PLACEMENT_DELETE + inline void gc::operator delete[]( void*, void* ) {} + inline void gc::operator delete[]( void* p, GCPlacement gcp ) { + gc::operator delete(p); } +# endif #endif /* GC_OPERATOR_NEW_ARRAY */ - inline gc_cleanup::~gc_cleanup() { GC_register_finalizer_ignore_self( GC_base(this), 0, 0, 0, 0 );} @@ -354,7 +349,7 @@ inline gc_cleanup::gc_cleanup() { if (0 != base) { // Don't call the debug version, since this is a real base address. GC_register_finalizer_ignore_self( - base, (GC_finalization_proc)cleanup, (void*) ((char*) this - (char*) base), + base, (GC_finalization_proc)cleanup, (void*)((char*)this - (char*)base), &oldProc, &oldData ); if (0 != oldProc) { GC_register_finalizer_ignore_self( base, oldProc, oldData, 0, 0 );}}} @@ -378,27 +373,34 @@ inline void* operator new( obj = GC_MALLOC_UNCOLLECTABLE( size );}; return obj;} -# ifdef GC_PLACEMENT_DELETE -inline void operator delete ( +#ifdef GC_PLACEMENT_DELETE + inline void operator delete ( void *p, GCPlacement gcp, GCCleanUpFunc cleanup, void* clientData ) -{ + { GC_FREE(p); -} -# endif + } +#endif /* GC_PLACEMENT_DELETE */ #ifdef GC_OPERATOR_NEW_ARRAY - -inline void* operator new[]( + inline void* operator new[]( size_t size, GCPlacement gcp, GCCleanUpFunc cleanup, void* clientData ) -{ - return ::operator new( size, gcp, cleanup, clientData );} - + { + return ::operator new( size, gcp, cleanup, clientData ); + } #endif /* GC_OPERATOR_NEW_ARRAY */ +#if defined(__CYGWIN__) +# include // for delete throw() + inline void operator delete(void *p) + { + GC_FREE(p); + } +#endif + #endif /* GC_CPP_H */ diff --git a/misc.c b/misc.c index 59bdd127..ee6fa963 100644 --- a/misc.c +++ b/misc.c @@ -636,8 +636,34 @@ STATIC void GC_exit_check(void) STATIC word GC_parse_mem_size_arg(const char *str) { char *endptr; - word result = (word)STRTOULL(str, &endptr, 10); - /* TODO: allow 'k', 'M', 'G' suffix */ + word result = 0; /* bad value */ + char ch; + + if (*str != '\0') { + result = (word)STRTOULL(str, &endptr, 10); + ch = *endptr; + if (ch != '\0') { + if (*(endptr + 1) != '\0') + return 0; + /* Allow k, M or G suffix. */ + switch (ch) { + case 'K': + case 'k': + result <<= 10; + break; + case 'M': + case 'm': + result <<= 20; + break; + case 'G': + case 'g': + result <<= 30; + break; + default: + result = 0; + } + } + } return result; } diff --git a/tests/test_cpp.cc b/tests/test_cpp.cc index 94a8ca37..ce683af4 100644 --- a/tests/test_cpp.cc +++ b/tests/test_cpp.cc @@ -27,12 +27,17 @@ few minutes to complete. #ifdef HAVE_CONFIG_H # include "private/config.h" #endif + #undef GC_BUILD + #include "gc_cpp.h" + #include #include #include + #define USE_STD_ALLOCATOR + #ifdef USE_STD_ALLOCATOR # include "gc_allocator.h" #elif __GNUC__ @@ -40,6 +45,7 @@ few minutes to complete. #else # include "gc_alloc.h" #endif + extern "C" { # include "private/gcconfig.h" GC_API void GC_printf(const char *format, ...); @@ -47,17 +53,18 @@ extern "C" { /* Don't include gc_priv.h, since that may include Windows system */ /* header files that don't take kindly to this context. */ } + #ifdef MSWIN32 -# include +# include #endif + #ifdef GC_NAME_CONFLICT -# define USE_GC UseGC - struct foo * GC; +# define USE_GC UseGC + struct foo * GC; #else -# define USE_GC GC +# define USE_GC GC #endif - #define my_assert( e ) \ if (! (e)) { \ GC_printf( "Assertion failure in " __FILE__ ", line %d: " #e "\n", \ @@ -180,7 +187,6 @@ GC_word Disguise( void* p ) { void* Undisguise( GC_word i ) { return (void*) ~ i;} - #ifdef MSWIN32 int APIENTRY WinMain( HINSTANCE instance, HINSTANCE prev, LPSTR cmd, int cmdShow ) @@ -188,29 +194,25 @@ int APIENTRY WinMain( int argc; char* argv[ 3 ]; - for (argc = 1; argc < sizeof( argv ) / sizeof( argv[ 0 ] ); argc++) { + for (argc = 1; argc < (int)(sizeof(argv) / sizeof(argv[0])); argc++) { argv[ argc ] = strtok( argc == 1 ? cmd : 0, " \t" ); if (0 == argv[ argc ]) break;} - +#elif defined(MACOS) + int main() { + char* argv_[] = {"test_cpp", "10"}; // MacOS doesn't have a commandline + argv = argv_; + argc = sizeof(argv_)/sizeof(argv_[0]); #else -# ifdef MACOS - int main() { -# else - int main( int argc, char* argv[] ) { -# endif + int main( int argc, char* argv[] ) { #endif - GC_INIT(); + GC_INIT(); -# if defined(MACOS) // MacOS - char* argv_[] = {"test_cpp", "10"}; // doesn't - argv = argv_; // have a - argc = sizeof(argv_)/sizeof(argv_[0]); // commandline -# endif int i, iters, n; # ifdef USE_STD_ALLOCATOR int *x = gc_allocator().allocate(1); - int *xio = gc_allocator_ignore_off_page().allocate(1); + int *xio; + xio = gc_allocator_ignore_off_page().allocate(1); int **xptr = traceable_allocator().allocate(1); # else # ifdef __GNUC__ @@ -237,7 +239,7 @@ int APIENTRY WinMain( GC_word as[ 1000 ]; GC_word bs[ 1000 ]; for (i = 0; i < 1000; i++) { - as[ i ] = Disguise( new (NoGC) A( i ) ); + as[ i ] = Disguise( new (NoGC ) A( i ) ); bs[ i ] = Disguise( new (NoGC) B( i ) );} /* Allocate a fair number of finalizable Cs, Ds, and Fs. @@ -245,15 +247,18 @@ int APIENTRY WinMain( for (i = 0; i < 1000; i++) { C* c = new C( 2 ); C c1( 2 ); /* stack allocation should work too */ - D* d = ::new (USE_GC, D::CleanUp, (void*)(GC_word)i) D( i ); - F* f = new F; + D* d; + F* f; + d = ::new (USE_GC, D::CleanUp, (void*)(GC_word)i) D( i ); + f = new F; if (0 == i % 10) delete c;} /* Allocate a very large number of collectable As and Bs and drop the references to them immediately, forcing many collections. */ for (i = 0; i < 1000000; i++) { - A* a = new (USE_GC) A( i ); + A* a; + a = new (USE_GC) A( i ); B* b = new B( i ); b = new (USE_GC) B( i ); if (0 == i % 10) { @@ -278,7 +283,6 @@ int APIENTRY WinMain( # ifdef FINALIZE_ON_DEMAND GC_invoke_finalizers(); # endif - } /* Make sure most of the finalizable Cs, Ds, and Fs have @@ -292,4 +296,6 @@ int APIENTRY WinMain( # endif my_assert (29 == x[0]); GC_printf( "The test appears to have succeeded.\n" ); - return( 0 );} + return( 0 ); +} + -- 2.50.1