Bug 867903. Speed up getDescriptors and some other obvious slow points in codegen. r=khuey

This commit is contained in:
Boris Zbarsky 2013-05-09 13:06:48 -04:00
Родитель 96a893b56d
Коммит fb1bdaf8dd
4 изменённых файлов: 41 добавлений и 31 удалений

Просмотреть файл

@ -35,14 +35,11 @@ def main():
configFile = os.path.normpath(args[0])
srcPrefix = os.path.normpath(args[1])
# Load the parsing results
# Load the configuration
f = open('ParserResults.pkl', 'rb')
parserData = cPickle.load(f)
config = cPickle.load(f)
f.close()
# Create the configuration data.
config = Configuration(configFile, parserData)
def readFile(f):
file = open(f, 'rb')
try:

Просмотреть файл

@ -60,6 +60,19 @@ class Configuration:
d.nativeType != descriptor.nativeType or d == descriptor
for d in self.descriptors)
# Keep the descriptor list sorted for determinism.
self.descriptors.sort(lambda x,y: cmp(x.name, y.name))
self.descriptorsByName = {}
for d in self.descriptors:
self.descriptorsByName.setdefault(d.interface.identifier.name,
[]).append(d)
self.descriptorsByFile = {}
for d in self.descriptors:
self.descriptorsByFile.setdefault(d.interface.filename(),
[]).append(d)
self.enums = [e for e in parseData if e.isEnum()]
# Figure out what our main-thread and worker dictionaries and callbacks
@ -90,17 +103,22 @@ class Configuration:
workerDictionaries);
flagWorkerOrMainThread(self.callbacks, mainCallbacks, workerCallbacks)
# Keep the descriptor list sorted for determinism.
self.descriptors.sort(lambda x,y: cmp(x.name, y.name))
def getInterface(self, ifname):
return self.interfaces[ifname]
def getDescriptors(self, **filters):
"""Gets the descriptors that match the given filters."""
curr = self.descriptors
# Collect up our filters, because we may have a webIDLFile filter that
# we always want to apply first.
tofilter = []
for key, val in filters.iteritems():
if key == 'webIDLFile':
getter = lambda x: x.interface.filename()
# Special-case this part to make it fast, since most of our
# getDescriptors calls are conditioned on a webIDLFile. We may
# not have this key, in which case we have no descriptors
# either.
curr = self.descriptorsByFile.get(val, [])
continue
elif key == 'hasInterfaceObject':
getter = lambda x: (not x.interface.isExternal() and
x.interface.hasInterfaceObject())
@ -118,8 +136,12 @@ class Configuration:
elif key == 'isNavigatorProperty':
getter = lambda x: x.interface.getNavigatorProperty() != None
else:
getter = lambda x: getattr(x, key)
curr = filter(lambda x: getter(x) == val, curr)
# Have to watch out: just closing over "key" is not enough,
# since we're about to mutate its value
getter = (lambda attrName: lambda x: getattr(x, attrName))(key)
tofilter.append((getter, val))
for f in tofilter:
curr = filter(lambda x: f[0](x) == f[1], curr)
return curr
def getEnums(self, webIDLFile):
return filter(lambda e: e.filename() == webIDLFile, self.enums)
@ -148,17 +170,11 @@ class Configuration:
Gets the appropriate descriptor for the given interface name
and the given workers boolean.
"""
iface = self.getInterface(interfaceName)
descriptors = self.getDescriptors(interface=iface)
for d in self.descriptorsByName[interfaceName]:
if d.workers == workers:
return d
# The only filter we currently have is workers vs non-workers.
matches = filter(lambda x: x.workers is workers, descriptors)
# After filtering, we should have exactly one result.
if len(matches) is not 1:
raise NoSuchDescriptorError("For " + interfaceName + " found " +
str(len(matches)) + " matches");
return matches[0]
raise NoSuchDescriptorError("For " + interfaceName + " found no matches");
def getDescriptorProvider(self, workers):
"""
Gets a descriptor provider that can provide descriptors as needed,

Просмотреть файл

@ -34,14 +34,11 @@ def main():
configFile = os.path.normpath(args[0])
interfaceName = args[1]
# Load the parsing results
# Load the configuration
f = open('ParserResults.pkl', 'rb')
parserData = cPickle.load(f)
config = cPickle.load(f)
f.close()
# Create the configuration data.
config = Configuration(configFile, parserData)
# Generate the example class.
generate_interface_example(config, interfaceName)

Просмотреть файл

@ -55,14 +55,14 @@ def main():
parser.parse(''.join(lines), fullPath)
parserResults = parser.finish()
# Write the parser results out to a pickle.
resultsFile = open('ParserResults.pkl', 'wb')
cPickle.dump(parserResults, resultsFile, -1)
resultsFile.close()
# Load the configuration.
config = Configuration(configFile, parserResults)
# Write the configuration out to a pickle.
resultsFile = open('ParserResults.pkl', 'wb')
cPickle.dump(config, resultsFile, -1)
resultsFile.close()
# Generate the prototype list.
generate_file(config, 'PrototypeList', 'declare')