Commit 5d470de5 authored by Stefan Behnel's avatar Stefan Behnel

faster exception handling/try-finally/etc. by inlining exc fetch/restore code

parent b6021cfa
...@@ -951,12 +951,13 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -951,12 +951,13 @@ class FuncDefNode(StatNode, BlockNode):
# so need to save and restore error state # so need to save and restore error state
buffers_present = len(lenv.buffer_entries) > 0 buffers_present = len(lenv.buffer_entries) > 0
if buffers_present: if buffers_present:
code.globalstate.use_utility_code(restore_exception_utility_code)
code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;") code.putln("{ PyObject *__pyx_type, *__pyx_value, *__pyx_tb;")
code.putln("PyErr_Fetch(&__pyx_type, &__pyx_value, &__pyx_tb);") code.putln("__Pyx_ErrFetch(&__pyx_type, &__pyx_value, &__pyx_tb);")
for entry in lenv.buffer_entries: for entry in lenv.buffer_entries:
code.putln("%s;" % Buffer.get_release_buffer_code(entry)) code.putln("%s;" % Buffer.get_release_buffer_code(entry))
#code.putln("%s = 0;" % entry.cname) #code.putln("%s = 0;" % entry.cname)
code.putln("PyErr_Restore(__pyx_type, __pyx_value, __pyx_tb);}") code.putln("__Pyx_ErrRestore(__pyx_type, __pyx_value, __pyx_tb);}")
err_val = self.error_value() err_val = self.error_value()
exc_check = self.caller_will_check_exceptions() exc_check = self.caller_will_check_exceptions()
...@@ -969,6 +970,7 @@ class FuncDefNode(StatNode, BlockNode): ...@@ -969,6 +970,7 @@ class FuncDefNode(StatNode, BlockNode):
'__Pyx_WriteUnraisable("%s");' % '__Pyx_WriteUnraisable("%s");' %
self.entry.qualified_name) self.entry.qualified_name)
env.use_utility_code(unraisable_exception_utility_code) env.use_utility_code(unraisable_exception_utility_code)
env.use_utility_code(restore_exception_utility_code)
default_retval = self.return_type.default_value default_retval = self.return_type.default_value
if err_val is None and default_retval: if err_val is None and default_retval:
err_val = default_retval err_val = default_retval
...@@ -2928,6 +2930,7 @@ class RaiseStatNode(StatNode): ...@@ -2928,6 +2930,7 @@ class RaiseStatNode(StatNode):
if self.exc_tb: if self.exc_tb:
self.exc_tb.release_temp(env) self.exc_tb.release_temp(env)
env.use_utility_code(raise_utility_code) env.use_utility_code(raise_utility_code)
env.use_utility_code(restore_exception_utility_code)
self.gil_check(env) self.gil_check(env)
gil_message = "Raising exception" gil_message = "Raising exception"
...@@ -2982,6 +2985,7 @@ class ReraiseStatNode(StatNode): ...@@ -2982,6 +2985,7 @@ class ReraiseStatNode(StatNode):
def analyse_expressions(self, env): def analyse_expressions(self, env):
self.gil_check(env) self.gil_check(env)
env.use_utility_code(raise_utility_code) env.use_utility_code(raise_utility_code)
env.use_utility_code(restore_exception_utility_code)
gil_message = "Raising exception" gil_message = "Raising exception"
...@@ -3641,6 +3645,7 @@ class ExceptClauseNode(Node): ...@@ -3641,6 +3645,7 @@ class ExceptClauseNode(Node):
for var in self.exc_vars: for var in self.exc_vars:
env.release_temp(var) env.release_temp(var)
env.use_utility_code(get_exception_utility_code) env.use_utility_code(get_exception_utility_code)
env.use_utility_code(restore_exception_utility_code)
def generate_handling_code(self, code, end_label): def generate_handling_code(self, code, end_label):
code.mark_pos(self.pos) code.mark_pos(self.pos)
...@@ -3825,6 +3830,7 @@ class TryFinallyStatNode(StatNode): ...@@ -3825,6 +3830,7 @@ class TryFinallyStatNode(StatNode):
"}") "}")
def put_error_catcher(self, code, error_label, i, catch_label): def put_error_catcher(self, code, error_label, i, catch_label):
code.globalstate.use_utility_code(restore_exception_utility_code)
code.putln( code.putln(
"%s: {" % "%s: {" %
error_label) error_label)
...@@ -3833,7 +3839,7 @@ class TryFinallyStatNode(StatNode): ...@@ -3833,7 +3839,7 @@ class TryFinallyStatNode(StatNode):
i) i)
code.put_var_xdecrefs_clear(self.cleanup_list) code.put_var_xdecrefs_clear(self.cleanup_list)
code.putln( code.putln(
"PyErr_Fetch(&%s, &%s, &%s);" % "__Pyx_ErrFetch(&%s, &%s, &%s);" %
Naming.exc_vars) Naming.exc_vars)
code.putln( code.putln(
"%s = %s;" % ( "%s = %s;" % (
...@@ -3846,11 +3852,12 @@ class TryFinallyStatNode(StatNode): ...@@ -3846,11 +3852,12 @@ class TryFinallyStatNode(StatNode):
"}") "}")
def put_error_uncatcher(self, code, i, error_label): def put_error_uncatcher(self, code, i, error_label):
code.globalstate.use_utility_code(restore_exception_utility_code)
code.putln( code.putln(
"case %s: {" % "case %s: {" %
i) i)
code.putln( code.putln(
"PyErr_Restore(%s, %s, %s);" % "__Pyx_ErrRestore(%s, %s, %s);" %
Naming.exc_vars) Naming.exc_vars)
code.putln( code.putln(
"%s = %s;" % ( "%s = %s;" % (
...@@ -4285,7 +4292,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) { ...@@ -4285,7 +4292,7 @@ static void __Pyx_Raise(PyObject *type, PyObject *value, PyObject *tb) {
} }
#endif #endif
} }
PyErr_Restore(type, value, tb); __Pyx_ErrRestore(type, value, tb);
return; return;
raise_error: raise_error:
Py_XDECREF(value); Py_XDECREF(value);
...@@ -4309,7 +4316,7 @@ static void __Pyx_ReRaise(void) { ...@@ -4309,7 +4316,7 @@ static void __Pyx_ReRaise(void) {
Py_XINCREF(type); Py_XINCREF(type);
Py_XINCREF(value); Py_XINCREF(value);
Py_XINCREF(tb); Py_XINCREF(tb);
PyErr_Restore(type, value, tb); __Pyx_ErrRestore(type, value, tb);
} }
"""] """]
...@@ -4559,13 +4566,13 @@ static void __Pyx_WriteUnraisable(const char *name); /*proto*/ ...@@ -4559,13 +4566,13 @@ static void __Pyx_WriteUnraisable(const char *name); /*proto*/
static void __Pyx_WriteUnraisable(const char *name) { static void __Pyx_WriteUnraisable(const char *name) {
PyObject *old_exc, *old_val, *old_tb; PyObject *old_exc, *old_val, *old_tb;
PyObject *ctx; PyObject *ctx;
PyErr_Fetch(&old_exc, &old_val, &old_tb); __Pyx_ErrFetch(&old_exc, &old_val, &old_tb);
#if PY_MAJOR_VERSION < 3 #if PY_MAJOR_VERSION < 3
ctx = PyString_FromString(name); ctx = PyString_FromString(name);
#else #else
ctx = PyUnicode_FromString(name); ctx = PyUnicode_FromString(name);
#endif #endif
PyErr_Restore(old_exc, old_val, old_tb); __Pyx_ErrRestore(old_exc, old_val, old_tb);
if (!ctx) if (!ctx)
ctx = Py_None; ctx = Py_None;
PyErr_WriteUnraisable(ctx); PyErr_WriteUnraisable(ctx);
...@@ -4664,6 +4671,39 @@ bad: ...@@ -4664,6 +4671,39 @@ bad:
'EMPTY_TUPLE' : Naming.empty_tuple, 'EMPTY_TUPLE' : Naming.empty_tuple,
}] }]
restore_exception_utility_code = [
"""
void INLINE __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb); /*proto*/
void INLINE __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb); /*proto*/
""","""
void INLINE __Pyx_ErrRestore(PyObject *type, PyObject *value, PyObject *tb) {
PyObject *tmp_type, *tmp_value, *tmp_tb;
PyThreadState *tstate = PyThreadState_GET();
tmp_type = tstate->curexc_type;
tmp_value = tstate->curexc_value;
tmp_tb = tstate->curexc_traceback;
tstate->curexc_type = type;
tstate->curexc_value = value;
tstate->curexc_traceback = tb;
Py_XDECREF(tmp_type);
Py_XDECREF(tmp_value);
Py_XDECREF(tmp_tb);
}
void INLINE __Pyx_ErrFetch(PyObject **type, PyObject **value, PyObject **tb) {
PyThreadState *tstate = PyThreadState_GET();
*type = tstate->curexc_type;
*value = tstate->curexc_value;
*tb = tstate->curexc_traceback;
tstate->curexc_type = 0;
tstate->curexc_value = 0;
tstate->curexc_traceback = 0;
}
"""]
#------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------
set_vtable_utility_code = [ set_vtable_utility_code = [
...@@ -4758,8 +4798,8 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb); ...@@ -4758,8 +4798,8 @@ static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb);
""",""" ""","""
static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) { static int __Pyx_GetException(PyObject **type, PyObject **value, PyObject **tb) {
PyObject *tmp_type, *tmp_value, *tmp_tb; PyObject *tmp_type, *tmp_value, *tmp_tb;
PyThreadState *tstate = PyThreadState_Get(); PyThreadState *tstate = PyThreadState_GET();
PyErr_Fetch(type, value, tb); __Pyx_ErrFetch(type, value, tb);
PyErr_NormalizeException(type, value, tb); PyErr_NormalizeException(type, value, tb);
if (PyErr_Occurred()) if (PyErr_Occurred())
goto bad; goto bad;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment