added Python syntax version of cycles

This commit is contained in:
Darren Ranalli 2008-08-26 23:06:34 +00:00
parent 7cb642fc2f
commit b8523833f7

View File

@ -6,6 +6,7 @@ from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.showbase.PythonUtil import gcDebugOn, safeRepr, fastRepr, printListEnumGen, printNumberedTypesGen from direct.showbase.PythonUtil import gcDebugOn, safeRepr, fastRepr, printListEnumGen, printNumberedTypesGen
from direct.showbase.Job import Job from direct.showbase.Job import Job
import gc import gc
import types
class FakeObject: class FakeObject:
pass pass
@ -89,6 +90,7 @@ class GarbageReport(Job):
self.referentsByNumber = {} self.referentsByNumber = {}
self.cycles = [] self.cycles = []
self.cyclesBySyntax = []
self.uniqueCycleSets = set() self.uniqueCycleSets = set()
self.cycleIds = set() self.cycleIds = set()
@ -131,6 +133,85 @@ class GarbageReport(Job):
for newCycles in self._getCycles(i, self.uniqueCycleSets): for newCycles in self._getCycles(i, self.uniqueCycleSets):
yield None yield None
self.cycles.extend(newCycles) self.cycles.extend(newCycles)
# create a representation of the cycle in human-readable form
newCyclesBySyntax = []
for cycle in newCycles:
cycleBySyntax = ''
objs = []
# leave off the last index, it's a repeat of the first index
for index in cycle[:-1]:
objs.append(self.garbage[index])
yield None
# make the list repeat so we can safely iterate off the end
numObjs = len(objs) - 1
objs.extend(objs)
# state variables for our loop below
numToSkip = 0
objAlreadyRepresented = False
# if cycle starts off with an instance dict, start with the instance instead
startIndex = 0
endIndex = numObjs
if type(objs[-1]) is types.InstanceType:
startIndex = -1
endIndex = numObjs - 1
for index in xrange(startIndex, endIndex):
if numToSkip:
numToSkip -= 1
continue
obj = objs[index]
if type(obj) is types.InstanceType:
if not objAlreadyRepresented:
cycleBySyntax += '%s' % obj.__class__.__name__
cycleBySyntax += '.'
# skip past the instance dict and get the member obj
numToSkip += 1
member = objs[index+2]
for key, value in obj.__dict__.iteritems():
if value is member:
break
yield None
else:
key = '<unknown member name>'
cycleBySyntax += '%s' % key
objAlreadyRepresented = True
elif type(obj) is types.DictType:
cycleBySyntax += '{'
# get object referred to by dict
val = objs[index+1]
for key, value in obj.iteritems():
if value is val:
break
yield None
else:
key = '<unknown key>'
cycleBySyntax += '%s}' % fastRepr(key)
objAlreadyRepresented = True
elif type(obj) in (types.TupleType, types.ListType):
brackets = {
types.TupleType: '()',
types.ListType: '[]',
}[type(obj)]
# get object being referenced by container
nextObj = objs[index+1]
cycleBySyntax += brackets[0]
for index in xrange(len(obj)):
if obj[index] is nextObj:
index = str(index)
break
yield None
else:
index = '<unknown index>'
cycleBySyntax += '%s%s' % (index, brackets[1])
objAlreadyRepresented = True
else:
cycleBySyntax += '%s->' % itype(obj)
objAlreadyRepresented = False
newCyclesBySyntax.append(cycleBySyntax)
yield None
self.cyclesBySyntax.extend(newCyclesBySyntax)
# if we're not doing a full report, add this cycle's IDs to the master set # if we're not doing a full report, add this cycle's IDs to the master set
if not self._args.fullReport: if not self._args.fullReport:
for cycle in newCycles: for cycle in newCycles:
@ -194,11 +275,17 @@ class GarbageReport(Job):
s.append(format % (idx, itype(self.garbage[idx]), objStr)) s.append(format % (idx, itype(self.garbage[idx]), objStr))
if self._args.findCycles: if self._args.findCycles:
s.append('===== Garbage Cycles =====') s.append('===== Garbage Cycles By Index =====')
for i in xrange(len(self.cycles)): for i in xrange(len(self.cycles)):
yield None yield None
s.append('%s' % self.cycles[i]) s.append('%s' % self.cycles[i])
if self._args.findCycles:
s.append('===== Garbage Cycles By Python Syntax =====')
for i in xrange(len(self.cyclesBySyntax)):
yield None
s.append('%s' % self.cyclesBySyntax[i])
if self._args.fullReport: if self._args.fullReport:
format = '%0' + '%s' % digits + 'i:%s' format = '%0' + '%s' % digits + 'i:%s'
s.append('===== Referrers By Number (what is referring to garbage item?) =====') s.append('===== Referrers By Number (what is referring to garbage item?) =====')