Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

bpo-46841: Quicken code in-place#31888

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Merged
markshannon merged 37 commits intopython:mainfrombrandtbucher:quicken-in-place-fast
Mar 21, 2022
Merged
Show file tree
Hide file tree
Changes from1 commit
Commits
Show all changes
37 commits
Select commitHold shift + click to select a range
6ca0d42
Move bytecode into the code object
brandtbucherMar 10, 2022
a77a124
Clean things up a bit
brandtbucherMar 10, 2022
975b8d1
Bump the magic number
brandtbucherMar 10, 2022
40ddf39
co_bytecode -> _co_code
brandtbucherMar 10, 2022
bfcba6d
Generate specialization table
brandtbucherMar 10, 2022
0376822
Clean things up a bit
brandtbucherMar 10, 2022
3e77b8d
Pack code objects more efficiently
brandtbucherMar 10, 2022
0a598a7
Fix typo
brandtbucherMar 10, 2022
2fda3b8
More cleanup
brandtbucherMar 11, 2022
42810dd
Try a different approach
brandtbucherMar 11, 2022
7df4934
Clean up the diff
brandtbucherMar 11, 2022
5fa0ca2
Support equality comparisons again
brandtbucherMar 11, 2022
1fc2282
Never un-quicken!
brandtbucherMar 11, 2022
b40e300
More renaming and cleanup
brandtbucherMar 11, 2022
af27670
Revert marshal format changes
brandtbucherMar 11, 2022
629bf8b
More cleanup
brandtbucherMar 11, 2022
59cda59
Clean up the diff
brandtbucherMar 11, 2022
73c33c1
Catch up with main
brandtbucherMar 12, 2022
ecfb193
Miscellaneous cleanup
brandtbucherMar 14, 2022
824b2da
Remove outdated comment
brandtbucherMar 14, 2022
8164f41
Properly skip over EXTENDED_ARG instructions
brandtbucherMar 14, 2022
932a3f2
Make sure that f_lasti is always valid
brandtbucherMar 14, 2022
c0c5498
Add some comments
brandtbucherMar 14, 2022
f62a395
Catch up with main
brandtbucherMar 14, 2022
e7464a3
Check opargs during size calculations
brandtbucherMar 14, 2022
4f51fdd
Add another TODO
brandtbucherMar 14, 2022
75bd375
Clean up formatting
brandtbucherMar 15, 2022
d6d5128
Fix compiler warning
brandtbucherMar 15, 2022
82145c1
Simplify calculation of instr_prev
brandtbucherMar 15, 2022
ca176ac
_Py_Quicken -> _PyCode_Quicken
brandtbucherMar 15, 2022
1e06bb5
Revert expensive f_lasti changes
brandtbucherMar 15, 2022
e70819f
Naming is hard
brandtbucherMar 16, 2022
001eb53
Catch up with main
brandtbucherMar 16, 2022
6b96204
make patchcheck
brandtbucherMar 16, 2022
3087025
blurb add
brandtbucherMar 16, 2022
6f3bc38
Reuse the PyCodeObject definition for deepfreeze
brandtbucherMar 16, 2022
c8054b9
Clean up TODO
brandtbucherMar 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
Never un-quicken!
  • Loading branch information
@brandtbucher
brandtbucher committedMar 11, 2022
commit1fc22823a1b1fa9d06b3d5d1ecf8383928687efa
3 changes: 0 additions & 3 deletionsInclude/cpython/code.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -93,9 +93,6 @@ struct PyCodeObject {
char _co_code[1];
};

#define _PyCode_GET_CODE(CO) ((_Py_CODEUNIT *)(CO)->_co_code)
#define _PyCode_GET_SIZE(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))

