mirror of
https://github.com/encounter/bdwgc.git
synced 2026-03-30 10:57:55 -07:00
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:
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
@@ -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 );
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user