Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
TMemoryRegulator.cxx
Go to the documentation of this file.
1
2// Author: Enric Tejedor CERN 08/2019
3// Author: Vincenzo Eduardo Padulano CERN 05/2024
4
5/*************************************************************************
6 * Copyright (C) 1995-2024, Rene Brun and Fons Rademakers. *
7 * All rights reserved. *
8 * *
9 * For the licensing terms see $ROOTSYS/LICENSE. *
10 * For the list of contributors see $ROOTSYS/README/CREDITS. *
11 *************************************************************************/
12
13#include "TMemoryRegulator.h"
14
15#include "../../cppyy/CPyCppyy/src/ProxyWrappers.h"
16#include "../../cppyy/CPyCppyy/src/CPPInstance.h"
17
18namespace {
19// We use a map because we do not control the deregistration anyway, that is
20// managed by the Python GC.
21// key: object address; value: object class id
22using TrackedObjects_t = std::unordered_map<Cppyy::TCppObject_t, Cppyy::TCppType_t>;
23
24TrackedObjects_t &GetTrackedObjects()
25{
26 thread_local TrackedObjects_t trackedObjects{};
27 return trackedObjects;
28}
29
30Cppyy::TCppType_t &GetTObjectTypeID()
31{
32 static Cppyy::TCppType_t tobjectTypeID{Cppyy::GetScope("TObject")};
33 return tobjectTypeID;
34}
35
36auto GetObjectIt(const TrackedObjects_t &objects, Cppyy::TCppObject_t key)
37{
38 return objects.find(key);
39}
40
41std::pair<bool, bool> RegisterHook(Cppyy::TCppObject_t cppobj, Cppyy::TCppType_t klass)
42{
43 if (Cppyy::IsSubtype(klass, GetTObjectTypeID())) {
44 GetTrackedObjects().insert({cppobj, klass});
45 }
46 return {true, true};
47}
48
49std::pair<bool, bool> UnregisterHook(Cppyy::TCppObject_t cppobj, Cppyy::TCppType_t klass)
50{
51 if (Cppyy::IsSubtype(klass, GetTObjectTypeID())) {
52 if (auto it = GetObjectIt(GetTrackedObjects(), cppobj); it != GetTrackedObjects().end()) {
53 GetTrackedObjects().erase(it);
54 }
55 }
56 return {true, true};
57}
58
59} // namespace
60
61////////////////////////////////////////////////////////////////////////////////
62/// \brief Injects custom registration/deregistration logic into cppyy's memory regulator
64{
67}
68
69////////////////////////////////////////////////////////////////////////////
70/// \brief Get the class id of the TObject being deleted and run Cppyy's
71/// RecursiveRemove.
72/// \param[in] object Object being destructed.
74{
75 auto &trackedObjects = GetTrackedObjects();
76 if (auto it = GetObjectIt(trackedObjects, reinterpret_cast<Cppyy::TCppObject_t>(object));
77 it != trackedObjects.end()) {
78 // The iterator may be invalidated in RecursiveRemove, so we erase it from our tracked objects first.
79 const auto cppobj = it->first;
80 const auto klassid = it->second;
81 trackedObjects.erase(it);
83 }
84}
static bool RecursiveRemove(Cppyy::TCppObject_t cppobj, Cppyy::TCppType_t klass)
static void SetUnregisterHook(MemHook_t h)
static void SetRegisterHook(MemHook_t h)
Mother of all ROOT objects.
Definition TObject.h:41
RPY_EXPORTED bool IsSubtype(TCppType_t derived, TCppType_t base)
void * TCppObject_t
Definition cpp_cppyy.h:21
TCppScope_t TCppType_t
Definition cpp_cppyy.h:19
RPY_EXPORTED TCppScope_t GetScope(const std::string &scope_name)
void CallCppyyRecursiveRemove(TObject *object)
Get the class id of the TObject being deleted and run Cppyy's RecursiveRemove.
RegulatorCleanup()
Injects custom registration/deregistration logic into cppyy's memory regulator.