/* Masks for co_flags above */
#define CO_OPTIMIZED 0x0001
#define CO_NEWLOCALS 0x0002
Expand Down
6 changes: 5 additions & 1 deletionInclude/internal/pycore_code.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -97,8 +97,12 @@ typedef struct {
/* We want to compare to zero for efficiency, so we offset values accordingly */
#define QUICKENING_INITIAL_WARMUP_VALUE (-QUICKENING_WARMUP_DELAY)

#define _PyCode_GET_CODE(CO) ((_Py_CODEUNIT *)(CO)->_co_code)
#define _PyCode_GET_SIZE(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))


void _Py_Quicken(PyCodeObject *code);
_Py_CODEUNIT*_Py_Unquickened(PyCodeObject *code);
_Py_CODEUNIT_PyCode_GetUnquickened(PyCodeObject *code, int i);

static inline void
_Py_IncrementCountAndMaybeQuicken(PyCodeObject *code)
Expand Down
22 changes: 12 additions & 10 deletionsObjects/codeobject.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1380,18 +1380,13 @@ code_richcompare(PyObject *self, PyObject *other, int op)
if (!eq) {
goto unequal;
}
_Py_CODEUNIT *co_code = _PyCode_GET_CODE(co);
_Py_CODEUNIT *cp_code = _PyCode_GET_CODE(cp);
for (int i = 0; i < Py_SIZE(co); i++) {
int opcode = _PyOpcode_Deoptimizations[_Py_OPCODE(co_code[i])];
eq = opcode == _PyOpcode_Deoptimizations[_Py_OPCODE(cp_code[i])];
if (HAS_ARG(opcode)) {
eq &= _Py_OPARG(co_code[i]) == _Py_OPARG(cp_code[i]);
}
_Py_CODEUNIT instruction = _PyCode_GetUnquickened(co, i);
eq = _PyCode_GetUnquickened(co, i) == _PyCode_GetUnquickened(cp, i);
if (!eq) {
goto unequal;
}
i += _PyOpcode_InlineCacheEntries[opcode];
i += _PyOpcode_InlineCacheEntries[_Py_OPCODE(instruction)];
}

/* compare constants */
Expand DownExpand Up@@ -1510,8 +1505,15 @@ code_getundercode(PyCodeObject *code, void *closure)
static PyObject *
code_getcode(PyCodeObject *code, void *closure)
{
return PyBytes_FromStringAndSize((char *)_Py_Unquickened(code),
_PyCode_GET_SIZE(code));
PyObject *co_code = PyBytes_FromStringAndSize(NULL, _PyCode_GET_SIZE(code));
if (co_code == NULL) {
return NULL;
}
_Py_CODEUNIT *instructions = (_Py_CODEUNIT *)PyBytes_AS_STRING(co_code);
for (int i = 0; i < Py_SIZE(code); i++) {
instructions[i] = _PyCode_GetUnquickened(code, i);
}
return co_code;
}

static PyGetSetDef code_getsetlist[] = {
Expand Down
17 changes: 14 additions & 3 deletionsObjects/frameobject.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -170,12 +170,21 @@ top_of_stack(int64_t stack)
static int64_t *
mark_stacks(PyCodeObject *code_obj, int len)
{
const _Py_CODEUNIT *code = _PyCode_GET_CODE(code_obj);
// XXX: this is one big TODO!!!
PyObject *xxx = PyBytes_FromStringAndSize(NULL, _PyCode_GET_SIZE(code_obj));
if (xxx == NULL) {
return NULL;
}
_Py_CODEUNIT *code = (_Py_CODEUNIT *)PyBytes_AS_STRING(xxx);
for (int i = 0; i < Py_SIZE(code_obj); i++) {
code[i] = _PyCode_GetUnquickened(code_obj, i);
}
int64_t *stacks = PyMem_New(int64_t, len+1);
int i, j, opcode;

if (stacks == NULL) {
PyErr_NoMemory();
Py_DECREF(xxx);
return NULL;
}
for (int i = 1; i <= len; i++) {
Expand DownExpand Up@@ -303,6 +312,7 @@ mark_stacks(PyCodeObject *code_obj, int len)
}
}
}
Py_DECREF(xxx);
return stacks;
}

