Browse Source

add MemoryBase to fix malloc issues, especially on OSX

David Rose 19 years ago
parent
commit
55225290b8

+ 5 - 0
dtool/Config.pp

@@ -327,6 +327,11 @@
 // available, even if it is unused.
 #defer DO_MEMORY_USAGE $[<= $[OPTIMIZE], 3]
 
+// Should we attempt to override the global new and delete operators?
+// It turns out this is usually a bad idea, but may be useful for
+// development.
+#define REDEFINE_GLOBAL_OPERATOR_NEW
+
 // This option compiles in support for simulating network delay via
 // the min-lag and max-lag prc variables.  It adds a tiny bit of
 // overhead even when it is not activated, so it is typically enabled

+ 1 - 0
dtool/LocalSetup.pp

@@ -275,6 +275,7 @@ $[cdefine TRACK_IN_INTERPRETER]
 
 /* Define if we want to enable track-memory-usage.  */
 $[cdefine DO_MEMORY_USAGE]
+$[cdefine REDEFINE_GLOBAL_OPERATOR_NEW]
 
 /* Define if we want to enable min-lag and max-lag.  */
 $[cdefine SIMULATE_NETWORK_DELAY]

+ 1 - 1
dtool/src/cppparser/cppPreprocessor.cxx

@@ -106,7 +106,7 @@ CPPPreprocessor::InputFile::
     // the stream pointer does not call the appropriate global delete
     // function; instead apparently calling the system delete
     // function.  So we call the delete function by hand instead.
-#ifndef USE_MEMORY_NOWRAPPERS
+#if !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
     _in->~istream();
     (*global_operator_delete)(_in);
 #else

+ 2 - 0
dtool/src/dtoolbase/Sources.pp

@@ -19,6 +19,7 @@
     dtoolbase.h dtoolbase_cc.h dtoolsymbols.h \
     fakestringstream.h \
     indent.I indent.h indent.cxx \
+    memoryBase.h \
     mutexImpl.h \
     mutexDummyImpl.h mutexDummyImpl.I \
     mutexNsprImpl.h mutexNsprImpl.I \
@@ -62,6 +63,7 @@
     deletedChain.h deletedChain.T \
     dtoolbase.h dtoolbase_cc.h dtoolsymbols.h fakestringstream.h \
     indent.I indent.h \
+    memoryBase.h \
     mutexImpl.h \
     mutexDummyImpl.h mutexDummyImpl.I \
     mutexNsprImpl.h mutexNsprImpl.I \

+ 2 - 0
dtool/src/dtoolbase/dtoolbase_cc.h

@@ -147,6 +147,7 @@ EXPCL_DTOOL void default_operator_delete(void *ptr);
 extern EXPCL_DTOOL void *(*global_operator_new)(size_t size);
 extern EXPCL_DTOOL void (*global_operator_delete)(void *ptr);
 
+#ifdef REDEFINE_GLOBAL_OPERATOR_NEW
 #ifdef GLOBAL_OPERATOR_NEW_EXCEPTIONS
 
 // Redefinitions of operator new/delete, for O1 - O3 builds (!NDEBUG)
@@ -184,6 +185,7 @@ INLINE void operator delete[](void *ptr) {
 }
 
 #endif  // GLOBAL_OPERATOR_NEW_EXCEPTIONS
+#endif  // REDEFINE_GLOBAL_OPERATOR_NEW
 #endif  // USE_MEMORY_NOWRAPPERS
 
 #if defined(USE_TAU) && defined(WIN32)

+ 83 - 0
dtool/src/dtoolbase/memoryBase.h

@@ -0,0 +1,83 @@
+// Filename: memoryBase.h
+// Created by:  drose (16Nov06)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef MEMORYBASE_H
+#define MEMORYBASE_H
+
+#include "dtoolbase.h"
+
+// Place this macro within a class definition to define appropriate
+// operator new and delete methods that hook into the MemoryInfo class
+// to provide memory tracking.  Of course, it is better simply to
+// inherit from MemoryBase; this macro is provided to resolve problems
+// with multiple inheritance or some such.
+
+#ifndef USE_MEMORY_NOWRAPPERS
+
+#define ALLOC_MEMORY_BASE                                    \
+  inline void *operator new(size_t size) {                   \
+    return (*global_operator_new)(size);                     \
+  }                                                          \
+  inline void *operator new(size_t size, void *) {           \
+    return (*global_operator_new)(size);                     \
+  }                                                          \
+  inline void operator delete(void *ptr) {                   \
+    (*global_operator_delete)(ptr);                          \
+  }                                                          \
+  inline void operator delete(void *ptr, void *) {           \
+    (*global_operator_delete)(ptr);                          \
+  }                                                          \
+  inline void *operator new[](size_t size) {                 \
+    return (*global_operator_new)(size);                     \
+  }                                                          \
+  inline void *operator new[](size_t size, void *) {         \
+    return (*global_operator_new)(size);                     \
+  }                                                          \
+  inline void operator delete[](void *ptr) {                 \
+    (*global_operator_delete)(ptr);                          \
+  }                                                          \
+  inline void operator delete[](void *ptr, void *) {         \
+    (*global_operator_delete)(ptr);                          \
+  }
+
+#else   // USE_MEMORY_NOWRAPPERS
+
+#define ALLOC_MEMORY_BASE
+
+#endif  // USE_MEMORY_NOWRAPPERS
+
+////////////////////////////////////////////////////////////////////
+//       Class : MemoryBase
+// Description : This class is intended to be the base class of all
+//               objects in Panda that might be allocated and deleted
+//               via the new and delete operators.  It redefines these
+//               operators to provide some memory tracking support.
+//
+//               We used to try to override the global operator new
+//               and delete methods, but that seems to cause problems
+//               when including header files for C++-based system
+//               libraries (such as are found on OSX).
+////////////////////////////////////////////////////////////////////
+class EXPCL_DTOOL MemoryBase {
+public:
+  ALLOC_MEMORY_BASE;
+};
+
+#endif
+
+

