Commit 70abf89f authored by Fred Drake's avatar Fred Drake

Avoid deep recursion when reading the header of the log file.

Add support for extracting function names from the log file, keeping the
extract-names-from-sources support as a fallback.
parent 46530ac9
...@@ -9,6 +9,7 @@ from _hotshot import \ ...@@ -9,6 +9,7 @@ from _hotshot import \
WHAT_EXIT, \ WHAT_EXIT, \
WHAT_LINENO, \ WHAT_LINENO, \
WHAT_DEFINE_FILE, \ WHAT_DEFINE_FILE, \
WHAT_DEFINE_FUNC, \
WHAT_ADD_INFO WHAT_ADD_INFO
...@@ -44,35 +45,40 @@ class LogReader: ...@@ -44,35 +45,40 @@ class LogReader:
# avoids using an additional method call which kills the performance. # avoids using an additional method call which kills the performance.
def next(self, index=0): def next(self, index=0):
try: while 1:
what, tdelta, fileno, lineno = self._nextitem()
except TypeError:
# logreader().next() returns None at the end
self._reader.close()
raise StopIteration()
if what == WHAT_DEFINE_FILE:
self._filemap[fileno] = tdelta
return self.next()
if what == WHAT_ADD_INFO:
key = tdelta.lower()
try: try:
L = self._info[key] what, tdelta, fileno, lineno = self._nextitem()
except KeyError: except TypeError:
L = [] # logreader().next() returns None at the end
self._info[key] = L self._reader.close()
L.append(lineno) raise StopIteration()
if key == "current-directory": if what == WHAT_DEFINE_FILE:
self.cwd = lineno self._filemap[fileno] = tdelta
return self.next() continue
if what == WHAT_ENTER: if what == WHAT_DEFINE_FUNC:
t = self._decode_location(fileno, lineno) filename = self._filemap[fileno]
filename, funcname = t self._funcmap[(fileno, lineno)] = (filename, tdelta)
self._stack.append((filename, funcname, lineno)) continue
elif what == WHAT_EXIT: if what == WHAT_ADD_INFO:
filename, funcname, lineno = self._stack.pop() key = tdelta.lower()
else: try:
filename, funcname, firstlineno = self._stack[-1] L = self._info[key]
return what, (filename, lineno, funcname), tdelta except KeyError:
L = []
self._info[key] = L
L.append(lineno)
if key == "current-directory":
self.cwd = lineno
continue
if what == WHAT_ENTER:
t = self._decode_location(fileno, lineno)
filename, funcname = t
self._stack.append((filename, funcname, lineno))
elif what == WHAT_EXIT:
filename, funcname, lineno = self._stack.pop()
else:
filename, funcname, firstlineno = self._stack[-1]
return what, (filename, lineno, funcname), tdelta
if sys.version < "2.2": if sys.version < "2.2":
# Don't add this for newer Python versions; we only want iteration # Don't add this for newer Python versions; we only want iteration
...@@ -90,6 +96,11 @@ class LogReader: ...@@ -90,6 +96,11 @@ class LogReader:
try: try:
return self._funcmap[(fileno, lineno)] return self._funcmap[(fileno, lineno)]
except KeyError: except KeyError:
#
# This should only be needed when the log file does not
# contain all the DEFINE_FUNC records needed to allow the
# function name to be retrieved from the log file.
#
if self._loadfile(fileno): if self._loadfile(fileno):
filename = funcname = None filename = funcname = None
try: try:
......
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