@@ -16,7 +16,6 @@ use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, ProcMacroDerive};
16
16
use rustc_hir as hir;
17
17
use rustc_hir:: def:: { CtorKind , CtorOf , DefKind , Res } ;
18
18
use rustc_hir:: def_id:: { CrateNum , DefId , DefIndex , CRATE_DEF_INDEX , LOCAL_CRATE } ;
19
- use rustc_hir:: definitions:: DefPathTable ;
20
19
use rustc_hir:: definitions:: { DefKey , DefPath , DefPathData , DefPathHash } ;
21
20
use rustc_hir:: lang_items;
22
21
use rustc_index:: vec:: { Idx , IndexVec } ;
@@ -29,7 +28,6 @@ use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
29
28
use rustc_middle:: mir:: { self , Body , Promoted } ;
30
29
use rustc_middle:: ty:: codec:: TyDecoder ;
31
30
use rustc_middle:: ty:: { self , Ty , TyCtxt } ;
32
- use rustc_middle:: util:: common:: record_time;
33
31
use rustc_serialize:: { opaque, Decodable , Decoder } ;
34
32
use rustc_session:: Session ;
35
33
use rustc_span:: hygiene:: ExpnDataDecodeMode ;
@@ -69,12 +67,6 @@ crate struct CrateMetadata {
69
67
/// universal (`for<'tcx>`), that is paired up with whichever `TyCtxt`
70
68
/// is being used to decode those values.
71
69
root : CrateRoot < ' static > ,
72
- /// For each definition in this crate, we encode a key. When the
73
- /// crate is loaded, we read all the keys and put them in this
74
- /// hashmap, which gives the reverse mapping. This allows us to
75
- /// quickly retrace a `DefPath`, which is needed for incremental
76
- /// compilation support.
77
- def_path_table : DefPathTable ,
78
70
/// Trait impl data.
79
71
/// FIXME: Used only from queries and can use query cache,
80
72
/// so pre-decoding can probably be avoided.
@@ -91,6 +83,10 @@ crate struct CrateMetadata {
91
83
/// Do not access the value directly, as it might not have been initialized yet.
92
84
/// The field must always be initialized to `DepNodeIndex::INVALID`.
93
85
dep_node_index : AtomicCell < DepNodeIndex > ,
86
+ /// Caches decoded `DefKey`s.
87
+ def_key_cache : Lock < FxHashMap < DefIndex , DefKey > > ,
88
+ /// Caches decoded `DefPathHash`es.
89
+ def_path_hash_cache : Lock < FxHashMap < DefIndex , DefPathHash > > ,
94
90
95
91
// --- Other significant crate properties ---
96
92
/// ID of this crate, from the current compilation session's point of view.
@@ -807,7 +803,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
807
803
data. has_auto_impl ,
808
804
data. is_marker ,
809
805
data. specialization_kind ,
810
- self . def_path_table . def_path_hash ( item_id) ,
806
+ self . def_path_hash ( item_id) ,
811
807
)
812
808
}
813
809
EntryKind :: TraitAlias => ty:: TraitDef :: new (
@@ -817,7 +813,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
817
813
false ,
818
814
false ,
819
815
ty:: trait_def:: TraitSpecializationKind :: None ,
820
- self . def_path_table . def_path_hash ( item_id) ,
816
+ self . def_path_hash ( item_id) ,
821
817
) ,
822
818
_ => bug ! ( "def-index does not refer to trait or trait alias" ) ,
823
819
}
@@ -1509,12 +1505,14 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1509
1505
1510
1506
#[ inline]
1511
1507
fn def_key ( & self , index : DefIndex ) -> DefKey {
1512
- let mut key = self . def_path_table . def_key ( index) ;
1513
- if self . is_proc_macro ( index) {
1514
- let name = self . raw_proc_macro ( index) . name ( ) ;
1515
- key. disambiguated_data . data = DefPathData :: MacroNs ( Symbol :: intern ( name) ) ;
1516
- }
1517
- key
1508
+ * self . def_key_cache . lock ( ) . entry ( index) . or_insert_with ( || {
1509
+ let mut key = self . root . tables . def_keys . get ( self , index) . unwrap ( ) . decode ( self ) ;
1510
+ if self . is_proc_macro ( index) {
1511
+ let name = self . raw_proc_macro ( index) . name ( ) ;
1512
+ key. disambiguated_data . data = DefPathData :: MacroNs ( Symbol :: intern ( name) ) ;
1513
+ }
1514
+ key
1515
+ } )
1518
1516
}
1519
1517
1520
1518
// Returns the path leading to the thing with this `id`.
@@ -1523,6 +1521,57 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
1523
1521
DefPath :: make ( self . cnum , id, |parent| self . def_key ( parent) )
1524
1522
}
1525
1523
1524
+ fn def_path_hash_unlocked (
1525
+ & self ,
1526
+ index : DefIndex ,
1527
+ def_path_hashes : & mut FxHashMap < DefIndex , DefPathHash > ,
1528
+ ) -> DefPathHash {
1529
+ * def_path_hashes. entry ( index) . or_insert_with ( || {
1530
+ self . root . tables . def_path_hashes . get ( self , index) . unwrap ( ) . decode ( self )
1531
+ } )
1532
+ }
1533
+
1534
+ #[ inline]
1535
+ fn def_path_hash ( & self , index : DefIndex ) -> DefPathHash {
1536
+ let mut def_path_hashes = self . def_path_hash_cache . lock ( ) ;
1537
+ self . def_path_hash_unlocked ( index, & mut def_path_hashes)
1538
+ }
1539
+
1540
+ fn all_def_path_hashes_and_def_ids ( & self ) -> Vec < ( DefPathHash , DefId ) > {
1541
+ let mut def_path_hashes = self . def_path_hash_cache . lock ( ) ;
1542
+ ( 0 ..self . num_def_ids ( ) )
1543
+ . map ( |index| {
1544
+ let index = DefIndex :: from_usize ( index) ;
1545
+ ( self . def_path_hash_unlocked ( index, & mut def_path_hashes) , self . local_def_id ( index) )
1546
+ } )
1547
+ . collect ( )
1548
+ }
1549
+
1550
+ /// Get the `DepNodeIndex` corresponding this crate. The result of this
1551
+ /// method is cached in the `dep_node_index` field.
1552
+ fn get_crate_dep_node_index ( & self , tcx : TyCtxt < ' tcx > ) -> DepNodeIndex {
1553
+ let mut dep_node_index = self . dep_node_index . load ( ) ;
1554
+
1555
+ if unlikely ! ( dep_node_index == DepNodeIndex :: INVALID ) {
1556
+ // We have not cached the DepNodeIndex for this upstream crate yet,
1557
+ // so use the dep-graph to find it out and cache it.
1558
+ // Note that multiple threads can enter this block concurrently.
1559
+ // That is fine because the DepNodeIndex remains constant
1560
+ // throughout the whole compilation session, and multiple stores
1561
+ // would always write the same value.
1562
+
1563
+ let def_path_hash = self . def_path_hash ( CRATE_DEF_INDEX ) ;
1564
+ let dep_node =
1565
+ DepNode :: from_def_path_hash ( def_path_hash, dep_graph:: DepKind :: CrateMetadata ) ;
1566
+
1567
+ dep_node_index = tcx. dep_graph . dep_node_index_of ( & dep_node) ;
1568
+ assert ! ( dep_node_index != DepNodeIndex :: INVALID ) ;
1569
+ self . dep_node_index . store ( dep_node_index) ;
1570
+ }
1571
+
1572
+ dep_node_index
1573
+ }
1574
+
1526
1575
/// Imports the source_map from an external crate into the source_map of the crate
1527
1576
/// currently being compiled (the "local crate").
1528
1577
///
@@ -1723,9 +1772,6 @@ impl CrateMetadata {
1723
1772
private_dep : bool ,
1724
1773
host_hash : Option < Svh > ,
1725
1774
) -> CrateMetadata {
1726
- let def_path_table = record_time ( & sess. perf_stats . decode_def_path_tables_time , || {
1727
- root. def_path_table . decode ( ( & blob, sess) )
1728
- } ) ;
1729
1775
let trait_impls = root
1730
1776
. impls
1731
1777
. decode ( ( & blob, sess) )
@@ -1737,7 +1783,6 @@ impl CrateMetadata {
1737
1783
CrateMetadata {
1738
1784
blob,
1739
1785
root,
1740
- def_path_table,
1741
1786
trait_impls,
1742
1787
raw_proc_macros,
1743
1788
source_map_import_info : OnceCell :: new ( ) ,
@@ -1752,6 +1797,8 @@ impl CrateMetadata {
1752
1797
host_hash,
1753
1798
extern_crate : Lock :: new ( None ) ,
1754
1799
hygiene_context : Default :: default ( ) ,
1800
+ def_key_cache : Default :: default ( ) ,
1801
+ def_path_hash_cache : Default :: default ( ) ,
1755
1802
}
1756
1803
}
1757
1804
@@ -1828,6 +1875,10 @@ impl CrateMetadata {
1828
1875
self . root . hash
1829
1876
}
1830
1877
1878
+ fn num_def_ids ( & self ) -> usize {
1879
+ self . root . tables . def_keys . size ( )
1880
+ }
1881
+
1831
1882
fn local_def_id ( & self , index : DefIndex ) -> DefId {
1832
1883
DefId { krate : self . cnum , index }
1833
1884
}
@@ -1843,36 +1894,6 @@ impl CrateMetadata {
1843
1894
1844
1895
None
1845
1896
}
1846
-
1847
- #[ inline]
1848
- fn def_path_hash ( & self , index : DefIndex ) -> DefPathHash {
1849
- self . def_path_table . def_path_hash ( index)
1850
- }
1851
-
1852
- /// Get the `DepNodeIndex` corresponding this crate. The result of this
1853
- /// method is cached in the `dep_node_index` field.
1854
- fn get_crate_dep_node_index ( & self , tcx : TyCtxt < ' tcx > ) -> DepNodeIndex {
1855
- let mut dep_node_index = self . dep_node_index . load ( ) ;
1856
-
1857
- if unlikely ! ( dep_node_index == DepNodeIndex :: INVALID ) {
1858
- // We have not cached the DepNodeIndex for this upstream crate yet,
1859
- // so use the dep-graph to find it out and cache it.
1860
- // Note that multiple threads can enter this block concurrently.
1861
- // That is fine because the DepNodeIndex remains constant
1862
- // throughout the whole compilation session, and multiple stores
1863
- // would always write the same value.
1864
-
1865
- let def_path_hash = self . def_path_hash ( CRATE_DEF_INDEX ) ;
1866
- let dep_node =
1867
- DepNode :: from_def_path_hash ( def_path_hash, dep_graph:: DepKind :: CrateMetadata ) ;
1868
-
1869
- dep_node_index = tcx. dep_graph . dep_node_index_of ( & dep_node) ;
1870
- assert ! ( dep_node_index != DepNodeIndex :: INVALID ) ;
1871
- self . dep_node_index . store ( dep_node_index) ;
1872
- }
1873
-
1874
- dep_node_index
1875
- }
1876
1897
}
1877
1898
1878
1899
// Cannot be implemented on 'ProcMacro', as libproc_macro
0 commit comments