Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(262)

Side by Side Diff: lib/html/scripts/databasebuilder.py

Issue 10987042: Speed up fremontcut/dartdomgenerator (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: One more fix Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file 2 # Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
3 # for details. All rights reserved. Use of this source code is governed by a 3 # for details. All rights reserved. Use of this source code is governed by a
4 # BSD-style license that can be found in the LICENSE file. 4 # BSD-style license that can be found in the LICENSE file.
5 5
6 import copy 6 import copy
7 import database 7 import database
8 import idlparser 8 import idlparser
9 import logging 9 import logging
10 import multiprocessing
10 import os 11 import os
11 import os.path 12 import os.path
12 import re 13 import re
13 14
14 from idlnode import * 15 from idlnode import *
15 16
16 _logger = logging.getLogger('databasebuilder') 17 _logger = logging.getLogger('databasebuilder')
17 18
18 # Used in source annotations to specify the parent interface declaring 19 # Used in source annotations to specify the parent interface declaring
19 # a displaced declaration. The 'via' attribute specifies the parent interface 20 # a displaced declaration. The 'via' attribute specifies the parent interface
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 self.source_attributes = source_attributes 57 self.source_attributes = source_attributes
57 self.idl_syntax = idl_syntax 58 self.idl_syntax = idl_syntax
58 self.idl_defines = idl_defines 59 self.idl_defines = idl_defines
59 self.type_rename_map = type_rename_map 60 self.type_rename_map = type_rename_map
60 self.rename_operation_arguments_on_merge = \ 61 self.rename_operation_arguments_on_merge = \
61 rename_operation_arguments_on_merge 62 rename_operation_arguments_on_merge
62 self.add_new_interfaces = add_new_interfaces 63 self.add_new_interfaces = add_new_interfaces
63 self.obsolete_old_declarations = obsolete_old_declarations 64 self.obsolete_old_declarations = obsolete_old_declarations
64 65
65 66
67 def _load_idl_file(file_name, import_options, result_queue):
68 """Loads an IDL file into memory"""
69 idl_parser = idlparser.IDLParser(import_options.idl_syntax)
70
71 try:
72 f = open(file_name, 'r')
73 content = f.read()
74 f.close()
75
76 idl_ast = idl_parser.parse(
77 content,
78 defines=import_options.idl_defines)
79 result = IDLFile(idl_ast, file_name)
80 result_queue.put(result, False)
81 return 0
82 except SyntaxError, e:
83 result_queue.put(RuntimeError('Failed to load file %s: %s' % (file_name, e)) ,
Anton Muhin 2012/09/26 17:53:09 nit: is line too long? I am personally fine with
vsm 2012/09/28 16:17:25 Done.
84 False)
85 return 1
86 except:
87 result_queue.put('Unknown error loading %s' % file_name, False)
88 return 1
89
66 class DatabaseBuilder(object): 90 class DatabaseBuilder(object):
67 def __init__(self, database): 91 def __init__(self, database):
68 """DatabaseBuilder is used for importing and merging interfaces into 92 """DatabaseBuilder is used for importing and merging interfaces into
69 the Database""" 93 the Database"""
70 self._database = database 94 self._database = database
71 self._imported_interfaces = [] 95 self._imported_interfaces = []
72 self._impl_stmts = [] 96 self._impl_stmts = []
73 97
74 def _load_idl_file(self, file_name, import_options):
75 """Loads an IDL file intor memory"""
76 idl_parser = idlparser.IDLParser(import_options.idl_syntax)
77
78 try:
79 f = open(file_name, 'r')
80 content = f.read()
81 f.close()
82
83 idl_ast = idl_parser.parse(content,
84 defines=import_options.idl_defines)
85 return IDLFile(idl_ast, file_name)
86 except SyntaxError, e:
87 raise RuntimeError('Failed to load file %s: %s' % (file_name, e))
88
89 def _resolve_type_defs(self, idl_file): 98 def _resolve_type_defs(self, idl_file):
90 type_def_map = {} 99 type_def_map = {}
91 # build map 100 # build map
92 for type_def in idl_file.all(IDLTypeDef): 101 for type_def in idl_file.all(IDLTypeDef):
93 if type_def.type.id != type_def.id: # sanity check 102 if type_def.type.id != type_def.id: # sanity check
94 type_def_map[type_def.id] = type_def.type.id 103 type_def_map[type_def.id] = type_def.type.id
95 # use the map 104 # use the map
96 for type_node in idl_file.all(IDLType): 105 for type_node in idl_file.all(IDLType):
97 while type_node.id in type_def_map: 106 while type_node.id in type_def_map:
98 type_node.id = type_def_map[type_node.id] 107 type_node.id = type_def_map[type_node.id]
99 108
100 def _strip_ext_attributes(self, idl_file): 109 def _strip_ext_attributes(self, idl_file):
101 """Strips unuseful extended attributes.""" 110 """Strips unuseful extended attributes."""
102 for ext_attrs in idl_file.all(IDLExtAttrs): 111 for ext_attrs in idl_file.all(IDLExtAttrs):
103 # TODO: Decide which attributes are uninteresting. 112 # TODO: Decide which attributes are uninteresting.
104 pass 113 pass
105 114
106 def _rename_types(self, idl_file, import_options): 115 def _rename_types(self, idl_file, import_options):
107 """Rename interface and type names with names provided in the 116 """Rename interface and type names with names provided in the
108 options. Also clears scopes from scoped names""" 117 options. Also clears scopes from scoped names"""
109 118
110 def rename(name): 119 def rename(name):
111 name_parts = name.split('::') 120 name_parts = name.split('::')
112 name = name_parts[-1] 121 name = name_parts[-1]
113 if name in import_options.type_rename_map: 122 if name in import_options.type_rename_map:
114 name = import_options.type_rename_map[name] 123 name = import_options.type_rename_map[name]
115 return name 124 return name
116 125
117 def rename_node(idl_node): 126 def rename_node(idl_node):
118 idl_node.id = rename(idl_node.id) 127 new_name = rename(idl_node.id)
128 if new_name != idl_node.id:
129 idl_node.id = new_name
130 if isinstance(idl_node, IDLInterface):
Anton Muhin 2012/09/26 17:53:09 up to you, but might be more natural to have a met
vsm 2012/09/28 16:17:25 Done.
131 idl_node.doc_js_name = new_name
Anton Muhin 2012/09/26 17:53:09 I am not familiar with this part of the system, bu
vsm 2012/09/28 16:17:25 It's a little confusing, but the renaming during d
132 idl_node.javascript_binding_name = new_name
133 for member in idl_node.operations:
134 member.doc_js_interface_name = new_name
135 for member in idl_node.attributes:
136 member.doc_js_interface_name = new_name
137 for member in idl_node.constants:
138 member.doc_js_interface_name = new_name
119 139
120 def rename_ext_attrs(ext_attrs_node): 140 def rename_ext_attrs(ext_attrs_node):
121 for type_valued_attribute_name in ['Supplemental']: 141 for type_valued_attribute_name in ['Supplemental']:
122 if type_valued_attribute_name in ext_attrs_node: 142 if type_valued_attribute_name in ext_attrs_node:
123 value = ext_attrs_node[type_valued_attribute_name] 143 value = ext_attrs_node[type_valued_attribute_name]
124 if isinstance(value, str): 144 if isinstance(value, str):
125 ext_attrs_node[type_valued_attribute_name] = rename(value) 145 ext_attrs_node[type_valued_attribute_name] = rename(value)
126 146
127 map(rename_node, idl_file.all(IDLInterface)) 147 map(rename_node, idl_file.all(IDLInterface))
128 map(rename_node, idl_file.all(IDLType)) 148 map(rename_node, idl_file.all(IDLType))
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 not new_interface.is_supplemental): 335 not new_interface.is_supplemental):
316 old_interface.annotations[source] = new_interface.annotations[source] 336 old_interface.annotations[source] = new_interface.annotations[source]
317 changed = True 337 changed = True
318 338
319 def merge_list(what): 339 def merge_list(what):
320 old_list = old_interface.__dict__[what] 340 old_list = old_interface.__dict__[what]
321 new_list = new_interface.__dict__[what] 341 new_list = new_interface.__dict__[what]
322 342
323 if what != 'parents' and old_interface.id != new_interface.id: 343 if what != 'parents' and old_interface.id != new_interface.id:
324 for node in new_list: 344 for node in new_list:
345 node.doc_js_interface_name = old_interface.id
325 node.ext_attrs['ImplementedBy'] = new_interface.id 346 node.ext_attrs['ImplementedBy'] = new_interface.id
326 347
327 changed = self._merge_nodes(old_list, new_list, import_options) 348 changed = self._merge_nodes(old_list, new_list, import_options)
328 349
329 # Delete list items with zero remaining annotations. 350 # Delete list items with zero remaining annotations.
330 if changed and import_options.obsolete_old_declarations: 351 if changed and import_options.obsolete_old_declarations:
331 352
332 def has_annotations(idl_node): 353 def has_annotations(idl_node):
333 return len(idl_node.annotations) 354 return len(idl_node.annotations)
334 355
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
414 else: 435 else:
415 raise Exception("Supplemental target '%s' not found", target) 436 raise Exception("Supplemental target '%s' not found", target)
416 437
417 # Step 4: Resolve 'implements' statements 438 # Step 4: Resolve 'implements' statements
418 for impl_stmt, import_options in self._impl_stmts: 439 for impl_stmt, import_options in self._impl_stmts:
419 self._merge_impl_stmt(impl_stmt, import_options) 440 self._merge_impl_stmt(impl_stmt, import_options)
420 441
421 self._impl_stmts = [] 442 self._impl_stmts = []
422 self._imported_interfaces = [] 443 self._imported_interfaces = []
423 444
424 def import_idl_file(self, file_path, 445 def import_idl_files(self, file_paths, import_options):
425 import_options=DatabaseBuilderOptions()): 446 # Parse the IDL files in parallel.
426 """Parses, loads into memory and cleans up and IDL file""" 447 result_queue = multiprocessing.Queue(len(file_paths))
427 idl_file = self._load_idl_file(file_path, import_options) 448 jobs = [ multiprocessing.Process(target=_load_idl_file,
449 args=(file_path, import_options,
450 result_queue))
451 for file_path in file_paths ]
452 for job in jobs:
453 job.start()
454 try:
455 for job in jobs:
456 # Timeout and throw after 5 sec.
457 result = result_queue.get(True, 5)
458 if isinstance(result, IDLFile):
459 self._process_idl_file(result, import_options)
460 else:
461 raise result
462 except:
463 # Clean up child processes on error.
464 for job in jobs:
465 job.terminate()
Anton Muhin 2012/09/26 17:53:09 if you just terminate the parent process, will it
vsm 2012/09/28 16:17:25 Not clear from the docs if start can throw. I've
466 raise
428 467
468 def _process_idl_file(self, idl_file,
469 import_options):
429 self._strip_ext_attributes(idl_file) 470 self._strip_ext_attributes(idl_file)
430 self._resolve_type_defs(idl_file) 471 self._resolve_type_defs(idl_file)
431 self._rename_types(idl_file, import_options) 472 self._rename_types(idl_file, import_options)
432 473
433 def enabled(idl_node): 474 def enabled(idl_node):
434 return self._is_node_enabled(idl_node, import_options.idl_defines) 475 return self._is_node_enabled(idl_node, import_options.idl_defines)
435 476
436 for module in idl_file.modules: 477 for module in idl_file.modules:
437 for interface in module.interfaces: 478 for interface in module.interfaces:
438 if not self._is_node_enabled(interface, import_options.idl_defines): 479 if not self._is_node_enabled(interface, import_options.idl_defines):
439 _logger.info('skipping interface %s/%s (source=%s file=%s)' 480 _logger.info('skipping interface %s/%s (source=%s)'
440 % (module.id, interface.id, import_options.source, 481 % (module.id, interface.id, import_options.source))
441 file_path))
442 continue 482 continue
443 483
444 _logger.info('importing interface %s/%s (source=%s file=%s)' 484 _logger.info('importing interface %s/%s (source=%s)'
445 % (module.id, interface.id, import_options.source, 485 % (module.id, interface.id, import_options.source))
446 file_path))
447 interface.attributes = filter(enabled, interface.attributes) 486 interface.attributes = filter(enabled, interface.attributes)
448 interface.operations = filter(enabled, interface.operations) 487 interface.operations = filter(enabled, interface.operations)
449 self._imported_interfaces.append((interface, module.id, import_options)) 488 self._imported_interfaces.append((interface, module.id, import_options))
450 489
451 for implStmt in module.implementsStatements: 490 for implStmt in module.implementsStatements:
452 self._impl_stmts.append((implStmt, import_options)) 491 self._impl_stmts.append((implStmt, import_options))
453 492
454 def _is_node_enabled(self, node, idl_defines): 493 def _is_node_enabled(self, node, idl_defines):
455 if not 'Conditional' in node.ext_attrs: 494 if not 'Conditional' in node.ext_attrs:
456 return True 495 return True
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and fetch 589 # TODO(antonm): Ideally we'd like to have pristine copy of WebKit IDLs and fetch
551 # this information directly from it. Unfortunately right now database is massaged 590 # this information directly from it. Unfortunately right now database is massaged
552 # a lot so it's difficult to maintain necessary information on DOMWindow i tself. 591 # a lot so it's difficult to maintain necessary information on DOMWindow i tself.
553 interface = self._database.GetInterface(options.type_rename_map.get(type, type)) 592 interface = self._database.GetInterface(options.type_rename_map.get(type, type))
554 if 'V8EnabledPerContext' in attr.ext_attrs: 593 if 'V8EnabledPerContext' in attr.ext_attrs:
555 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \ 594 interface.ext_attrs['synthesizedV8EnabledPerContext'] = \
556 attr.ext_attrs['V8EnabledPerContext'] 595 attr.ext_attrs['V8EnabledPerContext']
557 if 'V8EnabledAtRuntime' in attr.ext_attrs: 596 if 'V8EnabledAtRuntime' in attr.ext_attrs:
558 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \ 597 interface.ext_attrs['synthesizedV8EnabledAtRuntime'] = \
559 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id 598 attr.ext_attrs['V8EnabledAtRuntime'] or attr.id
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698