Load any missing fresh modules needed to process a stale SCC
(graph: Graph, ascc: SCC, manager: BuildManager)
| 4706 | |
| 4707 | |
| 4708 | def maybe_load_deps(graph: Graph, ascc: SCC, manager: BuildManager) -> None: |
| 4709 | """Load any missing fresh modules needed to process a stale SCC""" |
| 4710 | missing_sccs = set() |
| 4711 | sccs_to_find = ascc.deps.copy() |
| 4712 | while sccs_to_find: |
| 4713 | dep_scc = sccs_to_find.pop() |
| 4714 | if dep_scc in manager.done_sccs or dep_scc in missing_sccs: |
| 4715 | continue |
| 4716 | missing_sccs.add(dep_scc) |
| 4717 | sccs_to_find.update(manager.scc_by_id[dep_scc].deps) |
| 4718 | |
| 4719 | if missing_sccs: |
| 4720 | # Load missing SCCs from cache. |
| 4721 | # TODO: speed-up ordering if this causes problems for large builds. |
| 4722 | fresh_sccs_to_load = [ |
| 4723 | manager.scc_by_id[sid] for sid in manager.top_order if sid in missing_sccs |
| 4724 | ] |
| 4725 | |
| 4726 | if manager.parallel_worker: |
| 4727 | # Update cache metas as well, cache data is loaded below |
| 4728 | # in process_fresh_modules(). |
| 4729 | for prev_scc in fresh_sccs_to_load: |
| 4730 | for mod_id in prev_scc.mod_ids: |
| 4731 | graph[mod_id].reload_meta() |
| 4732 | |
| 4733 | manager.log(f"Processing {len(fresh_sccs_to_load)} fresh SCCs") |
| 4734 | if ( |
| 4735 | not manager.options.test_env |
| 4736 | and platform.python_implementation() == "CPython" |
| 4737 | and manager.gc_freeze_cycles < MAX_GC_FREEZE_CYCLES |
| 4738 | ): |
| 4739 | # When deserializing cache we create huge amount of new objects, so even |
| 4740 | # with our generous GC thresholds, GC is still doing a lot of pointless |
| 4741 | # work searching for garbage. So, we temporarily disable it when |
| 4742 | # processing fresh SCCs, and then move all the new objects to the oldest |
| 4743 | # generation with the freeze()/unfreeze() trick below. This is arguably |
| 4744 | # a hack, but it gives huge performance wins for large third-party |
| 4745 | # libraries, like torch. |
| 4746 | gc.disable() |
| 4747 | for prev_scc in fresh_sccs_to_load: |
| 4748 | manager.done_sccs.add(prev_scc.id) |
| 4749 | process_fresh_modules(graph, sorted(prev_scc.mod_ids), manager) |
| 4750 | if ( |
| 4751 | not manager.options.test_env |
| 4752 | and platform.python_implementation() == "CPython" |
| 4753 | and manager.gc_freeze_cycles < MAX_GC_FREEZE_CYCLES |
| 4754 | ): |
| 4755 | manager.gc_freeze_cycles += 1 |
| 4756 | gc.freeze() |
| 4757 | gc.unfreeze() |
| 4758 | gc.enable() |
| 4759 | |
| 4760 | |
| 4761 | def process_stale_scc(graph: Graph, ascc: SCC, manager: BuildManager) -> None: |
no test coverage detected
searching dependent graphs…