Skip to content

Commit 79f62c8

Browse files
mpagefacebook-github-bot
authored andcommitted
Annotate lightweight frame linkage
Summary: Add more annotations to lightweight frame linkage. Before: ``` Link frame 0x7ff438e00163: sub $0x80,%rsp 0x7ff438e0016a: mov %fs:0xffffffffffffffe8,%r11 0x7ff438e00173: mov %rdi,-0x70(%rbp) 0x7ff438e00177: mov (%rdi),%eax 0x7ff438e00179: inc %eax 0x7ff438e0017b: je 0x7ff438e00183 0x7ff438e00181: mov %eax,(%rdi) 0x7ff438e00183: movabs $0x7ff44b57eb40,%r10 0x7ff438e0018d: mov %r10,-0x68(%rbp) 0x7ff438e00191: mov (%r10),%eax 0x7ff438e00194: inc %eax 0x7ff438e00196: je 0x7ff438e0019f 0x7ff438e0019c: mov %eax,(%r10) 0x7ff438e0019f: movabs $0x7ff44b12c450,%r10 0x7ff438e001a9: mov %r10,-0x58(%rbp) 0x7ff438e001ad: movabs $0x7ff44b57ebfe,%r10 0x7ff438e001b7: mov %r10,-0x30(%rbp) 0x7ff438e001bb: movb $0x0,-0x22(%rbp) 0x7ff438e001bf: mov 0x38(%r11),%rax 0x7ff438e001c3: mov (%rax),%r10 0x7ff438e001c6: mov %r10,-0x60(%rbp) 0x7ff438e001ca: lea -0x68(%rbp),%r10 0x7ff438e001ce: mov %r10,(%rax) 0x7ff438e001d1: mov %rsi,%r10 ``` After: ``` Link frame 0x7f62ed800163: sub $0x80,%rsp Load tstate 0x7f62ed80016a: mov %fs:0xffffffffffffffe8,%r11 Store func before frame header 0x7f62ed800173: mov %rdi,-0x70(%rbp) 0x7f62ed800177: mov (%rdi),%eax 0x7f62ed800179: inc %eax 0x7f62ed80017b: je 0x7f62ed800183 0x7f62ed800181: mov %eax,(%rdi) Set _PyInterpreterFrame::f_code 0x7f62ed800183: movabs $0x7f62ff7b3b80,%r10 0x7f62ed80018d: mov %r10,-0x68(%rbp) 0x7f62ed800191: mov (%r10),%eax 0x7f62ed800194: inc %eax 0x7f62ed800196: je 0x7f62ed80019f 0x7f62ed80019c: mov %eax,(%r10) Set _PyInterpreterFrame::f_funcobj to frame reifier 0x7f62ed80019f: movabs $0x7f62ff32f170,%r10 0x7f62ed8001a9: mov %r10,-0x58(%rbp) Set _PyInterpreterFrame::prev_instr 0x7f62ed8001ad: movabs $0x7f62ff7b3c3e,%r10 0x7f62ed8001b7: mov %r10,-0x30(%rbp) Set _PyInterpreterFrame::owner 0x7f62ed8001bb: movb $0x0,-0x22(%rbp) Get topmost frame 0x7f62ed8001bf: mov 0x38(%r11),%rax 0x7f62ed8001c3: mov (%rax),%r10 Set _PyInterpreterFrame::previous 0x7f62ed8001c6: mov %r10,-0x60(%rbp) Set _PyInterpreterFrame as topmost frame 0x7f62ed8001ca: lea -0x68(%rbp),%r10 0x7f62ed8001ce: mov %r10,(%rax) --unassigned-- 0x7f62ed8001d1: mov %rsi,%r10 ``` Reviewed By: alexmalyshev Differential Revision: D82850833 fbshipit-source-id: 0135c24f7e3689423463b86fddc4dd434be7a8f7
1 parent 2413db7 commit 79f62c8

1 file changed

Lines changed: 27 additions & 1 deletion

File tree

