16
16
use astencode:: encode_inlined_item;
17
17
use common:: * ;
18
18
use cstore;
19
- use index:: { self , IndexData } ;
19
+ use index:: IndexData ;
20
20
21
21
use rustc:: middle:: cstore:: { InlinedItemRef , LinkMeta , LinkagePreference } ;
22
22
use rustc:: hir:: def;
@@ -30,11 +30,10 @@ use rustc::session::config::{self, CrateTypeRustcMacro};
30
30
use rustc:: util:: nodemap:: { FnvHashMap , NodeSet } ;
31
31
32
32
use rustc_serialize:: { Encodable , Encoder , SpecializedEncoder , opaque} ;
33
- use std:: cell :: RefCell ;
33
+ use std:: hash :: Hash ;
34
34
use std:: intrinsics;
35
35
use std:: io:: prelude:: * ;
36
36
use std:: io:: Cursor ;
37
- use std:: mem;
38
37
use std:: ops:: { Deref , DerefMut } ;
39
38
use std:: rc:: Rc ;
40
39
use std:: u32;
@@ -58,14 +57,10 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
58
57
reachable : & ' a NodeSet ,
59
58
mir_map : & ' a MirMap < ' tcx > ,
60
59
61
- type_shorthands : RefCell < FnvHashMap < Ty < ' tcx > , usize > > ,
62
- xrefs : FnvHashMap < XRef < ' tcx > , u32 > , // sequentially-assigned
60
+ type_shorthands : FnvHashMap < Ty < ' tcx > , usize > ,
61
+ predicate_shorthands : FnvHashMap < ty :: Predicate < ' tcx > , usize > ,
63
62
}
64
63
65
- /// "interned" entries referenced by id
66
- #[ derive( PartialEq , Eq , Hash ) ]
67
- enum XRef < ' tcx > { Predicate ( ty:: Predicate < ' tcx > ) }
68
-
69
64
impl < ' a , ' tcx > Deref for EncodeContext < ' a , ' tcx > {
70
65
type Target = rbml:: writer:: Encoder < ' a > ;
71
66
fn deref ( & self ) -> & Self :: Target {
@@ -117,20 +112,49 @@ impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> {
117
112
118
113
impl < ' a , ' tcx > SpecializedEncoder < Ty < ' tcx > > for EncodeContext < ' a , ' tcx > {
119
114
fn specialized_encode ( & mut self , ty : & Ty < ' tcx > ) -> Result < ( ) , Self :: Error > {
120
- let existing_shorthand = self . type_shorthands . borrow ( ) . get ( ty) . cloned ( ) ;
115
+ self . encode_with_shorthand ( ty, & ty. sty , |ecx| & mut ecx. type_shorthands )
116
+ }
117
+ }
118
+
119
+ impl < ' a , ' tcx > EncodeContext < ' a , ' tcx > {
120
+ fn seq < I , F , T > ( & mut self , iter : I , mut f : F )
121
+ where I : IntoIterator ,
122
+ I :: IntoIter : ExactSizeIterator ,
123
+ F : FnMut ( & mut Self , I :: Item ) -> T ,
124
+ T : Encodable {
125
+ let iter = iter. into_iter ( ) ;
126
+ self . emit_seq ( iter. len ( ) , move |ecx| {
127
+ for ( i, elem) in iter. enumerate ( ) {
128
+ ecx. emit_seq_elt ( i, |ecx| {
129
+ f ( ecx, elem) . encode ( ecx)
130
+ } ) ?;
131
+ }
132
+ Ok ( ( ) )
133
+ } ) . unwrap ( ) ;
134
+ }
135
+
136
+ /// Encode the given value or a previously cached shorthand.
137
+ fn encode_with_shorthand < T , U , M > ( & mut self , value : & T , variant : & U , map : M )
138
+ -> Result < ( ) , <Self as Encoder >:: Error >
139
+ where M : for < ' b > Fn ( & ' b mut Self ) -> & ' b mut FnvHashMap < T , usize > ,
140
+ T : Clone + Eq + Hash ,
141
+ U : Encodable {
142
+ let existing_shorthand = map ( self ) . get ( value) . cloned ( ) ;
121
143
if let Some ( shorthand) = existing_shorthand {
122
144
return self . emit_usize ( shorthand) ;
123
145
}
124
146
125
147
let start = self . mark_stable_position ( ) ;
126
- ty . sty . encode ( self ) ?;
148
+ variant . encode ( self ) ?;
127
149
let len = self . mark_stable_position ( ) - start;
128
150
129
151
// The shorthand encoding uses the same usize as the
130
152
// discriminant, with an offset so they can't conflict.
131
- let discriminant = unsafe { intrinsics:: discriminant_value ( & ty. sty ) } ;
132
- assert ! ( discriminant < TYPE_SHORTHAND_OFFSET as u64 ) ;
133
- let shorthand = start + TYPE_SHORTHAND_OFFSET ;
153
+ let discriminant = unsafe {
154
+ intrinsics:: discriminant_value ( variant)
155
+ } ;
156
+ assert ! ( discriminant < SHORTHAND_OFFSET as u64 ) ;
157
+ let shorthand = start + SHORTHAND_OFFSET ;
134
158
135
159
// Get the number of bits that leb128 could fit
136
160
// in the same space as the fully encoded type.
@@ -139,29 +163,11 @@ impl<'a, 'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'a, 'tcx> {
139
163
// Check that the shorthand is a not longer than the
140
164
// full encoding itself, i.e. it's an obvious win.
141
165
if leb128_bits >= 64 || ( shorthand as u64 ) < ( 1 << leb128_bits) {
142
- self . type_shorthands . borrow_mut ( ) . insert ( * ty , shorthand) ;
166
+ map ( self ) . insert ( value . clone ( ) , shorthand) ;
143
167
}
144
168
145
169
Ok ( ( ) )
146
170
}
147
- }
148
-
149
- impl < ' a , ' tcx > EncodeContext < ' a , ' tcx > {
150
- fn seq < I , F , T > ( & mut self , iter : I , mut f : F )
151
- where I : IntoIterator ,
152
- I :: IntoIter : ExactSizeIterator ,
153
- F : FnMut ( & mut Self , I :: Item ) -> T ,
154
- T : Encodable {
155
- let iter = iter. into_iter ( ) ;
156
- self . emit_seq ( iter. len ( ) , move |ecx| {
157
- for ( i, elem) in iter. enumerate ( ) {
158
- ecx. emit_seq_elt ( i, |ecx| {
159
- f ( ecx, elem) . encode ( ecx)
160
- } ) ?;
161
- }
162
- Ok ( ( ) )
163
- } ) . unwrap ( ) ;
164
- }
165
171
166
172
/// For every DefId that we create a metadata item for, we include a
167
173
/// serialized copy of its DefKey, which allows us to recreate a path.
@@ -393,7 +399,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
393
399
self . start_tag ( tag) ;
394
400
predicates. parent . encode ( self ) . unwrap ( ) ;
395
401
self . seq ( & predicates. predicates , |ecx, predicate| {
396
- ecx. add_xref ( XRef :: Predicate ( predicate. clone ( ) ) )
402
+ ecx. encode_with_shorthand ( predicate, predicate,
403
+ |ecx| & mut ecx. predicate_shorthands ) . unwrap ( )
397
404
} ) ;
398
405
self . end_tag ( ) ;
399
406
}
@@ -575,34 +582,6 @@ fn encode_stability(ecx: &mut EncodeContext, def_id: DefId) {
575
582
}
576
583
577
584
impl < ' a , ' tcx > EncodeContext < ' a , ' tcx > {
578
- fn add_xref ( & mut self , xref : XRef < ' tcx > ) -> u32 {
579
- let old_len = self . xrefs . len ( ) as u32 ;
580
- * self . xrefs . entry ( xref) . or_insert ( old_len)
581
- }
582
-
583
- fn encode_xrefs ( & mut self ) {
584
- let xrefs = mem:: replace ( & mut self . xrefs , Default :: default ( ) ) ;
585
- let mut xref_positions = vec ! [ 0 ; xrefs. len( ) ] ;
586
-
587
- // Encode XRefs sorted by their ID
588
- let mut sorted_xrefs: Vec < _ > = xrefs. into_iter ( ) . collect ( ) ;
589
- sorted_xrefs. sort_by_key ( |& ( _, id) | id) ;
590
-
591
- self . start_tag ( root_tag:: xref_data) ;
592
- for ( xref, id) in sorted_xrefs. into_iter ( ) {
593
- xref_positions[ id as usize ] = self . mark_stable_position ( ) as u32 ;
594
- match xref {
595
- XRef :: Predicate ( p) => p. encode ( self ) . unwrap ( )
596
- }
597
- }
598
- self . mark_stable_position ( ) ;
599
- self . end_tag ( ) ;
600
-
601
- self . start_tag ( root_tag:: xref_index) ;
602
- index:: write_dense_index ( xref_positions, & mut self . opaque . cursor ) ;
603
- self . end_tag ( ) ;
604
- }
605
-
606
585
fn encode_info_for_item ( & mut self ,
607
586
( def_id, item) : ( DefId , & hir:: Item ) ) {
608
587
let tcx = self . tcx ;
@@ -1233,7 +1212,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1233
1212
reachable : reachable,
1234
1213
mir_map : mir_map,
1235
1214
type_shorthands : Default :: default ( ) ,
1236
- xrefs : Default :: default ( )
1215
+ predicate_shorthands : Default :: default ( )
1237
1216
} ) ;
1238
1217
1239
1218
// RBML compacts the encoded bytes whenever appropriate,
@@ -1345,10 +1324,6 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) {
1345
1324
encode_item_index ( ecx, items) ;
1346
1325
let index_bytes = ecx. position ( ) - i;
1347
1326
1348
- i = ecx. position ( ) ;
1349
- ecx. encode_xrefs ( ) ;
1350
- let xref_bytes = ecx. position ( ) - i;
1351
-
1352
1327
let total_bytes = ecx. position ( ) ;
1353
1328
1354
1329
if ecx. tcx . sess . meta_stats ( ) {
@@ -1369,7 +1344,6 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) {
1369
1344
println ! ( " reachable bytes: {}" , reachable_bytes) ;
1370
1345
println ! ( " item bytes: {}" , item_bytes) ;
1371
1346
println ! ( " index bytes: {}" , index_bytes) ;
1372
- println ! ( " xref bytes: {}" , xref_bytes) ;
1373
1347
println ! ( " zero bytes: {}" , zero_bytes) ;
1374
1348
println ! ( " total bytes: {}" , total_bytes) ;
1375
1349
}
0 commit comments