Skip to content

Commit

Permalink
fix reading of emptied cells
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Jul 24, 2024
1 parent 583f744 commit f7ec54f
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 8 deletions.
33 changes: 33 additions & 0 deletions crates/turbo-tasks-memory/src/cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,44 @@ impl Cell {
}
}

pub fn empty(
&mut self,
clean: bool,
turbo_tasks: &dyn TurboTasksBackendApi<MemoryBackend>,
) -> Option<CellContent> {
let content = match replace(&mut self.state, CellState::Empty) {
CellState::TrackedValueless | CellState::Empty => None,
CellState::Computing { event } => {
event.notify(usize::MAX);
if clean {
// We can assume that the task is deterministic and produces the same content
// again. No need to notify dependent tasks.
return None;
}
None
}
CellState::Value { content } => Some(content),
};
// Assigning to a cell will invalidate all dependent tasks as the content might
// have changed.
if !self.dependent_tasks.is_empty() {
turbo_tasks.schedule_notify_tasks_set(&self.dependent_tasks);
self.dependent_tasks.clear();
}
content
}

/// Reduces memory needs to the minimum.
pub fn shrink_to_fit(&mut self) {
self.dependent_tasks.shrink_to_fit();
}

/// Returns true if the cell is current not used and could be dropped from
/// the array.
pub fn is_unused(&self) -> bool {
self.dependent_tasks.is_empty() && matches!(self.state, CellState::Empty)
}

/// Takes the content out of the cell. Make sure to drop the content outside
/// of the task state lock.
#[must_use]
Expand Down
31 changes: 23 additions & 8 deletions crates/turbo-tasks-memory/src/task.rs
Original file line number Diff line number Diff line change
Expand Up @@ -963,28 +963,43 @@ impl Task {
.gc
.execution_completed(duration, memory_usage, generation);

for (value_type, cells) in state.cells.iter_mut() {
let counter = cell_counters.get(value_type).copied().unwrap_or_default();
if counter != cells.len() as u32 {
drained_cells.extend(cells.drain(counter as usize..));
}
}
let TaskState {
ref mut cells,
ref mut state_type,
..
} = *state;

let InProgress(box InProgressState {
ref mut done_event,
count_as_finished,
ref mut outdated_edges,
ref mut outdated_collectibles,
ref mut new_children,
clean: _,
clean,
stale,
}) = state.state_type
}) = *state_type
else {
panic!(
"Task execution completed in unexpected state {}",
Task::state_string(&state)
)
};
for (value_type, cells) in cells.iter_mut() {
let counter =
cell_counters.get(value_type).copied().unwrap_or_default() as usize;
let mut is_unused = true;
while counter < cells.len() {
let last = cells.last_mut().unwrap();
last.empty(clean, turbo_tasks);
if is_unused {
if last.is_unused() {
drained_cells.push(cells.pop().unwrap());
} else {
is_unused = false;
}
}
}
}
let done_event = done_event.take();
let outdated_collectibles = outdated_collectibles.take_collectibles();
let mut outdated_edges = take(outdated_edges);
Expand Down

0 comments on commit f7ec54f

Please sign in to comment.