@@ -2,7 +2,6 @@ use crate::schema::*;
22
33use rustc:: hir:: def_id:: { DefId , DefIndex , DefIndexAddressSpace } ;
44use rustc_serialize:: opaque:: Encoder ;
5- use std:: slice;
65use std:: u32;
76use log:: debug;
87
@@ -14,14 +13,14 @@ use log::debug;
1413/// appropriate spot by calling `record_position`. We should never
1514/// visit the same index twice.
1615pub struct Index {
17- positions : [ Vec < u32 > ; 2 ]
16+ positions : [ Vec < u8 > ; 2 ]
1817}
1918
2019impl Index {
2120 pub fn new ( ( max_index_lo, max_index_hi) : ( usize , usize ) ) -> Index {
2221 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 ] ] ,
2524 }
2625 }
2726
@@ -36,26 +35,27 @@ impl Index {
3635 let space_index = item. address_space ( ) . index ( ) ;
3736 let array_index = item. as_array_index ( ) ;
3837
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 ,
4040 "recorded position for item {:?} twice, first at {:?} and now at {:?}" ,
4141 item,
42- self . positions [ space_index ] [ array_index ] ,
42+ read_le_u32 ( destination ) ,
4343 position) ;
4444
45- self . positions [ space_index ] [ array_index ] = position. to_le ( ) ;
45+ write_le_u32 ( destination , position) ;
4646 }
4747
4848 pub fn write_index ( & self , buf : & mut Encoder ) -> LazySeq < Index > {
4949 let pos = buf. position ( ) ;
5050
5151 // 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 ( ) ) ;
5353 // ... 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 ] ) ;
5555 // ... 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 ] ) ;
5757 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 )
5959 }
6060}
6161
@@ -64,24 +64,20 @@ impl<'tcx> LazySeq<Index> {
6464 /// DefIndex (if any).
6565 #[ inline( never) ]
6666 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={:?}" ,
7068 def_index,
71- words . len( ) ) ;
69+ self . len) ;
7270
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 ,
7573 DefIndexAddressSpace :: High => {
7674 // This is a DefIndex in the higher range, so find out where
7775 // 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
8077 }
8178 } ;
8279
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 ..] ) ;
8581 if position == u32:: MAX {
8682 debug ! ( "Index::lookup: position=u32::MAX" ) ;
8783 None
@@ -92,26 +88,12 @@ impl<'tcx> LazySeq<Index> {
9288 }
9389}
9490
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)
11395}
11496
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 ( ) ) ;
11799}
0 commit comments