cinderx/Jit/codegen/frame_asm.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,9 @@ void FrameAsm::linkLightWeightFunctionFrame(
169169
//
170170
// We need to initialize the f_code, f_funcobj fields of
171171
// the frame along w/ the previous pointer.
172+
asmjit::BaseNode* init_tstate_off_cursor = as_->cursor();
172173
initThreadStateOffset();
174+
env_.addAnnotation("Init tstate offset", init_tstate_off_cursor);
173175

174176
// We have precious caller saved registers that we can trash - rax
175177
// and r10 are the only non-argument registers, and our arguments
@@ -179,6 +181,7 @@ void FrameAsm::linkLightWeightFunctionFrame(
179181
// only in ASAN builds) then we'll need to preserve that as well
180182
// after spilling and restoring the arguments around the call to
181183
// get the thread state.
184+
asmjit::BaseNode* load_tstate_cursor = as_->cursor();
182185
auto scratch = x86::gpq(INITIAL_EXTRA_ARGS_REG.loc);
183186
if (tstate_offset == -1) {
184187
preserver.preserve();
@@ -191,6 +194,7 @@ void FrameAsm::linkLightWeightFunctionFrame(
191194
// too.
192195
as_->push(scratch);
193196
}
197+
env_.addAnnotation("Load tstate", load_tstate_cursor);
194198

195199
int frame_header_size = frameHeaderSizeExcludingSpillSpace();
196200
PyObject* frame_reifier = cinderx::getModuleState()->frameReifier();
@@ -201,10 +205,13 @@ void FrameAsm::linkLightWeightFunctionFrame(
201205

202206
// Initialize the fields minus previous.
203207
// Store func before the header
208+
asmjit::BaseNode* store_func_cursor = as_->cursor();
204209
as_->mov(x86::ptr(x86::rbp, -frame_header_size), func_reg);
205210
incRef(func_reg, ref_cnt);
211+
env_.addAnnotation("Store func before frame header", store_func_cursor);
206212

207213
// Store f_code
214+
asmjit::BaseNode* store_f_code_cursor = as_->cursor();
208215
bool needs_load =
209216
storeConst(x86::rbp, FRAME_OFFSET(f_code), func_->code.get(), scratch);
210217
if (!_Py_IsImmortal(func_->code.get())) {
@@ -214,21 +221,33 @@ void FrameAsm::linkLightWeightFunctionFrame(
214221
}
215222
incRef(scratch, ref_cnt);
216223
}
224+
env_.addAnnotation("Set _PyInterpreterFrame::f_code", store_f_code_cursor);
217225

218-
// Store f_funcobj as our helper frame object
226+
// Store f_funcobj as our helper frame reifier object
227+
asmjit::BaseNode* store_f_funcobj_cursor = as_->cursor();
219228
storeConst(x86::rbp, FRAME_OFFSET(f_funcobj), frame_reifier, scratch);
220229
JIT_DCHECK(_Py_IsImmortal(frame_reifier), "frame helper must be immortal");
230+
env_.addAnnotation(
231+
"Set _PyInterpreterFrame::f_funcobj to frame reifier",
232+
store_f_funcobj_cursor);
221233

222234
// Store prev_instr
235+
asmjit::BaseNode* store_prev_instr_cursor = as_->cursor();
223236
_Py_CODEUNIT* code = _PyCode_CODE(GetFunction()->code.get()) - 1;
224237
storeConst(x86::rbp, FRAME_OFFSET(prev_instr), code, scratch);
238+
env_.addAnnotation(
239+
"Set _PyInterpreterFrame::prev_instr", store_prev_instr_cursor);
225240

241+
// Store owner
242+
asmjit::BaseNode* store_owner_cursor = as_->cursor();
226243
as_->mov(
227244
x86::ptr(x86::rbp, FRAME_OFFSET(owner), sizeof(char)),
228245
FRAME_OWNED_BY_THREAD);
246+
env_.addAnnotation("Set _PyInterpreterFrame::owner", store_owner_cursor);
229247

230248
// Get the frame that is currently linked into thread state and update
231249
// our frames pointer back to it.
250+
asmjit::BaseNode* get_tos_cursor = as_->cursor();
232251
#if PY_VERSION_HEX >= 0x030D0000
233252
// 3.14+ - current_frame is stored in PyThreadState.current_frame
234253
const asmjit::x86::Gp& frame_holder = tstate_reg;
@@ -242,13 +261,20 @@ void FrameAsm::linkLightWeightFunctionFrame(
242261
as_->mov(frame_holder, x86::ptr(tstate_reg, offsetof(PyThreadState, cframe)));
243262
as_->mov(scratch, x86::ptr(frame_holder, offsetof(_PyCFrame, current_frame)));
244263
#endif
264+
env_.addAnnotation("Get topmost frame", get_tos_cursor);
245265

266+
asmjit::BaseNode* store_prev_cursor = as_->cursor();
246267
// cur_frame->previous = PyThreadState.cframe.current_frame
247268
as_->mov(x86::ptr(x86::rbp, FRAME_OFFSET(previous)), scratch);
269+
env_.addAnnotation("Set _PyInterpreterFrame::previous", store_prev_cursor);
270+
248271
// Then finally link in our frame to thread state
272+
asmjit::BaseNode* update_linkage_cursor = as_->cursor();
249273
as_->lea(scratch, x86::ptr(x86::rbp, -frame_header_size + sizeof(PyObject*)));
250274
// (PyThreadState.cframe|PyThreadState).current_frame = &cur_frame
251275
as_->mov(x86::ptr(frame_holder, offsetof(_PyCFrame, current_frame)), scratch);
276+
env_.addAnnotation(
277+
"Set _PyInterpreterFrame as topmost frame", update_linkage_cursor);
252278

253279
if (tstate_offset == -1) {
254280
as_->pop(scratch);

0 commit comments

Comments
 (0)