23 PyMethodDef methoddef_ = {
24 const_cast< char*
>(
"TMemoryRegulator_internal_ObjectEraseCallback" ),
30 PyObject* gObjectEraseCallback = PyCFunction_New( &methoddef_, NULL );
34 PyTypeObject PyROOT_NoneType;
45 PyMappingMethods PyROOT_NoneType_mapping = {
52 #if defined(__GNUC__) && (__GNUC__ >= 5 || (__GNUC__ >= 4 && ((__GNUC_MINOR__ == 2 && __GNUC_PATCHLEVEL__ >= 1) || (__GNUC_MINOR__ >= 3)))) && !__INTEL_COMPILER 53 #pragma GCC diagnostic ignored "-Wstrict-aliasing" 58 struct InitPyROOT_NoneType_t {
59 InitPyROOT_NoneType_t()
62 memset( &PyROOT_NoneType, 0,
sizeof( PyROOT_NoneType ) );
64 ((
PyObject&)PyROOT_NoneType).ob_type = &PyType_Type;
65 ((
PyObject&)PyROOT_NoneType).ob_refcnt = 1;
66 ((PyVarObject&)PyROOT_NoneType).ob_size = 0;
68 PyROOT_NoneType.tp_name =
const_cast< char*
>(
"PyROOT_NoneType" );
69 PyROOT_NoneType.tp_flags = Py_TPFLAGS_HAVE_RICHCOMPARE | Py_TPFLAGS_HAVE_GC;
71 PyROOT_NoneType.tp_traverse = (traverseproc) 0;
72 PyROOT_NoneType.tp_clear = (inquiry) 0;
73 PyROOT_NoneType.tp_dealloc = (destructor) &InitPyROOT_NoneType_t::DeAlloc;
74 PyROOT_NoneType.tp_repr =
Py_TYPE(Py_None)->tp_repr;
75 PyROOT_NoneType.tp_richcompare = (richcmpfunc) &InitPyROOT_NoneType_t::RichCompare;
76 #if PY_VERSION_HEX < 0x03000000 80 PyROOT_NoneType.tp_hash = (hashfunc) &InitPyROOT_NoneType_t::PtrHash;
82 PyROOT_NoneType.tp_as_mapping = &PyROOT_NoneType_mapping;
84 PyType_Ready( &PyROOT_NoneType );
92 return PyObject_RichCompare( other, Py_None, opid );
97 #if PY_VERSION_HEX < 0x03000000 98 return PyObject_Compare( other, Py_None );
101 return ! PyObject_RichCompareBool( other, Py_None, Py_EQ );
113 static InitPyROOT_NoneType_t initPyROOT_NoneType;
115 assert( fgObjectTable == 0 );
118 assert( fgWeakRefTable == 0 );
127 delete fgWeakRefTable;
130 delete fgObjectTable;
139 if ( !
object || ! fgObjectTable )
143 ObjectMap_t::iterator ppo = fgObjectTable->find(
object );
145 if ( ppo != fgObjectTable->end() ) {
146 fgWeakRefTable->erase( fgWeakRefTable->find( ppo->second ) );
151 fgObjectTable->erase( ppo );
156 Py_DECREF( ppo->second );
160 if ( ! PyROOT_NoneType.tp_traverse ) {
165 PyROOT_NoneType.tp_traverse =
Py_TYPE(pyobj)->tp_traverse;
166 PyROOT_NoneType.tp_clear =
Py_TYPE(pyobj)->tp_clear;
167 PyROOT_NoneType.tp_free =
Py_TYPE(pyobj)->tp_free;
168 }
else if ( PyROOT_NoneType.tp_traverse !=
Py_TYPE(pyobj)->tp_traverse ) {
169 std::cerr <<
"in PyROOT::TMemoryRegulater, unexpected object of type: " 170 <<
Py_TYPE(pyobj)->tp_name << std::endl;
177 int refcnt = ((
PyObject*)pyobj)->ob_refcnt;
179 PyObject_ClearWeakRefs( (
PyObject*)pyobj );
180 ((
PyObject*)pyobj)->ob_refcnt = refcnt;
187 Py_INCREF( (
PyObject*)(
void*)&PyROOT_NoneType );
189 ((
PyObject*)pyobj)->ob_type = &PyROOT_NoneType;
193 fgObjectTable->erase( ppo );
202 if ( ! ( pyobj &&
object ) )
205 ObjectMap_t::iterator ppo = fgObjectTable->find(
object );
206 if ( ppo == fgObjectTable->end() ) {
208 PyObject* pyref = PyWeakref_NewRef( (
PyObject*)pyobj, gObjectEraseCallback );
209 ObjectMap_t::iterator newppo = fgObjectTable->insert( std::make_pair(
object, pyref ) ).first;
210 (*fgWeakRefTable)[ pyref ] = newppo;
222 ObjectMap_t::iterator ppo = fgObjectTable->find(
object );
224 if ( ppo != fgObjectTable->end() ) {
225 fgWeakRefTable->erase( fgWeakRefTable->find( ppo->second ) );
226 fgObjectTable->erase( ppo );
241 ObjectMap_t::iterator ppo = fgObjectTable->find(
object );
242 if ( ppo != fgObjectTable->end() ) {
243 PyObject* pyobj = PyWeakref_GetObject( ppo->second );
245 if ( pyobj && ((
ObjectProxy*)pyobj)->ObjectIsA() != klass ) {
272 ObjectMap_t::iterator ppo = fgObjectTable->find(
object );
273 if ( ppo != fgObjectTable->end() ) {
275 fgWeakRefTable->erase( fgWeakRefTable->find( ppo->second ) );
276 Py_DECREF( ppo->second );
277 fgObjectTable->erase( ppo );
282 WeakRefMap_t::iterator wri = fgWeakRefTable->find( pyref );
283 if ( wri != fgWeakRefTable->end() ) {
284 fgObjectTable->erase( wri->second );
285 fgWeakRefTable->erase( wri );
290 Py_INCREF( Py_None );
static PyObject * RetrieveObject(TObject *object, Cppyy::TCppType_t klass)
lookup <object>, return old proxy if tracked
std::map< TObject *, PyObject *> ObjectMap_t
virtual void RecursiveRemove(TObject *object)
Recursively remove this object from a list.
static Bool_t RegisterObject(ObjectProxy *pyobj, TObject *object)
start tracking <object> proxied by <pyobj>
ptrdiff_t GetBaseOffset(TCppType_t derived, TCppType_t base, TCppObject_t address, int direction, bool rerror=false)
static WeakRefMap_t * fgWeakRefTable
~TMemoryRegulator()
cleanup weakref cache
static ObjectMap_t * fgObjectTable
Bool_t ObjectProxy_Check(T *object)
static Bool_t UnregisterObject(TObject *object)
stop tracking <object>, without notification
static PyObject * ObjectEraseCallback(PyObject *, PyObject *pyref)
if object destructor must call RecursiveRemove()
Bool_t IsSubtype(TCppType_t derived, TCppType_t base)
TCppScope_t GetScope(const std::string &scope_name)
Mother of all ROOT objects.
std::map< PyObject *, ObjectMap_t::iterator > WeakRefMap_t
void op_dealloc_nofree(ObjectProxy *)
Destroy the held C++ object, if owned; does not deallocate the proxy.
Int_t Compare(const void *item1, const void *item2)
Cppyy::TCppType_t ObjectIsA() const