1use std::cell::RefCell;
43use std::cmp::max;
44use std::marker::PhantomData;
45use std::sync::Arc;
46use std::sync::atomic::Ordering;
47use std::{iter, mem, u64};
48
49use rustc_data_structures::fingerprint::{Fingerprint, PackedFingerprint};
50use rustc_data_structures::fx::FxHashMap;
51use rustc_data_structures::outline;
52use rustc_data_structures::profiling::SelfProfilerRef;
53use rustc_data_structures::sync::{AtomicU64, Lock, WorkerLocal, broadcast};
54use rustc_data_structures::unhash::UnhashMap;
55use rustc_index::IndexVec;
56use rustc_serialize::opaque::mem_encoder::MemEncoder;
57use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixedSize, MemDecoder};
58use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
59use rustc_session::Session;
60use tracing::{debug, instrument};
61
62use super::graph::{CurrentDepGraph, DepNodeColor, DepNodeColorMap};
63use super::query::DepGraphQuery;
64use super::{DepKind, DepNode, DepNodeIndex, Deps};
65use crate::dep_graph::edges::EdgesVec;
66
67rustc_index::newtype_index! {
71 #[encodable]
72 #[max = 0x7FFF_FFFF]
73 pub struct SerializedDepNodeIndex {}
74}
75
76const DEP_NODE_SIZE: usize = size_of::<SerializedDepNodeIndex>();
77const DEP_NODE_PAD: usize = DEP_NODE_SIZE - 1;
80const DEP_NODE_WIDTH_BITS: usize = DEP_NODE_SIZE / 2;
85
86#[derive(Debug, Default)]
91pub struct SerializedDepGraph {
92 nodes: IndexVec<SerializedDepNodeIndex, DepNode>,
94 fingerprints: IndexVec<SerializedDepNodeIndex, Fingerprint>,
97 edge_list_indices: IndexVec<SerializedDepNodeIndex, EdgeHeader>,
101 edge_list_data: Vec<u8>,
104 index: Vec<UnhashMap<PackedFingerprint, SerializedDepNodeIndex>>,
107 session_count: u64,
110}
111
112impl SerializedDepGraph {
113 #[inline]
114 pub fn edge_targets_from(
115 &self,
116 source: SerializedDepNodeIndex,
117 ) -> impl Iterator<Item = SerializedDepNodeIndex> + Clone {
118 let header = self.edge_list_indices[source];
119 let mut raw = &self.edge_list_data[header.start()..];
120
121 let bytes_per_index = header.bytes_per_index();
122
123 let mask = header.mask();
125 (0..header.num_edges).map(move |_| {
126 let index = &raw[..DEP_NODE_SIZE];
129 raw = &raw[bytes_per_index..];
130 let index = u32::from_le_bytes(index.try_into().unwrap()) & mask;
131 SerializedDepNodeIndex::from_u32(index)
132 })
133 }
134
135 #[inline]
136 pub fn index_to_node(&self, dep_node_index: SerializedDepNodeIndex) -> DepNode {
137 self.nodes[dep_node_index]
138 }
139
140 #[inline]
141 pub fn node_to_index_opt(&self, dep_node: &DepNode) -> Option<SerializedDepNodeIndex> {
142 self.index.get(dep_node.kind.as_usize())?.get(&dep_node.hash).cloned()
143 }
144
145 #[inline]
146 pub fn fingerprint_by_index(&self, dep_node_index: SerializedDepNodeIndex) -> Fingerprint {
147 self.fingerprints[dep_node_index]
148 }
149
150 #[inline]
151 pub fn node_count(&self) -> usize {
152 self.nodes.len()
153 }
154
155 #[inline]
156 pub fn session_count(&self) -> u64 {
157 self.session_count
158 }
159}
160
161#[derive(Debug, Clone, Copy)]
166struct EdgeHeader {
167 repr: usize,
168 num_edges: u32,
169}
170
171impl EdgeHeader {
172 #[inline]
173 fn start(self) -> usize {
174 self.repr >> DEP_NODE_WIDTH_BITS
175 }
176
177 #[inline]
178 fn bytes_per_index(self) -> usize {
179 (self.repr & mask(DEP_NODE_WIDTH_BITS)) + 1
180 }
181
182 #[inline]
183 fn mask(self) -> u32 {
184 mask(self.bytes_per_index() * 8) as u32
185 }
186}
187
188#[inline]
189fn mask(bits: usize) -> usize {
190 usize::MAX >> ((size_of::<usize>() * 8) - bits)
191}
192
193impl SerializedDepGraph {
194 #[instrument(level = "debug", skip(d, deps))]
195 pub fn decode<D: Deps>(d: &mut MemDecoder<'_>, deps: &D) -> Arc<SerializedDepGraph> {
196 debug!("position: {:?}", d.position());
198
199 let (node_max, node_count, edge_count) =
202 d.with_position(d.len() - 3 * IntEncodedWithFixedSize::ENCODED_SIZE, |d| {
203 debug!("position: {:?}", d.position());
204 let node_max = IntEncodedWithFixedSize::decode(d).0 as usize;
205 let node_count = IntEncodedWithFixedSize::decode(d).0 as usize;
206 let edge_count = IntEncodedWithFixedSize::decode(d).0 as usize;
207 (node_max, node_count, edge_count)
208 });
209 debug!("position: {:?}", d.position());
210
211 debug!(?node_count, ?edge_count);
212
213 let graph_bytes = d.len() - (3 * IntEncodedWithFixedSize::ENCODED_SIZE) - d.position();
214
215 let mut nodes = IndexVec::from_elem_n(
216 DepNode { kind: D::DEP_KIND_NULL, hash: PackedFingerprint::from(Fingerprint::ZERO) },
217 node_max,
218 );
219 let mut fingerprints = IndexVec::from_elem_n(Fingerprint::ZERO, node_max);
220 let mut edge_list_indices =
221 IndexVec::from_elem_n(EdgeHeader { repr: 0, num_edges: 0 }, node_max);
222
223 let mut edge_list_data =
233 Vec::with_capacity(graph_bytes - node_count * size_of::<SerializedNodeHeader<D>>());
234
235 for _ in 0..node_count {
236 let node_header =
239 SerializedNodeHeader::<D> { bytes: d.read_array(), _marker: PhantomData };
240
241 let index = node_header.index();
242
243 let node = &mut nodes[index];
244 assert!(node_header.node().kind != D::DEP_KIND_NULL && node.kind == D::DEP_KIND_NULL);
246 *node = node_header.node();
247
248 fingerprints[index] = node_header.fingerprint();
249
250 let num_edges = node_header.len().unwrap_or_else(|| d.read_u32());
253
254 let edges_len_bytes = node_header.bytes_per_index() * (num_edges as usize);
258 let edges_header = node_header.edges_header(&edge_list_data, num_edges);
261
262 edge_list_data.extend(d.read_raw_bytes(edges_len_bytes));
263
264 edge_list_indices[index] = edges_header;
265 }
266
267 edge_list_data.extend(&[0u8; DEP_NODE_PAD]);
271
272 let mut index: Vec<_> = (0..(D::DEP_KIND_MAX + 1))
274 .map(|_| UnhashMap::with_capacity_and_hasher(d.read_u32() as usize, Default::default()))
275 .collect();
276
277 let session_count = d.read_u64();
278
279 for (idx, node) in nodes.iter_enumerated() {
280 if index[node.kind.as_usize()].insert(node.hash, idx).is_some() {
281 if node.kind != D::DEP_KIND_NULL && node.kind != D::DEP_KIND_SIDE_EFFECT {
283 let name = deps.name(node.kind);
284 panic!(
285 "Error: A dep graph node ({name}) does not have an unique index. \
286 Running a clean build on a nightly compiler with `-Z incremental-verify-ich` \
287 can help narrow down the issue for reporting. A clean build may also work around the issue.\n
288 DepNode: {node:?}"
289 )
290 }
291 }
292 }
293
294 Arc::new(SerializedDepGraph {
295 nodes,
296 fingerprints,
297 edge_list_indices,
298 edge_list_data,
299 index,
300 session_count,
301 })
302 }
303}
304
305struct SerializedNodeHeader<D> {
314 bytes: [u8; 38],
319 _marker: PhantomData<D>,
320}
321
322struct Unpacked {
325 len: Option<u32>,
326 bytes_per_index: usize,
327 kind: DepKind,
328 index: SerializedDepNodeIndex,
329 hash: PackedFingerprint,
330 fingerprint: Fingerprint,
331}
332
333impl<D: Deps> SerializedNodeHeader<D> {
341 const TOTAL_BITS: usize = size_of::<DepKind>() * 8;
342 const LEN_BITS: usize = Self::TOTAL_BITS - Self::KIND_BITS - Self::WIDTH_BITS;
343 const WIDTH_BITS: usize = DEP_NODE_WIDTH_BITS;
344 const KIND_BITS: usize = Self::TOTAL_BITS - D::DEP_KIND_MAX.leading_zeros() as usize;
345 const MAX_INLINE_LEN: usize = (u16::MAX as usize >> (Self::TOTAL_BITS - Self::LEN_BITS)) - 1;
346
347 #[inline]
348 fn new(
349 node: DepNode,
350 index: DepNodeIndex,
351 fingerprint: Fingerprint,
352 edge_max_index: u32,
353 edge_count: usize,
354 ) -> Self {
355 debug_assert_eq!(Self::TOTAL_BITS, Self::LEN_BITS + Self::WIDTH_BITS + Self::KIND_BITS);
356
357 let mut head = node.kind.as_inner();
358
359 let free_bytes = edge_max_index.leading_zeros() as usize / 8;
360 let bytes_per_index = (DEP_NODE_SIZE - free_bytes).saturating_sub(1);
361 head |= (bytes_per_index as u16) << Self::KIND_BITS;
362
363 if edge_count <= Self::MAX_INLINE_LEN {
366 head |= (edge_count as u16 + 1) << (Self::KIND_BITS + Self::WIDTH_BITS);
367 }
368
369 let hash: Fingerprint = node.hash.into();
370
371 let mut bytes = [0u8; 38];
373 bytes[..2].copy_from_slice(&head.to_le_bytes());
374 bytes[2..6].copy_from_slice(&index.as_u32().to_le_bytes());
375 bytes[6..22].copy_from_slice(&hash.to_le_bytes());
376 bytes[22..].copy_from_slice(&fingerprint.to_le_bytes());
377
378 #[cfg(debug_assertions)]
379 {
380 let res = Self { bytes, _marker: PhantomData };
381 assert_eq!(fingerprint, res.fingerprint());
382 assert_eq!(node, res.node());
383 if let Some(len) = res.len() {
384 assert_eq!(edge_count, len as usize);
385 }
386 }
387 Self { bytes, _marker: PhantomData }
388 }
389
390 #[inline]
391 fn unpack(&self) -> Unpacked {
392 let head = u16::from_le_bytes(self.bytes[..2].try_into().unwrap());
393 let index = u32::from_le_bytes(self.bytes[2..6].try_into().unwrap());
394 let hash = self.bytes[6..22].try_into().unwrap();
395 let fingerprint = self.bytes[22..].try_into().unwrap();
396
397 let kind = head & mask(Self::KIND_BITS) as u16;
398 let bytes_per_index = (head >> Self::KIND_BITS) & mask(Self::WIDTH_BITS) as u16;
399 let len = (head as u32) >> (Self::WIDTH_BITS + Self::KIND_BITS);
400
401 Unpacked {
402 len: len.checked_sub(1),
403 bytes_per_index: bytes_per_index as usize + 1,
404 kind: DepKind::new(kind),
405 index: SerializedDepNodeIndex::from_u32(index),
406 hash: Fingerprint::from_le_bytes(hash).into(),
407 fingerprint: Fingerprint::from_le_bytes(fingerprint),
408 }
409 }
410
411 #[inline]
412 fn len(&self) -> Option<u32> {
413 self.unpack().len
414 }
415
416 #[inline]
417 fn bytes_per_index(&self) -> usize {
418 self.unpack().bytes_per_index
419 }
420
421 #[inline]
422 fn index(&self) -> SerializedDepNodeIndex {
423 self.unpack().index
424 }
425
426 #[inline]
427 fn fingerprint(&self) -> Fingerprint {
428 self.unpack().fingerprint
429 }
430
431 #[inline]
432 fn node(&self) -> DepNode {
433 let Unpacked { kind, hash, .. } = self.unpack();
434 DepNode { kind, hash }
435 }
436
437 #[inline]
438 fn edges_header(&self, edge_list_data: &[u8], num_edges: u32) -> EdgeHeader {
439 EdgeHeader {
440 repr: (edge_list_data.len() << DEP_NODE_WIDTH_BITS) | (self.bytes_per_index() - 1),
441 num_edges,
442 }
443 }
444}
445
446#[derive(Debug)]
447struct NodeInfo {
448 node: DepNode,
449 fingerprint: Fingerprint,
450 edges: EdgesVec,
451}
452
453impl NodeInfo {
454 fn encode<D: Deps>(&self, e: &mut MemEncoder, index: DepNodeIndex) {
455 let NodeInfo { node, fingerprint, ref edges } = *self;
456 let header = SerializedNodeHeader::<D>::new(
457 node,
458 index,
459 fingerprint,
460 edges.max_index(),
461 edges.len(),
462 );
463 e.write_array(header.bytes);
464
465 if header.len().is_none() {
466 e.emit_u32(edges.len().try_into().unwrap());
468 }
469
470 let bytes_per_index = header.bytes_per_index();
471 for node_index in edges.iter() {
472 e.write_with(|dest| {
473 *dest = node_index.as_u32().to_le_bytes();
474 bytes_per_index
475 });
476 }
477 }
478
479 #[inline]
483 fn encode_promoted<D: Deps>(
484 e: &mut MemEncoder,
485 node: DepNode,
486 index: DepNodeIndex,
487 fingerprint: Fingerprint,
488 prev_index: SerializedDepNodeIndex,
489 colors: &DepNodeColorMap,
490 previous: &SerializedDepGraph,
491 ) -> usize {
492 let edges = previous.edge_targets_from(prev_index);
493 let edge_count = edges.size_hint().0;
494
495 let edge_max =
497 edges.clone().map(|i| colors.current(i).unwrap().as_u32()).max().unwrap_or(0);
498
499 let header = SerializedNodeHeader::<D>::new(node, index, fingerprint, edge_max, edge_count);
500 e.write_array(header.bytes);
501
502 if header.len().is_none() {
503 e.emit_u32(edge_count.try_into().unwrap());
505 }
506
507 let bytes_per_index = header.bytes_per_index();
508 for node_index in edges {
509 let node_index = colors.current(node_index).unwrap();
510 e.write_with(|dest| {
511 *dest = node_index.as_u32().to_le_bytes();
512 bytes_per_index
513 });
514 }
515
516 edge_count
517 }
518}
519
520struct Stat {
521 kind: DepKind,
522 node_counter: u64,
523 edge_counter: u64,
524}
525
526struct LocalEncoderState {
527 next_node_index: u32,
528 remaining_node_index: u32,
529 encoder: MemEncoder,
530 node_count: usize,
531 edge_count: usize,
532
533 kind_stats: Vec<u32>,
535}
536
537struct LocalEncoderResult {
538 node_max: u32,
539 node_count: usize,
540 edge_count: usize,
541
542 kind_stats: Vec<u32>,
544}
545
546struct EncoderState<D: Deps> {
547 next_node_index: AtomicU64,
548 previous: Arc<SerializedDepGraph>,
549 file: Lock<Option<FileEncoder>>,
550 local: WorkerLocal<RefCell<LocalEncoderState>>,
551 stats: Option<Lock<FxHashMap<DepKind, Stat>>>,
552 marker: PhantomData<D>,
553}
554
555impl<D: Deps> EncoderState<D> {
556 fn new(encoder: FileEncoder, record_stats: bool, previous: Arc<SerializedDepGraph>) -> Self {
557 Self {
558 previous,
559 next_node_index: AtomicU64::new(0),
560 stats: record_stats.then(|| Lock::new(FxHashMap::default())),
561 file: Lock::new(Some(encoder)),
562 local: WorkerLocal::new(|_| {
563 RefCell::new(LocalEncoderState {
564 next_node_index: 0,
565 remaining_node_index: 0,
566 edge_count: 0,
567 node_count: 0,
568 encoder: MemEncoder::new(),
569 kind_stats: iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect(),
570 })
571 }),
572 marker: PhantomData,
573 }
574 }
575
576 #[inline]
577 fn next_index(&self, local: &mut LocalEncoderState) -> DepNodeIndex {
578 if local.remaining_node_index == 0 {
579 const COUNT: u32 = 256;
580
581 local.next_node_index =
585 self.next_node_index.fetch_add(COUNT as u64, Ordering::Relaxed).try_into().unwrap();
586
587 local.next_node_index.checked_add(COUNT).unwrap();
589
590 local.remaining_node_index = COUNT;
591 }
592
593 DepNodeIndex::from_u32(local.next_node_index)
594 }
595
596 #[inline]
598 fn bump_index(&self, local: &mut LocalEncoderState) {
599 local.remaining_node_index -= 1;
600 local.next_node_index += 1;
601 local.node_count += 1;
602 }
603
604 #[inline]
605 fn record(
606 &self,
607 node: DepNode,
608 index: DepNodeIndex,
609 edge_count: usize,
610 edges: impl FnOnce(&Self) -> Vec<DepNodeIndex>,
611 record_graph: &Option<Lock<DepGraphQuery>>,
612 local: &mut LocalEncoderState,
613 ) {
614 local.kind_stats[node.kind.as_usize()] += 1;
615 local.edge_count += edge_count;
616
617 if let Some(record_graph) = &record_graph {
618 let edges = edges(self);
620
621 outline(move || {
623 if let Some(record_graph) = &mut record_graph.try_lock() {
625 record_graph.push(index, node, &edges);
626 }
627 });
628 }
629
630 if let Some(stats) = &self.stats {
631 let kind = node.kind;
632
633 outline(move || {
635 let mut stats = stats.lock();
636 let stat =
637 stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 });
638 stat.node_counter += 1;
639 stat.edge_counter += edge_count as u64;
640 });
641 }
642 }
643
644 #[inline]
645 fn flush_mem_encoder(&self, local: &mut LocalEncoderState) {
646 let data = &mut local.encoder.data;
647 if data.len() > 64 * 1024 {
648 self.file.lock().as_mut().unwrap().emit_raw_bytes(&data[..]);
649 data.clear();
650 }
651 }
652
653 fn encode_node(
655 &self,
656 index: DepNodeIndex,
657 node: &NodeInfo,
658 record_graph: &Option<Lock<DepGraphQuery>>,
659 local: &mut LocalEncoderState,
660 ) {
661 node.encode::<D>(&mut local.encoder, index);
662 self.flush_mem_encoder(&mut *local);
663 self.record(
664 node.node,
665 index,
666 node.edges.len(),
667 |_| node.edges[..].to_vec(),
668 record_graph,
669 &mut *local,
670 );
671 }
672
673 #[inline]
680 fn encode_promoted_node(
681 &self,
682 index: DepNodeIndex,
683 prev_index: SerializedDepNodeIndex,
684 record_graph: &Option<Lock<DepGraphQuery>>,
685 colors: &DepNodeColorMap,
686 local: &mut LocalEncoderState,
687 ) {
688 let node = self.previous.index_to_node(prev_index);
689 let fingerprint = self.previous.fingerprint_by_index(prev_index);
690 let edge_count = NodeInfo::encode_promoted::<D>(
691 &mut local.encoder,
692 node,
693 index,
694 fingerprint,
695 prev_index,
696 colors,
697 &self.previous,
698 );
699 self.flush_mem_encoder(&mut *local);
700 self.record(
701 node,
702 index,
703 edge_count,
704 |this| {
705 this.previous
706 .edge_targets_from(prev_index)
707 .map(|i| colors.current(i).unwrap())
708 .collect()
709 },
710 record_graph,
711 &mut *local,
712 );
713 }
714
715 fn finish(&self, profiler: &SelfProfilerRef, current: &CurrentDepGraph<D>) -> FileEncodeResult {
716 self.next_node_index.store(u32::MAX as u64 + 1, Ordering::SeqCst);
718
719 let results = broadcast(|_| {
720 let mut local = self.local.borrow_mut();
721
722 local.remaining_node_index = 0;
724
725 let data = mem::replace(&mut local.encoder.data, Vec::new());
726 self.file.lock().as_mut().unwrap().emit_raw_bytes(&data);
727
728 LocalEncoderResult {
729 kind_stats: local.kind_stats.clone(),
730 node_max: local.next_node_index,
731 node_count: local.node_count,
732 edge_count: local.edge_count,
733 }
734 });
735
736 let mut encoder = self.file.lock().take().unwrap();
737
738 let mut kind_stats: Vec<u32> = iter::repeat(0).take(D::DEP_KIND_MAX as usize + 1).collect();
739
740 let mut node_max = 0;
741 let mut node_count = 0;
742 let mut edge_count = 0;
743
744 for result in results {
745 node_max = max(node_max, result.node_max);
746 node_count += result.node_count;
747 edge_count += result.edge_count;
748 for (i, stat) in result.kind_stats.iter().enumerate() {
749 kind_stats[i] += stat;
750 }
751 }
752
753 for count in kind_stats.iter() {
755 count.encode(&mut encoder);
756 }
757
758 self.previous.session_count.checked_add(1).unwrap().encode(&mut encoder);
759
760 debug!(?node_max, ?node_count, ?edge_count);
761 debug!("position: {:?}", encoder.position());
762 IntEncodedWithFixedSize(node_max.try_into().unwrap()).encode(&mut encoder);
763 IntEncodedWithFixedSize(node_count.try_into().unwrap()).encode(&mut encoder);
764 IntEncodedWithFixedSize(edge_count.try_into().unwrap()).encode(&mut encoder);
765 debug!("position: {:?}", encoder.position());
766 let result = encoder.finish();
768 if let Ok(position) = result {
769 profiler.artifact_size("dep_graph", "dep-graph.bin", position as u64);
772 }
773
774 self.print_incremental_info(current, node_count, edge_count);
775
776 result
777 }
778
779 fn print_incremental_info(
780 &self,
781 current: &CurrentDepGraph<D>,
782 total_node_count: usize,
783 total_edge_count: usize,
784 ) {
785 if let Some(record_stats) = &self.stats {
786 let record_stats = record_stats.lock();
787 let mut stats: Vec<_> = record_stats.values().collect();
788 stats.sort_by_key(|s| -(s.node_counter as i64));
789
790 const SEPARATOR: &str = "[incremental] --------------------------------\
791 ----------------------------------------------\
792 ------------";
793
794 eprintln!("[incremental]");
795 eprintln!("[incremental] DepGraph Statistics");
796 eprintln!("{SEPARATOR}");
797 eprintln!("[incremental]");
798 eprintln!("[incremental] Total Node Count: {}", total_node_count);
799 eprintln!("[incremental] Total Edge Count: {}", total_edge_count);
800
801 if cfg!(debug_assertions) {
802 let total_read_count = current.total_read_count.load(Ordering::Relaxed);
803 let total_duplicate_read_count =
804 current.total_duplicate_read_count.load(Ordering::Relaxed);
805 eprintln!("[incremental] Total Edge Reads: {total_read_count}");
806 eprintln!("[incremental] Total Duplicate Edge Reads: {total_duplicate_read_count}");
807 }
808
809 eprintln!("[incremental]");
810 eprintln!(
811 "[incremental] {:<36}| {:<17}| {:<12}| {:<17}|",
812 "Node Kind", "Node Frequency", "Node Count", "Avg. Edge Count"
813 );
814 eprintln!("{SEPARATOR}");
815
816 for stat in stats {
817 let node_kind_ratio =
818 (100.0 * (stat.node_counter as f64)) / (total_node_count as f64);
819 let node_kind_avg_edges = (stat.edge_counter as f64) / (stat.node_counter as f64);
820
821 eprintln!(
822 "[incremental] {:<36}|{:>16.1}% |{:>12} |{:>17.1} |",
823 format!("{:?}", stat.kind),
824 node_kind_ratio,
825 stat.node_counter,
826 node_kind_avg_edges,
827 );
828 }
829
830 eprintln!("{SEPARATOR}");
831 eprintln!("[incremental]");
832 }
833 }
834}
835
836pub(crate) struct GraphEncoder<D: Deps> {
837 profiler: SelfProfilerRef,
838 status: EncoderState<D>,
839 record_graph: Option<Lock<DepGraphQuery>>,
840}
841
842impl<D: Deps> GraphEncoder<D> {
843 pub(crate) fn new(
844 sess: &Session,
845 encoder: FileEncoder,
846 prev_node_count: usize,
847 previous: Arc<SerializedDepGraph>,
848 ) -> Self {
849 let record_graph = sess
850 .opts
851 .unstable_opts
852 .query_dep_graph
853 .then(|| Lock::new(DepGraphQuery::new(prev_node_count)));
854 let status = EncoderState::new(encoder, sess.opts.unstable_opts.incremental_info, previous);
855 GraphEncoder { status, record_graph, profiler: sess.prof.clone() }
856 }
857
858 pub(crate) fn with_query(&self, f: impl Fn(&DepGraphQuery)) {
859 if let Some(record_graph) = &self.record_graph {
860 f(&record_graph.lock())
861 }
862 }
863
864 pub(crate) fn send_new(
866 &self,
867 node: DepNode,
868 fingerprint: Fingerprint,
869 edges: EdgesVec,
870 ) -> DepNodeIndex {
871 let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
872 let node = NodeInfo { node, fingerprint, edges };
873 let mut local = self.status.local.borrow_mut();
874 let index = self.status.next_index(&mut *local);
875 self.status.bump_index(&mut *local);
876 self.status.encode_node(index, &node, &self.record_graph, &mut *local);
877 index
878 }
879
880 pub(crate) fn send_and_color(
884 &self,
885 prev_index: SerializedDepNodeIndex,
886 colors: &DepNodeColorMap,
887 node: DepNode,
888 fingerprint: Fingerprint,
889 edges: EdgesVec,
890 is_green: bool,
891 ) -> DepNodeIndex {
892 let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
893 let node = NodeInfo { node, fingerprint, edges };
894
895 let mut local = self.status.local.borrow_mut();
896
897 let index = self.status.next_index(&mut *local);
898
899 if is_green {
900 match colors.try_mark_green(prev_index, index) {
903 Ok(()) => (),
904 Err(dep_node_index) => return dep_node_index,
905 }
906 } else {
907 colors.insert(prev_index, DepNodeColor::Red);
908 }
909
910 self.status.bump_index(&mut *local);
911 self.status.encode_node(index, &node, &self.record_graph, &mut *local);
912 index
913 }
914
915 #[inline]
920 pub(crate) fn send_promoted(
921 &self,
922 prev_index: SerializedDepNodeIndex,
923 colors: &DepNodeColorMap,
924 ) -> DepNodeIndex {
925 let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
926
927 let mut local = self.status.local.borrow_mut();
928 let index = self.status.next_index(&mut *local);
929
930 match colors.try_mark_green(prev_index, index) {
933 Ok(()) => {
934 self.status.bump_index(&mut *local);
935 self.status.encode_promoted_node(
936 index,
937 prev_index,
938 &self.record_graph,
939 colors,
940 &mut *local,
941 );
942 index
943 }
944 Err(dep_node_index) => dep_node_index,
945 }
946 }
947
948 pub(crate) fn finish(&self, current: &CurrentDepGraph<D>) -> FileEncodeResult {
949 let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph_finish");
950
951 self.status.finish(&self.profiler, current)
952 }
953}