+ 2 - 1
dtool/src/interrogatedb/typeRegistry.h

@@ -24,6 +24,7 @@
 #include "pnotify.h"
 #include "pvector.h"
 #include "pmap.h"
+#include "memoryBase.h"
 
 #include <set>
 
@@ -40,7 +41,7 @@ class TypedObject;
 //               initially, and it should be migrated to shared memory
 //               as soon as shared memory becomes available.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_DTOOLCONFIG TypeRegistry {
+class EXPCL_DTOOLCONFIG TypeRegistry : public MemoryBase {
 public:
   // User code shouldn't generally need to call
   // TypeRegistry::register_type() or record_derivation() directly;

+ 2 - 1
dtool/src/interrogatedb/typedObject.h

@@ -23,6 +23,7 @@
 
 #include "typeHandle.h"
 #include "register_type.h"
+#include "memoryBase.h"
 
 #include <set>
 
@@ -104,7 +105,7 @@
 //               }
 //               
 ////////////////////////////////////////////////////////////////////
-class EXPCL_DTOOLCONFIG TypedObject {
+class EXPCL_DTOOLCONFIG TypedObject : public MemoryBase {
 public:
   INLINE TypedObject();
   INLINE TypedObject(const TypedObject &copy);

+ 1 - 1
panda/src/downloader/httpChannel.cxx

@@ -190,7 +190,7 @@ close_read_file(istream *stream) const {
     // the stream pointer does not call the appropriate global delete
     // function; instead apparently calling the system delete
     // function.  So we call the delete function by hand instead.
-#ifndef USE_MEMORY_NOWRAPPERS
+#if !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
     stream->~istream();
     (*global_operator_delete)(stream);
 #else

+ 1 - 0
panda/src/express/memoryUsage.cxx

@@ -603,6 +603,7 @@ ns_record_void_pointer(void *ptr, size_t size) {
     if ((info._flags & MemoryInfo::F_got_void) != 0) {
       express_cat.error()
         << "Void pointer " << (void *)ptr << " recorded twice!\n";
+      nassertv(false);
     }
 
     if (info._freeze_index == _freeze_index) {

+ 2 - 1
panda/src/express/referenceCount.h

@@ -23,6 +23,7 @@
 #include "weakReferenceList.h"
 #include "typedObject.h"
 #include "memoryUsage.h"
+#include "memoryBase.h"
 #include "config_express.h"
 #include "atomicAdjust.h"
 #include "numeric_types.h"
@@ -42,7 +43,7 @@
 //               conjunction with PointerTo to automatically delete
 //               objects when the last pointer to them goes away.
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDAEXPRESS ReferenceCount {
+class EXPCL_PANDAEXPRESS ReferenceCount : public MemoryBase {
 protected:
   INLINE ReferenceCount();
   INLINE ReferenceCount(const ReferenceCount &);

+ 1 - 1
panda/src/express/virtualFile.cxx

@@ -223,7 +223,7 @@ close_read_file(istream *stream) const {
     // the stream pointer does not call the appropriate global delete
     // function; instead apparently calling the system delete
     // function.  So we call the delete function by hand instead.
-#ifndef USE_MEMORY_NOWRAPPERS
+#if !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
     stream->~istream();
     (*global_operator_delete)(stream);
 #else

+ 1 - 1
panda/src/express/virtualFileMount.cxx

@@ -46,7 +46,7 @@ close_read_file(istream *stream) const {
     // the stream pointer does not call the appropriate global delete
     // function; instead apparently calling the system delete
     // function.  So we call the delete function by hand instead.
-#ifndef USE_MEMORY_NOWRAPPERS
+#if !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
     stream->~istream();
     (*global_operator_delete)(stream);
 #else

+ 1 - 1
panda/src/express/virtualFileSystem.cxx

@@ -607,7 +607,7 @@ close_read_file(istream *stream) const {
     // the stream pointer does not call the appropriate global delete
     // function; instead apparently calling the system delete
     // function.  So we call the delete function by hand instead.
-#ifndef USE_MEMORY_NOWRAPPERS
+#if !defined(USE_MEMORY_NOWRAPPERS) && defined(REDEFINE_GLOBAL_OPERATOR_NEW)
     stream->~istream();
     (*global_operator_delete)(stream);
 #else