Logo ROOT  
Reference Guide
TMemoryRegulator.cxx
Go to the documentation of this file.
1 
2 // Author: Enric Tejedor CERN 08/2019
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 #include "TMemoryRegulator.h"
13 
14 #include "ProxyWrappers.h"
15 #include "CPPInstance.h"
16 #include "CPPInstance.h"
17 
18 using namespace CPyCppyy;
19 
21 
22 ////////////////////////////////////////////////////////////////////////////
23 /// \brief Constructor. Registers the hooks to run on Cppyy's object
24 /// construction and destruction
26 {
29 }
30 
31 ////////////////////////////////////////////////////////////////////////////
32 /// \brief Register a hook that Cppyy runs when constructing an object.
33 /// \param[in] cppobj Address of the object.
34 /// \param[in] klass Class id of the object.
35 /// \return Pair of two booleans. First indicates success, second tells
36 /// Cppyy if we want to continue running RegisterPyObject
38 {
39  static Cppyy::TCppType_t tobjectTypeID = (Cppyy::TCppType_t)Cppyy::GetScope("TObject");
40 
41  if (Cppyy::IsSubtype(klass, tobjectTypeID)) {
42  ObjectMap_t::iterator ppo = fObjectMap.find(cppobj);
43  if (ppo == fObjectMap.end()) {
44  fObjectMap.insert({cppobj, klass});
45  }
46  }
47 
48  return {true, true};
49 }
50 
51 ////////////////////////////////////////////////////////////////////////////
52 /// \brief Register a hook that Cppyy runs when deleting an object.
53 /// \param[in] cppobj Address of the object.
54 /// \param[in] klass Class id of the object.
55 /// \return Pair of two booleans. First indicates success, second tells
56 /// Cppyy if we want to continue running UnRegisterPyObject
58 {
59  static Cppyy::TCppType_t tobjectTypeID = (Cppyy::TCppType_t)Cppyy::GetScope("TObject");
60 
61  if (Cppyy::IsSubtype(klass, tobjectTypeID)) {
62  ObjectMap_t::iterator ppo = fObjectMap.find(cppobj);
63  if (ppo != fObjectMap.end()) {
64  fObjectMap.erase(ppo);
65  }
66  }
67 
68  return {true, true};
69 }
70 
71 ////////////////////////////////////////////////////////////////////////////
72 /// \brief Get the class id of the TObject being deleted and run Cppyy's
73 /// RecursiveRemove.
74 /// \param[in] object Object being destructed.
76 {
77  auto cppobj = (Cppyy::TCppObject_t)object;
78  Cppyy::TCppType_t klass = 0;
79 
80  ObjectMap_t::iterator ppo = fObjectMap.find(cppobj);
81  if (ppo != fObjectMap.end()) {
82  klass = ppo->second;
83  MemoryRegulator::RecursiveRemove(cppobj, klass);
84  fObjectMap.erase(ppo);
85  }
86 }
87 
88 ////////////////////////////////////////////////////////////////////////////
89 /// \brief Clean up all tracked objects.
91 {
92  while (!fObjectMap.empty()) {
93  auto elem = fObjectMap.begin();
94  auto cppobj = elem->first;
95  auto klassid = elem->second;
96  auto pyclass = CreateScopeProxy(klassid);
97  auto pyobj = (CPPInstance *)MemoryRegulator::RetrievePyObject(cppobj, pyclass);
98 
99  if (pyobj && (pyobj->fFlags & CPPInstance::kIsOwner)) {
100  // Only delete the C++ object if the Python proxy owns it.
101  // If it is a value, cppyy deletes it in RecursiveRemove as part of
102  // the proxy cleanup.
103  auto o = static_cast<TObject *>(cppobj);
104  bool isValue = pyobj->fFlags & CPPInstance::kIsValue;
105  RecursiveRemove(o);
106  if (!isValue)
107  delete o;
108  }
109  else {
110  // Non-owning proxy, just unregister to clean tables.
111  // The proxy deletion by Python will have no effect on C++, so all good
112  MemoryRegulator::UnregisterPyObject(pyobj, pyclass);
113  }
114  }
115 }
PyROOT::ObjectMap_t
std::unordered_map< Cppyy::TCppObject_t, Cppyy::TCppType_t > ObjectMap_t
Definition: TMemoryRegulator.h:49
CPyCppyy
Set of helper functions that are invoked from the pythonizors, on the Python side.
Definition: TPyClassGenerator.cxx:31
CPPInstance.h
PyROOT::TMemoryRegulator::UnregisterHook
static std::pair< bool, bool > UnregisterHook(Cppyy::TCppObject_t, Cppyy::TCppType_t)
Register a hook that Cppyy runs when deleting an object.
Definition: TMemoryRegulator.cxx:57
PyROOT::TMemoryRegulator::RecursiveRemove
virtual void RecursiveRemove(TObject *)
Get the class id of the TObject being deleted and run Cppyy's RecursiveRemove.
Definition: TMemoryRegulator.cxx:75
CPyCppyy::MemoryRegulator::RetrievePyObject
static PyObject * RetrievePyObject(Cppyy::TCppObject_t cppobj, PyObject *pyclass)
Definition: MemoryRegulator.cxx:229
Cppyy::IsSubtype
RPY_EXPORTED bool IsSubtype(TCppType_t derived, TCppType_t base)
Definition: clingwrapper.cxx:1228
CPyCppyy::CPPInstance
Definition: CPPInstance.h:26
PyROOT::TMemoryRegulator::ClearProxiedObjects
void ClearProxiedObjects()
Clean up all tracked objects.
Definition: TMemoryRegulator.cxx:90
CPyCppyy::MemoryRegulator::SetUnregisterHook
static void SetUnregisterHook(MemHook_t h)
Definition: MemoryRegulator.cxx:256
Cppyy::GetScope
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
Definition: clingwrapper.cxx:497
CPyCppyy::MemoryRegulator::RecursiveRemove
static bool RecursiveRemove(Cppyy::TCppObject_t cppobj, Cppyy::TCppType_t klass)
Definition: MemoryRegulator.cxx:99
ProxyWrappers.h
CPyCppyy::CreateScopeProxy
PyObject * CreateScopeProxy(Cppyy::TCppScope_t)
Definition: ProxyWrappers.cxx:490
PyROOT::TMemoryRegulator::RegisterHook
static std::pair< bool, bool > RegisterHook(Cppyy::TCppObject_t, Cppyy::TCppType_t)
Register a hook that Cppyy runs when constructing an object.
Definition: TMemoryRegulator.cxx:37
PyROOT::TMemoryRegulator::fObjectMap
static ObjectMap_t fObjectMap
Definition: TMemoryRegulator.h:53
CPyCppyy::MemoryRegulator::SetRegisterHook
static void SetRegisterHook(MemHook_t h)
Definition: MemoryRegulator.cxx:250
CPyCppyy::CPPInstance::kIsOwner
@ kIsOwner
Definition: CPPInstance.h:31
PyROOT::TMemoryRegulator::TMemoryRegulator
TMemoryRegulator()
Constructor.
Definition: TMemoryRegulator.cxx:25
Cppyy::TCppType_t
TCppScope_t TCppType_t
Definition: cpp_cppyy.h:19
Cppyy::TCppObject_t
void * TCppObject_t
Definition: cpp_cppyy.h:21
TMemoryRegulator.h
CPyCppyy::MemoryRegulator::UnregisterPyObject
static bool UnregisterPyObject(CPPInstance *pyobj, PyObject *pyclass)
Definition: MemoryRegulator.cxx:200
CPyCppyy::CPPInstance::kIsValue
@ kIsValue
Definition: CPPInstance.h:35
TObject
Mother of all ROOT objects.
Definition: TObject.h:37