2011-04-20 Ivan Maidanski <ivmai@mail.ru>

* 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".
This commit is contained in:
ivmai
2011-04-20 21:25:18 +00:00
committed by Ivan Maidanski
parent af1726c615
commit 83e0a2cefc
4 changed files with 112 additions and 67 deletions
+11
View File
@@ -1,3 +1,14 @@
2011-04-20 Ivan Maidanski <ivmai@mail.ru>
* 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 <ivmai@mail.ru>
* misc.c (GC_parse_mem_size_arg): New function.
+39 -37
View File
@@ -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 <new> // for delete throw()
inline void operator delete(void *p)
{
GC_FREE(p);
}
#endif
#endif /* GC_CPP_H */
+28 -2
View File
@@ -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;
}
+34 -28
View File
@@ -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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#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,16 +53,17 @@ 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 <windows.h>
#endif
#ifdef GC_NAME_CONFLICT
# define USE_GC UseGC
struct foo * GC;
#else
# define USE_GC GC
# include <windows.h>
#endif
#ifdef GC_NAME_CONFLICT
# define USE_GC UseGC
struct foo * GC;
#else
# define USE_GC GC
#endif
#define my_assert( e ) \
if (! (e)) { \
@@ -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<int>().allocate(1);
int *xio = gc_allocator_ignore_off_page<int>().allocate(1);
int *xio;
xio = gc_allocator_ignore_off_page<int>().allocate(1);
int **xptr = traceable_allocator<int *>().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 );
}