Skip to content

Commit cdfd31d

Browse files
jbower-fbfacebook-github-bot
authored andcommitted
Make PyModule instance available on CinderX ModuleState
Summary: Introducing this so we can bump the reference count on the module if something is alive and relies on its content. Specifically the memory backing the free-list for generators to start with. Reviewed By: alexmalyshev Differential Revision: D78516908 fbshipit-source-id: a3e3700b96f60ea4c4cbce5cf502069f4669404a
1 parent 52e3ff4 commit cdfd31d

3 files changed

Lines changed: 28 additions & 6 deletions

File tree

cinderx/_cinderx-lib.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,6 @@ void module_free(void* raw_mod) {
10651065
}
10661066

10671067
state->shutdown();
1068-
cinderx::setModuleState(nullptr);
10691068
}
10701069

10711070
// Called when the interpreter is shutting down, allows us to do some aggressive
@@ -1337,7 +1336,7 @@ static int _cinderx_exec(PyObject* m) {
13371336
}
13381337
state->setSymbolizer(symbolizer);
13391338

1340-
cinderx::setModuleState(state);
1339+
cinderx::setModule(m);
13411340

13421341
CiExc_StaticTypeError =
13431342
PyErr_NewException("cinderx.StaticTypeError", PyExc_TypeError, nullptr);

cinderx/module_state.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
#include "cinderx/module_state.h"
44

5+
#include "cinderx/Common/log.h"
6+
57
namespace cinderx {
68

79
int ModuleState::traverse(visitproc visit, void* arg) {
@@ -15,16 +17,25 @@ int ModuleState::clear() {
1517
return 0;
1618
}
1719

20+
static ModuleState* s_cinderx_state;
21+
1822
void ModuleState::shutdown() {
1923
cache_manager_.reset();
2024
runtime_.reset();
2125
symbolizer_.reset();
26+
JIT_DCHECK(
27+
this == s_cinderx_state,
28+
"Global module state pointer inconsistent with this module state {} != "
29+
"{}",
30+
reinterpret_cast<void*>(this),
31+
reinterpret_cast<void*>(s_cinderx_state));
32+
s_cinderx_state = nullptr;
2233
}
2334

24-
static ModuleState* s_cinderx_state;
25-
26-
void setModuleState(ModuleState* state) {
35+
void setModule(PyObject* m) {
36+
auto state = reinterpret_cast<cinderx::ModuleState*>(PyModule_GetState(m));
2737
s_cinderx_state = state;
38+
state->setModule(m);
2839
}
2940

3041
ModuleState* getModuleState() {

cinderx/module_state.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,17 @@ class ModuleState {
136136
initialized_ = init;
137137
}
138138

139+
void setModule(BorrowedRef<> module) {
140+
cinderx_module_ = module;
141+
}
142+
143+
// Returns the PyModule instance for the CinderX module. This can be useful if
144+
// we have live data backed by the module, in which case we can increase the
145+
// refcount of the module to prevent it from being freed prematurely.
146+
BorrowedRef<> module() const {
147+
return cinderx_module_;
148+
}
149+
139150
private:
140151
std::unique_ptr<jit::IGlobalCacheManager> cache_manager_;
141152
std::unique_ptr<jit::ICodeAllocator> code_allocator_;
@@ -152,9 +163,10 @@ class ModuleState {
152163
jit::UnorderedSet<BorrowedRef<PyFunctionObject>> perf_trampoline_worklist_;
153164

154165
bool initialized_{false};
166+
BorrowedRef<> cinderx_module_;
155167
};
156168

157-
void setModuleState(ModuleState* state);
169+
void setModule(PyObject* module);
158170
ModuleState* getModuleState();
159171

160172
} // namespace cinderx

0 commit comments

Comments
 (0)