@@ -2,7 +2,6 @@ use crate::schema::*;
2
2
3
3
use rustc:: hir:: def_id:: { DefId , DefIndex , DefIndexAddressSpace } ;
4
4
use rustc_serialize:: opaque:: Encoder ;
5
- use std:: slice;
6
5
use std:: u32;
7
6
use log:: debug;
8
7
@@ -14,14 +13,14 @@ use log::debug;
14
13
/// appropriate spot by calling `record_position`. We should never
15
14
/// visit the same index twice.
16
15
pub struct Index {
17
- positions : [ Vec < u32 > ; 2 ]
16
+ positions : [ Vec < u8 > ; 2 ]
18
17
}
19
18
20
19
impl Index {
21
20
pub fn new ( ( max_index_lo, max_index_hi) : ( usize , usize ) ) -> Index {
22
21
Index {
23
- positions : [ vec ! [ u32 :: MAX ; max_index_lo] ,
24
- vec ! [ u32 :: MAX ; max_index_hi] ] ,
22
+ positions : [ vec ! [ 0xff ; max_index_lo * 4 ] ,
23
+ vec ! [ 0xff ; max_index_hi * 4 ] ] ,
25
24
}
26
25
}
27
26
@@ -36,26 +35,27 @@ impl Index {
36
35
let space_index = item. address_space ( ) . index ( ) ;
37
36
let array_index = item. as_array_index ( ) ;
38
37
39
- assert ! ( self . positions[ space_index] [ array_index] == u32 :: MAX ,
38
+ let destination = & mut self . positions [ space_index] [ array_index * 4 ..] ;
39
+ assert ! ( read_le_u32( destination) == u32 :: MAX ,
40
40
"recorded position for item {:?} twice, first at {:?} and now at {:?}" ,
41
41
item,
42
- self . positions [ space_index ] [ array_index ] ,
42
+ read_le_u32 ( destination ) ,
43
43
position) ;
44
44
45
- self . positions [ space_index ] [ array_index ] = position. to_le ( ) ;
45
+ write_le_u32 ( destination , position) ;
46
46
}
47
47
48
48
pub fn write_index ( & self , buf : & mut Encoder ) -> LazySeq < Index > {
49
49
let pos = buf. position ( ) ;
50
50
51
51
// First we write the length of the lower range ...
52
- buf. emit_raw_bytes ( words_to_bytes ( & [ ( self . positions [ 0 ] . len ( ) as u32 ) . to_le ( ) ] ) ) ;
52
+ buf. emit_raw_bytes ( & ( self . positions [ 0 ] . len ( ) as u32 / 4 ) . to_le_bytes ( ) ) ;
53
53
// ... then the values in the lower range ...
54
- buf. emit_raw_bytes ( words_to_bytes ( & self . positions [ 0 ] [ .. ] ) ) ;
54
+ buf. emit_raw_bytes ( & self . positions [ 0 ] ) ;
55
55
// ... then the values in the higher range.
56
- buf. emit_raw_bytes ( words_to_bytes ( & self . positions [ 1 ] [ .. ] ) ) ;
56
+ buf. emit_raw_bytes ( & self . positions [ 1 ] ) ;
57
57
LazySeq :: with_position_and_length ( pos as usize ,
58
- self . positions [ 0 ] . len ( ) + self . positions [ 1 ] . len ( ) + 1 )
58
+ ( self . positions [ 0 ] . len ( ) + self . positions [ 1 ] . len ( ) ) / 4 + 1 )
59
59
}
60
60
}
61
61
@@ -64,24 +64,20 @@ impl<'tcx> LazySeq<Index> {
64
64
/// DefIndex (if any).
65
65
#[ inline( never) ]
66
66
pub fn lookup ( & self , bytes : & [ u8 ] , def_index : DefIndex ) -> Option < Lazy < Entry < ' tcx > > > {
67
- let words = & bytes_to_words ( & bytes[ self . position ..] ) [ ..self . len ] ;
68
-
69
- debug ! ( "Index::lookup: index={:?} words.len={:?}" ,
67
+ debug ! ( "Index::lookup: index={:?} len={:?}" ,
70
68
def_index,
71
- words . len( ) ) ;
69
+ self . len) ;
72
70
73
- let positions = match def_index. address_space ( ) {
74
- DefIndexAddressSpace :: Low => & words [ 1 .. ] ,
71
+ let i = def_index . as_array_index ( ) + match def_index. address_space ( ) {
72
+ DefIndexAddressSpace :: Low => 0 ,
75
73
DefIndexAddressSpace :: High => {
76
74
// This is a DefIndex in the higher range, so find out where
77
75
// that starts:
78
- let lo_count = u32:: from_le ( words[ 0 ] . get ( ) ) as usize ;
79
- & words[ lo_count + 1 .. ]
76
+ read_le_u32 ( & bytes[ self . position ..] ) as usize
80
77
}
81
78
} ;
82
79
83
- let array_index = def_index. as_array_index ( ) ;
84
- let position = u32:: from_le ( positions[ array_index] . get ( ) ) ;
80
+ let position = read_le_u32 ( & bytes[ self . position + ( 1 + i) * 4 ..] ) ;
85
81
if position == u32:: MAX {
86
82
debug ! ( "Index::lookup: position=u32::MAX" ) ;
87
83
None
@@ -92,26 +88,12 @@ impl<'tcx> LazySeq<Index> {
92
88
}
93
89
}
94
90
95
- #[ repr( packed) ]
96
- #[ derive( Copy ) ]
97
- struct Unaligned < T > ( T ) ;
98
-
99
- // The derived Clone impl is unsafe for this packed struct since it needs to pass a reference to
100
- // the field to `T::clone`, but this reference may not be properly aligned.
101
- impl < T : Copy > Clone for Unaligned < T > {
102
- fn clone ( & self ) -> Self {
103
- * self
104
- }
105
- }
106
-
107
- impl < T > Unaligned < T > {
108
- fn get ( self ) -> T { self . 0 }
109
- }
110
-
111
- fn bytes_to_words ( b : & [ u8 ] ) -> & [ Unaligned < u32 > ] {
112
- unsafe { slice:: from_raw_parts ( b. as_ptr ( ) as * const Unaligned < u32 > , b. len ( ) / 4 ) }
91
+ fn read_le_u32 ( b : & [ u8 ] ) -> u32 {
92
+ let mut bytes = [ 0 ; 4 ] ;
93
+ bytes. copy_from_slice ( & b[ ..4 ] ) ;
94
+ u32:: from_le_bytes ( bytes)
113
95
}
114
96
115
- fn words_to_bytes ( w : & [ u32 ] ) -> & [ u8 ] {
116
- unsafe { slice :: from_raw_parts ( w . as_ptr ( ) as * const u8 , w . len ( ) * 4 ) }
97
+ fn write_le_u32 ( b : & mut [ u8 ] , x : u32 ) {
98
+ b [ .. 4 ] . copy_from_slice ( & x . to_le_bytes ( ) ) ;
117
99
}
0 commit comments