diff options
author | Mark Shannon <mark@hotpy.org> | 2021-05-07 14:19:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-05-07 14:19:19 (GMT) |
commit | adcd2205565f91c6719f4141ab4e1da6d7086126 (patch) | |
tree | 0953b285944eccde57b05b8f3c7e30fb501a3d64 /Include | |
parent | b32c8e97951db46484ba3b646b988bcdc4062199 (diff) | |
download | cpython-adcd2205565f91c6719f4141ab4e1da6d7086126.zip cpython-adcd2205565f91c6719f4141ab4e1da6d7086126.tar.gz cpython-adcd2205565f91c6719f4141ab4e1da6d7086126.tar.bz2 |
bpo-40222: "Zero cost" exception handling (GH-25729)
"Zero cost" exception handling.
* Uses a lookup table to determine how to handle exceptions.
* Removes SETUP_FINALLY and POP_TOP block instructions, eliminating (most of) the runtime overhead of try statements.
* Reduces the size of the frame object by about 60%.
Diffstat (limited to 'Include')
-rw-r--r-- | Include/cpython/code.h | 5 | ||||
-rw-r--r-- | Include/cpython/frameobject.h | 15 | ||||
-rw-r--r-- | Include/opcode.h | 25 |
3 files changed, 17 insertions, 28 deletions
diff --git a/Include/cpython/code.h b/Include/cpython/code.h index e810eb4..330f1f5 100644 --- a/Include/cpython/code.h +++ b/Include/cpython/code.h @@ -40,6 +40,7 @@ struct PyCodeObject { PyObject *co_name; /* unicode (name, for reference) */ PyObject *co_linetable; /* string (encoding addr<->lineno mapping) See Objects/lnotab_notes.txt for details. */ + PyObject *co_exceptiontable; /* Byte string encoding exception handling table */ void *co_zombieframe; /* for optimization only (see frameobject.c) */ PyObject *co_weakreflist; /* to support weakrefs to code objects */ /* Scratch space for extra data relating to the code object. @@ -117,12 +118,12 @@ PyAPI_DATA(PyTypeObject) PyCode_Type; PyAPI_FUNC(PyCodeObject *) PyCode_New( int, int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, - PyObject *, PyObject *, int, PyObject *); + PyObject *, PyObject *, int, PyObject *, PyObject *); PyAPI_FUNC(PyCodeObject *) PyCode_NewWithPosOnlyArgs( int, int, int, int, int, int, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, PyObject *, - PyObject *, PyObject *, int, PyObject *); + PyObject *, PyObject *, int, PyObject *, PyObject *); /* same as struct above */ /* Creates a new empty code object with the specified source location. */ diff --git a/Include/cpython/frameobject.h b/Include/cpython/frameobject.h index 5122ec4..0c2206c0 100644 --- a/Include/cpython/frameobject.h +++ b/Include/cpython/frameobject.h @@ -34,18 +34,14 @@ struct _frame { PyObject *f_locals; /* local symbol table (any mapping) */ PyObject **f_valuestack; /* points after the last local */ PyObject *f_trace; /* Trace function */ - int f_stackdepth; /* Depth of value stack */ - char f_trace_lines; /* Emit per-line trace events? */ - char f_trace_opcodes; /* Emit per-opcode trace events? */ - /* Borrowed reference to a generator, or NULL */ PyObject *f_gen; - + int f_stackdepth; /* Depth of value stack */ int f_lasti; /* Last instruction if called */ int f_lineno; /* Current line number. Only valid if non-zero */ - int f_iblock; /* index in f_blockstack */ PyFrameState f_state; /* What state the frame is in */ - PyTryBlock f_blockstack[CO_MAXBLOCKS]; /* for try and loop blocks */ + char f_trace_lines; /* Emit per-line trace events? */ + char f_trace_opcodes; /* Emit per-opcode trace events? */ PyObject *f_localsplus[1]; /* locals+stack, dynamically sized */ }; @@ -77,11 +73,6 @@ _PyFrame_New_NoTrack(PyThreadState *, PyFrameConstructor *, PyObject *); /* The rest of the interface is specific for frame objects */ -/* Block management functions */ - -PyAPI_FUNC(void) PyFrame_BlockSetup(PyFrameObject *, int, int, int); -PyAPI_FUNC(PyTryBlock *) PyFrame_BlockPop(PyFrameObject *); - /* Conversions between "fast locals" and locals in dictionary */ PyAPI_FUNC(void) PyFrame_LocalsToFast(PyFrameObject *, int); diff --git a/Include/opcode.h b/Include/opcode.h index 5203975..1e44e1f 100644 --- a/Include/opcode.h +++ b/Include/opcode.h @@ -35,10 +35,13 @@ extern "C" { #define MATCH_SEQUENCE 32 #define MATCH_KEYS 33 #define COPY_DICT_WITHOUT_KEYS 34 +#define PUSH_EXC_INFO 35 +#define POP_EXCEPT_AND_RERAISE 37 #define WITH_EXCEPT_START 49 #define GET_AITER 50 #define GET_ANEXT 51 #define BEFORE_ASYNC_WITH 52 +#define BEFORE_WITH 53 #define END_ASYNC_FOR 54 #define INPLACE_ADD 55 #define INPLACE_SUBTRACT 56 @@ -69,7 +72,6 @@ extern "C" { #define IMPORT_STAR 84 #define SETUP_ANNOTATIONS 85 #define YIELD_VALUE 86 -#define POP_BLOCK 87 #define POP_EXCEPT 89 #define HAVE_ARGUMENT 90 #define STORE_NAME 90 @@ -103,7 +105,6 @@ extern "C" { #define CONTAINS_OP 118 #define RERAISE 119 #define JUMP_IF_NOT_EXC_MATCH 121 -#define SETUP_FINALLY 122 #define LOAD_FAST 124 #define STORE_FAST 125 #define DELETE_FAST 126 @@ -118,14 +119,12 @@ extern "C" { #define DELETE_DEREF 138 #define CALL_FUNCTION_KW 141 #define CALL_FUNCTION_EX 142 -#define SETUP_WITH 143 #define EXTENDED_ARG 144 #define LIST_APPEND 145 #define SET_ADD 146 #define MAP_ADD 147 #define LOAD_CLASSDEREF 148 #define MATCH_CLASS 152 -#define SETUP_ASYNC_WITH 154 #define FORMAT_VALUE 155 #define BUILD_CONST_KEY_MAP 156 #define BUILD_STRING 157 @@ -140,8 +139,8 @@ static uint32_t _PyOpcode_RelativeJump[8] = { 0U, 0U, 536870912U, - 67125248U, - 67141632U, + 16384U, + 0U, 0U, 0U, 0U, @@ -150,22 +149,20 @@ static uint32_t _PyOpcode_Jump[8] = { 0U, 0U, 536870912U, - 101695488U, - 67141632U, + 34586624U, + 0U, 0U, 0U, 0U, }; #endif /* OPCODE_TABLES */ -/* EXCEPT_HANDLER is a special, implicit block type which is created when - entering an except handler. It is not an opcode but we define it here - as we want it to be available to both frameobject.c and ceval.c, while - remaining private.*/ -#define EXCEPT_HANDLER 257 - #define HAS_ARG(op) ((op) >= HAVE_ARGUMENT) +/* Reserve some bytecodes for internal use in the compiler. + * The value of 240 is arbitrary. */ +#define IS_ARTIFICIAL(op) ((op) > 240) + #ifdef __cplusplus } #endif |