Skip to content

Commit 1500ec1

Browse files
sokraeps1lon
authored andcommitted
Turbopack: reduce the amount of task modifications caused by recomputation (#78728)
### What? Improve backend code to avoid flagging a task as modified when it is just recomputed without changes.
1 parent 679afec commit 1500ec1

File tree

1 file changed

+54
-47
lines changed
  • turbopack/crates/turbo-tasks-backend/src/backend

1 file changed

+54
-47
lines changed

turbopack/crates/turbo-tasks-backend/src/backend/mod.rs

Lines changed: 54 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,8 @@ use crate::{
5656
backing_storage::BackingStorage,
5757
data::{
5858
ActivenessState, AggregationNumber, CachedDataItem, CachedDataItemKey, CachedDataItemType,
59-
CachedDataItemValue, CachedDataItemValueRef, CellRef, CollectibleRef, CollectiblesRef,
60-
DirtyState, InProgressCellState, InProgressState, InProgressStateInner, OutputValue,
61-
RootType,
59+
CachedDataItemValueRef, CellRef, CollectibleRef, CollectiblesRef, DirtyState,
60+
InProgressCellState, InProgressState, InProgressStateInner, OutputValue, RootType,
6261
},
6362
utils::{
6463
bi_map::BiMap, chunked_vec::ChunkedVec, ptr_eq_arc::PtrEqArc, sharded::Sharded, swap_retain,
@@ -422,7 +421,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
422421
}
423422

424423
let mut ctx = self.execute_context(turbo_tasks);
425-
let mut task = ctx.task(task_id, TaskDataCategory::All);
424+
let mut task = ctx.task(task_id, TaskDataCategory::Meta);
426425

427426
fn listen_to_done_event<B: BackingStorage>(
428427
this: &TurboTasksBackendInner<B>,
@@ -493,7 +492,7 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
493492
&mut ctx,
494493
);
495494
}
496-
task = ctx.task(task_id, TaskDataCategory::All);
495+
task = ctx.task(task_id, TaskDataCategory::Meta);
497496
}
498497

499498
let is_dirty =
@@ -1552,10 +1551,16 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
15521551

15531552
// Remove no longer existing cells and
15541553
// find all outdated data items (removed cells, outdated edges)
1555-
removed_data.extend(task.extract_if(CachedDataItemType::CellData, |key, _| {
1556-
matches!(key, CachedDataItemKey::CellData { cell } if cell_counters
1557-
.get(&cell.type_id).is_none_or(|start_index| cell.index >= *start_index))
1558-
}));
1554+
// Note: For persistent tasks we only want to call extract_if when there are actual cells to
1555+
// remove to avoid tracking that as modification.
1556+
if task_id.is_transient() || iter_many!(task, CellData { cell }
1557+
if cell_counters.get(&cell.type_id).is_none_or(|start_index| cell.index >= *start_index) => cell
1558+
).count() > 0 {
1559+
removed_data.extend(task.extract_if(CachedDataItemType::CellData, |key, _| {
1560+
matches!(key, CachedDataItemKey::CellData { cell } if cell_counters
1561+
.get(&cell.type_id).is_none_or(|start_index| cell.index >= *start_index))
1562+
}));
1563+
}
15591564
if self.should_track_children() {
15601565
old_edges.extend(
15611566
task.iter(CachedDataItemType::OutdatedCollectible)
@@ -1708,6 +1713,8 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
17081713
));
17091714