Expand DownExpand Up@@ -837,9 +847,10 @@ PyFrame_New(PyThreadState *tstate, PyCodeObject *code,
static int
_PyFrame_OpAlreadyRan(_PyInterpreterFrame *frame, int opcode, int oparg)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others.Learn more.

We might be able to remove this entirely, as there should be no way to trace before the firstRESUME.
So don't worry too much if it appears a bit broken.

{
const _Py_CODEUNIT *code = _PyCode_GET_CODE(frame->f_code);
// XXX: Does this handle EXTENDED_ARGs?
for (int i = 0; i < frame->f_lasti; i++) {
if (_Py_OPCODE(code[i]) == opcode && _Py_OPARG(code[i]) == oparg) {
_Py_CODEUNIT instruction = _PyCode_GetUnquickened(frame->f_code, i);
if (instruction == _Py_MAKECODEUNIT(opcode, oparg)) {
return 1;
}
}
Expand Down
10 changes: 4 additions & 6 deletionsObjects/genobject.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -349,17 +349,16 @@ _PyGen_yf(PyGenObject *gen)

if (gen->gi_frame_valid) {
_PyInterpreterFrame *frame = (_PyInterpreterFrame *)gen->gi_iframe;
_Py_CODEUNIT *code = _PyCode_GET_CODE(gen->gi_code);

if (frame->f_lasti < 1) {
/* Return immediately if the frame didn't start yet. SEND
always come after LOAD_CONST: a code object should not start
with SEND */
assert(_Py_OPCODE(code[0]) != SEND);
assert(_Py_OPCODE(_PyCode_GetUnquickened(gen->gi_code, 0)) != SEND);
return NULL;
}

if (_Py_OPCODE(code[frame->f_lasti - 1]) != SEND || frame->stacktop < 0)
if (_Py_OPCODE(_PyCode_GetUnquickened(gen->gi_code,frame->f_lasti - 1)) != SEND || frame->stacktop < 0)
{
return NULL;
}
Expand DownExpand Up@@ -485,12 +484,11 @@ _gen_throw(PyGenObject *gen, int close_on_genexit,
Py_DECREF(ret);
/* Termination repetition of SEND loop */
assert(frame->f_lasti >= 0);
_Py_CODEUNIT *code = _PyCode_GET_CODE(gen->gi_code);
/* Backup to SEND */
frame->f_lasti--;
assert(_Py_OPCODE(code[frame->f_lasti]) == SEND);
assert(_Py_OPCODE(_PyCode_GetUnquickened(gen->gi_code,frame->f_lasti)) == SEND);
// XXX: This doesn't seem to handle EXTENDED_ARGs:
int jump = _Py_OPARG(code[frame->f_lasti]);
int jump = _Py_OPARG(_PyCode_GetUnquickened(gen->gi_code,frame->f_lasti));
frame->f_lasti += jump;
if (_PyGen_FetchStopIterationValue(&val) == 0) {
ret = gen_send(gen, val);
Expand Down
7 changes: 3 additions & 4 deletionsPython/ceval.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -1327,7 +1327,7 @@ eval_frame_handle_pending(PyThreadState *tstate)

/* Get opcode and oparg from original instructions, not quickened form. */
#define TRACING_NEXTOPARG() do { \
_Py_CODEUNIT word =_Py_Unquickened(frame->f_code)[INSTR_OFFSET()]; \
_Py_CODEUNIT word =_PyCode_GetUnquickened(frame->f_code,INSTR_OFFSET()); \
opcode = _Py_OPCODE(word); \
oparg = _Py_OPARG(word); \
} while (0)
Expand DownExpand Up@@ -1568,8 +1568,7 @@ trace_function_exit(PyThreadState *tstate, _PyInterpreterFrame *frame, PyObject
static int
skip_backwards_over_extended_args(PyCodeObject *code, int offset)
{
_Py_CODEUNIT *instrs = _Py_Unquickened(code);
while (offset > 0 && _Py_OPCODE(instrs[offset-1]) == EXTENDED_ARG) {
while (offset > 0 && _Py_OPCODE(_PyCode_GetUnquickened(code, offset - 1)) == EXTENDED_ARG) {
offset--;
}
return offset;
Expand DownExpand Up@@ -6707,7 +6706,7 @@ maybe_call_line_trace(Py_tracefunc func, PyObject *obj,
then call the trace function if we're tracing source lines.
*/
initialize_trace_info(&tstate->trace_info, frame);
_Py_CODEUNIT prev =_Py_Unquickened(frame->f_code)[instr_prev];
_Py_CODEUNIT prev =_PyCode_GetUnquickened(frame->f_code,instr_prev);
int lastline;
if (_Py_OPCODE(prev) == RESUME && _Py_OPARG(prev) == 0) {
lastline = -1;
Expand Down
20 changes: 5 additions & 15 deletionsPython/specialize.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -340,22 +340,12 @@ _Py_Quicken(PyCodeObject *code)
}
}

_Py_CODEUNIT *
_Py_Unquickened(PyCodeObject *code)
_Py_CODEUNIT
_PyCode_GetUnquickened(PyCodeObject *code, int i)
{
_Py_CODEUNIT *instructions = _PyCode_GET_CODE(code);
if (code->co_warmup == 0) {
_Py_QuickenedCount--;
for (Py_ssize_t i = 0; i < Py_SIZE(code); i++) {
int opcode = _PyOpcode_Deoptimizations[_Py_OPCODE(instructions[i])];
instructions[i] = _Py_MAKECODEUNIT(opcode, _Py_OPARG(instructions[i]));
int cache_entries = _PyOpcode_InlineCacheEntries[opcode];
while (cache_entries--) {
instructions[++i] = _Py_MAKECODEUNIT(CACHE, 0);
}
}
}
return instructions;
_Py_CODEUNIT instruction = _PyCode_GET_CODE(code)[i];
int opcode = _PyOpcode_Deoptimizations[_Py_OPCODE(instruction)];
return _Py_MAKECODEUNIT(opcode, _Py_OPARG(instruction));
}

static inline int
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp