From 7542c621d4273f5ea075c1127e5dbdb33ff6677f Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 16 Jan 2017 17:18:53 +0100 Subject: Optimize _PyCFunction_FastCallKeywords() Issue #29259: Write fast path in _PyCFunction_FastCallKeywords() for METH_FASTCALL, avoid the creation of a temporary dictionary for keyword arguments. Cleanup also _PyCFunction_FastCallDict(): * Don't dereference func before checking that it's not NULL * Move code to raise the "no keyword argument" exception into a new no_keyword_error label. Update python-gdb.py for the change. --- Tools/gdb/libpython.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'Tools/gdb') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index cc1afbe16d..88fb0aa7b0 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1518,7 +1518,8 @@ class Frame(object): except RuntimeError: return 'PyCFunction invocation (unable to read "func")' - elif caller == '_PyCFunction_FastCallDict': + elif caller in {'_PyCFunction_FastCallDict', + '_PyCFunction_FastCallKeywords'}: try: func = older._gdbframe.read_var('func_obj') return str(func) -- cgit v1.2.1 From 994fae95a192c9e1571e9410c81d828a85d84095 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Jan 2017 13:49:43 +0100 Subject: Fix Python 2.6 support in python-gdb.py Issue #29259. --- Tools/gdb/libpython.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'Tools/gdb') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 88fb0aa7b0..5c59b99942 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1518,8 +1518,8 @@ class Frame(object): except RuntimeError: return 'PyCFunction invocation (unable to read "func")' - elif caller in {'_PyCFunction_FastCallDict', - '_PyCFunction_FastCallKeywords'}: + elif caller in ('_PyCFunction_FastCallDict', + '_PyCFunction_FastCallKeywords'): try: func = older._gdbframe.read_var('func_obj') return str(func) -- cgit v1.2.1 From 9674949696574bee9ae2bc3b9b56c30ea12285c0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 18 Jan 2017 17:20:01 +0100 Subject: Update and enhance python-gdb.py Issue #29259: * Detect PyCFunction is the current frame, not only in the older frame * Ignore PyCFunction_Call() since it now calls _PyCFunction_FastCallDict(), and _PyCFunction_FastCallDict() is already detected --- Tools/gdb/libpython.py | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'Tools/gdb') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 5c59b99942..0903c01766 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1497,15 +1497,17 @@ class Frame(object): return 'Garbage-collecting' # Detect invocations of PyCFunction instances: - older = self.older() - if not older: - return False - - caller = older._gdbframe.name() + frame = self._gdbframe + caller = frame.name() if not caller: return False - if caller == 'PyCFunction_Call': + if caller in ('_PyCFunction_FastCallDict', + '_PyCFunction_FastCallKeywords'): + if caller == '_PyCFunction_FastCallKeywords': + arg_name = 'func_obj' + else: + arg_name = 'func' # Within that frame: # "func" is the local containing the PyObject* of the # PyCFunctionObject instance @@ -1513,18 +1515,10 @@ class Frame(object): # "self" is the (PyObject*) of the 'self' try: # Use the prettyprinter for the func: - func = older._gdbframe.read_var('func') - return str(func) - except RuntimeError: - return 'PyCFunction invocation (unable to read "func")' - - elif caller in ('_PyCFunction_FastCallDict', - '_PyCFunction_FastCallKeywords'): - try: - func = older._gdbframe.read_var('func_obj') + func = frame.read_var(arg_name) return str(func) except RuntimeError: - return 'PyCFunction invocation (unable to read "func_obj")' + return 'PyCFunction invocation (unable to read %s)' % arg_name # This frame isn't worth reporting: return False -- cgit v1.2.1 From fba5031c50d359d3d1531ab88f19f2e8b6d4531b Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Wed, 1 Feb 2017 16:29:54 +0100 Subject: python-gdb.py supports method-wrapper Issue #29367: python-gdb.py now supports also method-wrapper (wrapperobject) objects. --- Tools/gdb/libpython.py | 53 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 48 insertions(+), 5 deletions(-) (limited to 'Tools/gdb') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index 0903c01766..cca9741ced 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -362,6 +362,7 @@ class PyObjectPtr(object): 'set' : PySetObjectPtr, 'frozenset' : PySetObjectPtr, 'builtin_function_or_method' : PyCFunctionObjectPtr, + 'method-wrapper': wrapperobject, } if tp_name in name_map: return name_map[tp_name] @@ -1330,6 +1331,39 @@ class PyUnicodeObjectPtr(PyObjectPtr): out.write(quote) +class wrapperobject(PyObjectPtr): + _typename = 'wrapperobject' + + def safe_name(self): + try: + name = self.field('descr')['d_base']['name'].string() + return repr(name) + except (NullPyObjectPtr, RuntimeError): + return '' + + def safe_tp_name(self): + try: + return self.field('self')['ob_type']['tp_name'].string() + except (NullPyObjectPtr, RuntimeError): + return '' + + def safe_self_addresss(self): + try: + address = long(self.field('self')) + return '%#x' % address + except (NullPyObjectPtr, RuntimeError): + return '' + + def proxyval(self, visited): + name = self.safe_name() + tp_name = self.safe_tp_name() + self_address = self.safe_self_addresss() + return ("" + % (name, tp_name, self_address)) + + def write_repr(self, out, visited): + proxy = self.proxyval(visited) + out.write(proxy) def int_from_int(gdbval): @@ -1364,11 +1398,13 @@ class PyObjectPtrPrinter: def pretty_printer_lookup(gdbval): type = gdbval.type.unqualified() - if type.code == gdb.TYPE_CODE_PTR: - type = type.target().unqualified() - t = str(type) - if t in ("PyObject", "PyFrameObject", "PyUnicodeObject"): - return PyObjectPtrPrinter(gdbval) + if type.code != gdb.TYPE_CODE_PTR: + return None + + type = type.target().unqualified() + t = str(type) + if t in ("PyObject", "PyFrameObject", "PyUnicodeObject", "wrapperobject"): + return PyObjectPtrPrinter(gdbval) """ During development, I've been manually invoking the code in this way: @@ -1520,6 +1556,13 @@ class Frame(object): except RuntimeError: return 'PyCFunction invocation (unable to read %s)' % arg_name + if caller == 'wrapper_call': + try: + func = frame.read_var('wp') + return str(func) + except RuntimeError: + return '' + # This frame isn't worth reporting: return False -- cgit v1.2.1 From 99c092a531abf57a8f5c37356dc6971cdfed497a Mon Sep 17 00:00:00 2001 From: INADA Naoki Date: Fri, 3 Feb 2017 07:43:03 +0900 Subject: Issue #29263: LOAD_METHOD support for C methods Calling builtin method is at most 10% faster. --- Tools/gdb/libpython.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'Tools/gdb') diff --git a/Tools/gdb/libpython.py b/Tools/gdb/libpython.py index cca9741ced..4f45256188 100755 --- a/Tools/gdb/libpython.py +++ b/Tools/gdb/libpython.py @@ -1540,10 +1540,7 @@ class Frame(object): if caller in ('_PyCFunction_FastCallDict', '_PyCFunction_FastCallKeywords'): - if caller == '_PyCFunction_FastCallKeywords': - arg_name = 'func_obj' - else: - arg_name = 'func' + arg_name = 'func' # Within that frame: # "func" is the local containing the PyObject* of the # PyCFunctionObject instance -- cgit v1.2.1