17101715
// Update the dirty state
1716+
let old_dirty_state = get!(task, Dirty).copied();
1717+
17111718
let new_dirty_state = if session_dependent {
17121719
Some(DirtyState {
17131720
clean_in_session: Some(self.session_id),
@@ -1716,48 +1723,48 @@ impl<B: BackingStorage> TurboTasksBackendInner<B> {
17161723
None
17171724
};
17181725

1719-
let old_dirty = if let Some(new_dirty_state) = new_dirty_state {
1720-
task.insert(CachedDataItem::Dirty {
1721-
value: new_dirty_state,
1722-
})
1723-
} else {
1724-
task.remove(&CachedDataItemKey::Dirty {})
1725-
};
1726-
1727-
let old_dirty_state = old_dirty.map(|old_dirty| match old_dirty {
1728-
CachedDataItemValue::Dirty { value } => value,
1729-
_ => unreachable!(),
1730-
});
1731-
1732-
let data_update = if self.should_track_children()
1733-
&& (old_dirty_state.is_some() || new_dirty_state.is_some())
1734-
{
1735-
let mut dirty_containers = get!(task, AggregatedDirtyContainerCount)
1736-
.cloned()
1737-
.unwrap_or_default();
1738-
if let Some(old_dirty_state) = old_dirty_state {
1739-
dirty_containers.update_with_dirty_state(&old_dirty_state);
1726+
let data_update = if old_dirty_state != new_dirty_state {
1727+
if let Some(new_dirty_state) = new_dirty_state {
1728+
task.insert(CachedDataItem::Dirty {
1729+
value: new_dirty_state,
1730+
});
1731+
} else {
1732+
task.remove(&CachedDataItemKey::Dirty {});
17401733
}
1741-
let aggregated_update = match (old_dirty_state, new_dirty_state) {
1742-
(None, None) => unreachable!(),
1743-
(Some(old), None) => dirty_containers.undo_update_with_dirty_state(&old),
1744-
(None, Some(new)) => dirty_containers.update_with_dirty_state(&new),
1745-
(Some(old), Some(new)) => dirty_containers.replace_dirty_state(&old, &new),
1746-
};
1747-
if !aggregated_update.is_zero() {
1748-
if aggregated_update.get(self.session_id) < 0 {
1749-
if let Some(root_state) = get_mut!(task, Activeness) {
1750-
root_state.all_clean_event.notify(usize::MAX);
1751-
root_state.unset_active_until_clean();
1752-
if root_state.is_empty() {
1753-
task.remove(&CachedDataItemKey::Activeness {});
1734+
1735+
if self.should_track_children()
1736+
&& (old_dirty_state.is_some() || new_dirty_state.is_some())
1737+
{
1738+
let mut dirty_containers = get!(task, AggregatedDirtyContainerCount)
1739+
.cloned()
1740+
.unwrap_or_default();
1741+
if let Some(old_dirty_state) = old_dirty_state {
1742+
dirty_containers.update_with_dirty_state(&old_dirty_state);
1743+
}
1744+
let aggregated_update = match (old_dirty_state, new_dirty_state) {
1745+
(None, None) => unreachable!(),
1746+
(Some(old), None) => dirty_containers.undo_update_with_dirty_state(&old),
1747+
(None, Some(new)) => dirty_containers.update_with_dirty_state(&new),
1748+
(Some(old), Some(new)) => dirty_containers.replace_dirty_state(&old, &new),
1749+
};
1750+
if !aggregated_update.is_zero() {
1751+
if aggregated_update.get(self.session_id) < 0 {
1752+
if let Some(root_state) = get_mut!(task, Activeness) {
1753+
root_state.all_clean_event.notify(usize::MAX);
1754+
root_state.unset_active_until_clean();
1755+
if root_state.is_empty() {
1756+
task.remove(&CachedDataItemKey::Activeness {});
1757+
}
17541758
}
17551759
}
1760+
AggregationUpdateJob::data_update(
1761+
&mut task,
1762+
AggregatedDataUpdate::new()
1763+
.dirty_container_update(task_id, aggregated_update),
1764+
)
1765+
} else {
1766+
None
17561767
}
1757-
AggregationUpdateJob::data_update(
1758-
&mut task,
1759-
AggregatedDataUpdate::new().dirty_container_update(task_id, aggregated_update),
1760-
)
17611768
} else {
17621769
None
17631770
}

0 commit comments

Comments
 (0)