Skip to content

Commit 599eb6d

Browse files
alexmalyshevfacebook-github-bot
authored andcommitted
Minor cleanup on Jit/code_runtime.h
Summary: Hides the implementation, types globals and builtins as dicts, fixes up and adds comments, and shrinks GenYieldPoint by 8 bytes. Reviewed By: mpage Differential Revision: D83566613 fbshipit-source-id: 4bb7635c56d40d3f4b53f2c14c3eb3201c17326d
1 parent 71c1e53 commit 599eb6d

7 files changed

Lines changed: 165 additions & 138 deletions

File tree

cinderx/Jit/code_runtime.cpp

Lines changed: 87 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,69 @@
22

33
#include "cinderx/Jit/code_runtime.h"
44

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

7-
const int64_t CodeRuntime::kPyCodeOffset =
8-
RuntimeFrameState::codeOffset() + CodeRuntime::frameStateOffset();
9+
GenYieldPoint::GenYieldPoint(std::size_t deopt_idx, ptrdiff_t yield_from_offset)
10+
: deopt_idx_{deopt_idx}, yield_from_offset_{yield_from_offset} {}
911

10-
void CodeRuntime::releaseReferences() {
11-
// Serialize as we modify ref-counts which may be widely accessible.
12-
ThreadedCompileSerialize guard;
13-
references_.clear();
12+
void GenYieldPoint::setResumeTarget(uintptr_t resume_target) {
13+
resume_target_ = resume_target;
14+
}
15+
16+
uintptr_t GenYieldPoint::resumeTarget() const {
17+
return resume_target_;
18+
}
19+
20+
std::size_t GenYieldPoint::deoptIdx() const {
21+
return deopt_idx_;
22+
}
23+
24+
bool GenYieldPoint::isYieldFrom() const {
25+
return yield_from_offset_ != kInvalidYieldFromOffset;
26+
}
27+
28+
ptrdiff_t GenYieldPoint::yieldFromOffset() const {
29+
return yield_from_offset_;
30+
}
31+
32+
bool RuntimeFrameState::isGen() const {
33+
return code()->co_flags & kCoFlagsAnyGenerator;
34+
}
35+
36+
BorrowedRef<PyCodeObject> RuntimeFrameState::code() const {
37+
return code_;
38+
}
39+
40+
BorrowedRef<PyDictObject> RuntimeFrameState::builtins() const {
41+
return builtins_;
42+
}
43+
44+
BorrowedRef<PyDictObject> RuntimeFrameState::globals() const {
45+
return globals_;
46+
}
47+
48+
BorrowedRef<PyFunctionObject> RuntimeFrameState::func() const {
49+
return func_;
50+
}
51+
52+
CodeRuntime::CodeRuntime(BorrowedRef<PyFunctionObject> func)
53+
: CodeRuntime{
54+
BorrowedRef<PyCodeObject>{func->func_code},
55+
func->func_builtins,
56+
func->func_globals} {}
57+
58+
CodeRuntime::CodeRuntime(
59+
BorrowedRef<PyCodeObject> code,
60+
BorrowedRef<PyDictObject> builtins,
61+
BorrowedRef<PyDictObject> globals)
62+
: frame_state_{code, builtins, globals} {
63+
// Ensure code, globals, and builtins objects live as long as their compiled
64+
// functions.
65+
addReference(code);
66+
addReference(builtins);
67+
addReference(globals);
1468
}
1569

1670
void CodeRuntime::addReference(BorrowedRef<> obj) {
@@ -19,4 +73,31 @@ void CodeRuntime::addReference(BorrowedRef<> obj) {
1973
references_.emplace(ThreadedRef<>::create(obj));
2074
}
2175

76+
void CodeRuntime::releaseReferences() {
77+
// Serialize as we modify ref-counts which may be widely accessible.
78+
ThreadedCompileSerialize guard;
79+
references_.clear();
80+
}
81+
82+
GenYieldPoint* CodeRuntime::addGenYieldPoint(GenYieldPoint&& gen_yield_point) {
83+
gen_yield_points_.emplace_back(std::move(gen_yield_point));
84+
return &gen_yield_points_.back();
85+
}
86+
87+
const RuntimeFrameState* CodeRuntime::frameState() const {
88+
return &frame_state_;
89+
}
90+
91+
int CodeRuntime::frameSize() const {
92+
return frame_size_;
93+
}
94+
95+
void CodeRuntime::setFrameSize(int size) {
96+
frame_size_ = size;
97+
}
98+
99+
DebugInfo* CodeRuntime::debugInfo() {
100+
return &debug_info_;
101+
}
102+
22103
} // namespace jit

cinderx/Jit/code_runtime.h

Lines changed: 64 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -9,188 +9,132 @@
99
#endif
1010

1111
#include "cinderx/Common/ref.h"
12-
#include "cinderx/Common/util.h"
1312
#include "cinderx/Jit/debug_info.h"
14-
#include "cinderx/Jit/frame_header.h"
1513
#include "cinderx/Jit/threaded_compile.h"
1614

1715
#include <deque>
18-
#include <unordered_map>
16+
#include <limits>
17+
#include <unordered_set>
1918

2019
namespace jit {
2120

21+
constexpr ptrdiff_t kInvalidYieldFromOffset =
22+
std::numeric_limits<ptrdiff_t>::max();
23+
24+
// Information about how a specific yield instruction should resume.
2225
class GenYieldPoint {
2326
public:
24-
explicit GenYieldPoint(
25-
std::size_t deopt_idx,
26-
bool is_yield_from,
27-
ptrdiff_t yield_from_offs)
28-
: deopt_idx_(deopt_idx),
29-
isYieldFrom_(is_yield_from),
30-
yieldFromOffs_(yield_from_offs) {}
31-
32-
void setResumeTarget(uint64_t resume_target) {
33-
resume_target_ = resume_target;
34-
}
35-
36-
uint64_t resumeTarget() const {
37-
return resume_target_;
38-
}
39-
40-
std::size_t deoptIdx() const {
41-
return deopt_idx_;
27+
static constexpr int resumeTargetOffset() {
28+
return offsetof(GenYieldPoint, resume_target_);
4229
}
4330

44-
bool isYieldFrom() const {
45-
return isYieldFrom_;
46-
}
31+
GenYieldPoint(std::size_t deopt_idx, ptrdiff_t yield_from_offset);
4732

48-
ptrdiff_t yieldFromOffset() const {
49-
return yieldFromOffs_;
50-
}
33+
// Get and set what address the yield should resume from.
34+
uintptr_t resumeTarget() const;
35+
void setResumeTarget(uintptr_t resume_target);
5136

52-
static constexpr int resumeTargetOffset() {
53-
return offsetof(GenYieldPoint, resume_target_);
54-
}
37+
std::size_t deoptIdx() const;
38+
bool isYieldFrom() const;
39+
ptrdiff_t yieldFromOffset() const;
5540

5641
private:
57-
uint64_t resume_target_{0};
42+
uintptr_t resume_target_{0};
5843
const std::size_t deopt_idx_;
59-
const bool isYieldFrom_;
60-
const ptrdiff_t yieldFromOffs_;
44+
const ptrdiff_t yield_from_offset_;
6145
};
6246

6347
class alignas(16) RuntimeFrameState {
6448
public:
49+
static constexpr int64_t codeOffset() {
50+
return offsetof(RuntimeFrameState, code_);
51+
}
52+
6553
RuntimeFrameState(
6654
BorrowedRef<PyCodeObject> code,
67-
BorrowedRef<> builtins,
68-
BorrowedRef<> globals,
55+
BorrowedRef<PyDictObject> builtins,
56+
BorrowedRef<PyDictObject> globals,
6957
BorrowedRef<PyFunctionObject> func = nullptr)
70-
: code_(code), builtins_(builtins), globals_(globals), func_(func) {}
58+
: code_{code}, builtins_{builtins}, globals_{globals}, func_{func} {}
7159

72-
bool isGen() const {
73-
return code()->co_flags & kCoFlagsAnyGenerator;
74-
}
75-
76-
BorrowedRef<PyCodeObject> code() const {
77-
return code_;
78-
}
79-
80-
BorrowedRef<> builtins() const {
81-
return builtins_;
82-
}
83-
84-
BorrowedRef<> globals() const {
85-
return globals_;
86-
}
60+
// Check if this is a generator frame.
61+
bool isGen() const;
8762

88-
BorrowedRef<PyFunctionObject> func() const {
89-
return func_;
90-
}
91-
92-
static constexpr int64_t codeOffset() {
93-
return offsetof(RuntimeFrameState, code_);
94-
}
63+
BorrowedRef<PyCodeObject> code() const;
64+
BorrowedRef<PyDictObject> builtins() const;
65+
BorrowedRef<PyDictObject> globals() const;
66+
BorrowedRef<PyFunctionObject> func() const;
9567

9668
private:
97-
// These are owned by the CodeRuntime that owns this RuntimeFrameState.
69+
// All fields are owned by the CodeRuntime that owns this RuntimeFrameState.
70+
9871
BorrowedRef<PyCodeObject> code_;
99-
BorrowedRef<> builtins_;
100-
BorrowedRef<> globals_;
72+
BorrowedRef<PyDictObject> builtins_;
73+
BorrowedRef<PyDictObject> globals_;
74+
// The function is only set for inlined frames.
10175
BorrowedRef<PyFunctionObject> func_;
10276
};
10377

10478
// Runtime data for a PyCodeObject object, containing caches and any other data
10579
// associated with a JIT-compiled function.
10680
class alignas(16) CodeRuntime {
10781
public:
108-
CodeRuntime(
109-
PyCodeObject* code,
110-
PyObject* builtins,
111-
PyObject* globals,
112-
PyFunctionObject* func = nullptr)
113-
: frame_state_(code, builtins, globals, func) {
114-
// TASK(T88040922): Until we work out something smarter, force code,
115-
// globals, and builtins objects for compiled functions to live as long as
116-
// the JIT is initialized.
117-
addReference(BorrowedRef(code));
118-
addReference(builtins);
119-
addReference(globals);
120-
if (func != nullptr) {
121-
addReference(&func->ob_base);
122-
}
82+
static constexpr int64_t frameStateOffset() {
83+
#pragma GCC diagnostic push
84+
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
85+
return offsetof(CodeRuntime, frame_state_);
86+
#pragma GCC diagnostic pop
12387
}
12488

125-
explicit CodeRuntime(PyFunctionObject* func)
126-
: CodeRuntime(
127-
reinterpret_cast<PyCodeObject*>(func->func_code),
128-
func->func_builtins,
129-
func->func_globals) {}
89+
static constexpr int64_t codeOffset() {
90+
return CodeRuntime::frameStateOffset() + RuntimeFrameState::codeOffset();
91+
}
92+
93+
explicit CodeRuntime(BorrowedRef<PyFunctionObject> func);
94+
CodeRuntime(
95+
BorrowedRef<PyCodeObject> code,
96+
BorrowedRef<PyDictObject> builtins,
97+
BorrowedRef<PyDictObject> globals);
13098

13199
template <typename... Args>
132100
RuntimeFrameState* allocateRuntimeFrameState(Args&&... args) {
133-
// Serialize as we modify the globally shared runtimes data.
134-
ThreadedCompileSerialize guard;
135-
inlined_frame_states_.emplace_back(
136-
std::make_unique<RuntimeFrameState>(std::forward<Args>(args)...));
137-
return inlined_frame_states_.back().get();
138-
}
139-
140-
const RuntimeFrameState* frameState() const {
141-
return &frame_state_;
101+
return inlined_frame_states_
102+
.emplace_back(
103+
std::make_unique<RuntimeFrameState>(std::forward<Args>(args)...))
104+
.get();
142105
}
143106

144-
// Release any references this CodeRuntime holds to Python objects.
145-
void releaseReferences();
146-
147-
// Ensure that this CodeRuntime owns a reference to the given owned object,
148-
// keeping it alive for use by the compiled code. Transfer ownership of the
149-
// object to the CodeRuntime.
150-
void addReference(Ref<>&& obj);
151-
152107
// Ensure that this CodeRuntime owns a reference to the given borrowed
153108
// object, keeping it alive for use by the compiled code. Make CodeRuntime a
154109
// new owner of the object.
155110
void addReference(BorrowedRef<> obj);
156111

112+
// Release any references this CodeRuntime holds to Python objects.
113+
void releaseReferences();
114+
157115
// Store meta-data about generator yield point.
158-
GenYieldPoint* addGenYieldPoint(GenYieldPoint&& gen_yield_point) {
159-
gen_yield_points_.emplace_back(std::move(gen_yield_point));
160-
return &gen_yield_points_.back();
161-
}
116+
GenYieldPoint* addGenYieldPoint(GenYieldPoint&& gen_yield_point);
162117

163-
void set_frame_size(int size) {
164-
frame_size_ = size;
165-
}
166-
int frame_size() const {
167-
return frame_size_;
168-
}
118+
// Get the top-level runtime frame state for this CodeRuntime's PyCodeObject.
119+
const RuntimeFrameState* frameState() const;
169120

170-
DebugInfo* debug_info() {
171-
return &debug_info_;
172-
}
121+
// Get and set the total size of a stack frame for this compiled code object.
122+
int frameSize() const;
123+
void setFrameSize(int size);
173124

174-
static constexpr int64_t frameStateOffset() {
175-
#pragma GCC diagnostic push
176-
#pragma GCC diagnostic ignored "-Winvalid-offsetof"
177-
return offsetof(CodeRuntime, frame_state_);
178-
#pragma GCC diagnostic pop
179-
}
180-
181-
static const int64_t kPyCodeOffset;
125+
DebugInfo* debugInfo();
182126

183127
private:
184128
RuntimeFrameState frame_state_;
185129
std::vector<std::unique_ptr<RuntimeFrameState>> inlined_frame_states_;
186130

131+
// References owned by this CodeRuntime.
187132
std::unordered_set<ThreadedRef<PyObject>> references_;
188133

189134
// Metadata about yield points. Deque so we can have raw pointers to content.
190135
std::deque<GenYieldPoint> gen_yield_points_;
191136

192137
int frame_size_{-1};
193-
194138
DebugInfo debug_info_;
195139
};
196140

cinderx/Jit/codegen/autogen.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,9 +366,10 @@ void emitStoreGenYieldPoint(
366366
live_regs_input - num_live_regs,
367367
live_regs_input);
368368

369-
auto yield_from_offset = is_yield_from ? calc_spill_offset(2) : 0;
369+
auto yield_from_offset =
370+
is_yield_from ? calc_spill_offset(2) : kInvalidYieldFromOffset;
370371
GenYieldPoint* gen_yield_point = env->code_rt->addGenYieldPoint(
371-
GenYieldPoint{deopt_idx, is_yield_from, yield_from_offset});
372+
GenYieldPoint{deopt_idx, yield_from_offset});
372373

373374
env->unresolved_gen_entry_labels.emplace(gen_yield_point, resume_label);
374375
if (yield->origin()) {

0 commit comments

Comments
 (0)