summaryrefslogtreecommitdiffstats
path: root/Include
diff options
context:
space:
mode:
authorMark Shannon <mark@hotpy.org>2021-05-07 14:19:19 (GMT)
committerGitHub <noreply@github.com>2021-05-07 14:19:19 (GMT)
commitadcd2205565f91c6719f4141ab4e1da6d7086126 (patch)
tree0953b285944eccde57b05b8f3c7e30fb501a3d64 /Include
parentb32c8e97951db46484ba3b646b988bcdc4062199 (diff)
downloadcpython-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.h5
-rw-r--r--Include/cpython/frameobject.h15
-rw-r--r--Include/opcode.h25
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