pub fn decode_alloc_id<'a, 'tcx, D>(&self,
                                        decoder: &mut D)
                                        -> Result<AllocId, D::Error>
        where D: TyDecoder<'a, 'tcx>,
              'tcx: 'a,
    {
        // Read the index of the allocation
        let idx = decoder.read_u32()? as usize;
        let pos = self.state.data_offsets[idx] as usize;

        // Decode the AllocDiscriminant now so that we know if we have to reserve an
        // AllocId.
        let (alloc_kind, pos) = decoder.with_position(pos, |decoder| {
            let alloc_kind = AllocDiscriminant::decode(decoder)?;
            Ok((alloc_kind, decoder.position()))
        })?;

        // Check the decoding state, see if it's already decoded or if we should
        // decode it here.
        let alloc_id = {
            let mut entry = self.state.decoding_state[idx].lock();

            match *entry {
                State::Done(alloc_id) => {
                    return Ok(alloc_id);
                }
                ref mut entry @ State::Empty => {
                    // We are allowed to decode
                    match alloc_kind {
                        AllocDiscriminant::Alloc => {
                            // If this is an allocation, we need to reserve an
                            // AllocId so we can decode cyclic graphs.
                            let alloc_id = decoder.tcx().alloc_map.lock().reserve();
                            *entry = State::InProgress(
                                TinyList::new_single(self.session_id),
                                alloc_id);
                            Some(alloc_id)
                        },
                        AllocDiscriminant::Fn | AllocDiscriminant::Static => {
                            // Fns and statics cannot be cyclic and their AllocId
                            // is determined later by interning
                            *entry = State::InProgressNonAlloc(
                                TinyList::new_single(self.session_id));
                            None
                        }
                    }
                }
                State::InProgressNonAlloc(ref mut sessions) => {
                    if sessions.contains(&self.session_id) {
                        bug!("This should be unreachable")
                    } else {
                        // Start decoding concurrently
                        sessions.insert(self.session_id);
                        None
                    }
                }
                State::InProgress(ref mut sessions, alloc_id) => {
                    if sessions.contains(&self.session_id) {
                        // Don't recurse.
                        return Ok(alloc_id)
                    } else {
                        // Start decoding concurrently
                        sessions.insert(self.session_id);
                        Some(alloc_id)
                    }
                }
            }
        };

        // Now decode the actual data
        let alloc_id = decoder.with_position(pos, |decoder| {
            match alloc_kind {
                AllocDiscriminant::Alloc => {
                    let allocation = <&'tcx Allocation as Decodable>::decode(decoder)?;
                    // We already have a reserved AllocId.
                    let alloc_id = alloc_id.unwrap();
                    trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
                    decoder.tcx().alloc_map.lock().set_alloc_id_same_memory(alloc_id, allocation);
                    Ok(alloc_id)
                },
                AllocDiscriminant::Fn => {
                    assert!(alloc_id.is_none());
                    trace!("creating fn alloc id");
                    let instance = ty::Instance::decode(decoder)?;
                    trace!("decoded fn alloc instance: {:?}", instance);
                    let alloc_id = decoder.tcx().alloc_map.lock().create_fn_alloc(instance);
                    Ok(alloc_id)
                },
                AllocDiscriminant::Static => {
                    assert!(alloc_id.is_none());
                    trace!("creating extern static alloc id at");
                    let did = DefId::decode(decoder)?;
                    let alloc_id = decoder.tcx().alloc_map.lock().intern_static(did);
                    Ok(alloc_id)
                }
            }
        })?;

        self.state.decoding_state[idx].with_lock(|entry| {
            *entry = State::Done(alloc_id);
        });

        Ok(alloc_id)
    }
// Decodes an AllocId in a thread-safe way.
Decodes an AllocId in a thread-safe way.
Decodes an AllocId in a thread - safe way .
pub fn decode_alloc_id<'a, 'tcx, D>(&self,
                                        decoder: &mut D)
                                        -> Result<AllocId, D::Error>
        where D: TyDecoder<'a, 'tcx>,
              'tcx: 'a,
    {
        // Read the index of the allocation
        let idx = decoder.read_u32()? as usize;
        let pos = self.state.data_offsets[idx] as usize;
        // Decode the AllocDiscriminant now so that we know if we have to reserve an
        // AllocId.
        let (alloc_kind, pos) = decoder.with_position(pos, |decoder| {
            let alloc_kind = AllocDiscriminant::decode(decoder)?;
            Ok((alloc_kind, decoder.position()))
        })?;
        // Check the decoding state, see if it's already decoded or if we should
        // decode it here.
        let alloc_id = {
            let mut entry = self.state.decoding_state[idx].lock();
            match *entry {
                State::Done(alloc_id) => {
                    return Ok(alloc_id);
                }
                ref mut entry @ State::Empty => {
                    // We are allowed to decode
                    match alloc_kind {
                        AllocDiscriminant::Alloc => {
                            // If this is an allocation, we need to reserve an
                            // AllocId so we can decode cyclic graphs.
                            let alloc_id = decoder.tcx().alloc_map.lock().reserve();
                            *entry = State::InProgress(
                                TinyList::new_single(self.session_id),
                                alloc_id);
                            Some(alloc_id)
                        },
                        AllocDiscriminant::Fn | AllocDiscriminant::Static => {
                            // Fns and statics cannot be cyclic and their AllocId
                            // is determined later by interning
                            *entry = State::InProgressNonAlloc(
                                TinyList::new_single(self.session_id));
                            None
                        }
                    }
                }
                State::InProgressNonAlloc(ref mut sessions) => {
                    if sessions.contains(&self.session_id) {
                        bug!("This should be unreachable")
                    } else {
                        // Start decoding concurrently
                        sessions.insert(self.session_id);
                        None
                    }
                }
                State::InProgress(ref mut sessions, alloc_id) => {
                    if sessions.contains(&self.session_id) {
                        // Don't recurse.
                        return Ok(alloc_id)
                    } else {
                        // Start decoding concurrently
                        sessions.insert(self.session_id);
                        Some(alloc_id)
                    }
                }
            }
        };
        // Now decode the actual data
        let alloc_id = decoder.with_position(pos, |decoder| {
            match alloc_kind {
                AllocDiscriminant::Alloc => {
                    let allocation = <&'tcx Allocation as Decodable>::decode(decoder)?;
                    // We already have a reserved AllocId.
                    let alloc_id = alloc_id.unwrap();
                    trace!("decoded alloc {:?} {:#?}", alloc_id, allocation);
                    decoder.tcx().alloc_map.lock().set_alloc_id_same_memory(alloc_id, allocation);
                    Ok(alloc_id)
                },
                AllocDiscriminant::Fn => {
                    assert!(alloc_id.is_none());
                    trace!("creating fn alloc id");
                    let instance = ty::Instance::decode(decoder)?;
                    trace!("decoded fn alloc instance: {:?}", instance);
                    let alloc_id = decoder.tcx().alloc_map.lock().create_fn_alloc(instance);
                    Ok(alloc_id)
                },
                AllocDiscriminant::Static => {
                    assert!(alloc_id.is_none());
                    trace!("creating extern static alloc id at");
                    let did = DefId::decode(decoder)?;
                    let alloc_id = decoder.tcx().alloc_map.lock().intern_static(did);
                    Ok(alloc_id)
                }
            }
        })?;
        self.state.decoding_state[idx].with_lock(|entry| {
            *entry = State::Done(alloc_id);
        });
        Ok(alloc_id)
    }
pub fn decode_alloc_id < ' a , ' tcx , D > ( & self , decoder : & mut D ) -> Result < AllocId , D :: Error > where D : TyDecoder < ' a , ' tcx > , ' tcx : ' a , { // Read the index of the allocation let idx = decoder . read_u32 ( ) ? as usize ; let pos = self . state . data_offsets [ idx ] as usize ; // Decode the AllocDiscriminant now so that we know if we have to reserve an // AllocId. let ( alloc_kind , pos ) = decoder . with_position ( pos , | decoder | { let alloc_kind = AllocDiscriminant :: decode ( decoder ) ? ; Ok ( ( alloc_kind , decoder . position ( ) ) ) } ) ? ; // Check the decoding state, see if it's already decoded or if we should // decode it here. let alloc_id = { let mut entry = self . state . decoding_state [ idx ] . lock ( ) ; match * entry { State :: Done ( alloc_id ) => { return Ok ( alloc_id ) ; } ref mut entry @ State :: Empty => { // We are allowed to decode match alloc_kind { AllocDiscriminant :: Alloc => { // If this is an allocation, we need to reserve an // AllocId so we can decode cyclic graphs. let alloc_id = decoder . tcx ( ) . alloc_map . lock ( ) . reserve ( ) ; * entry = State :: InProgress ( TinyList :: new_single ( self . session_id ) , alloc_id ) ; Some ( alloc_id ) } , AllocDiscriminant :: Fn | AllocDiscriminant :: Static => { // Fns and statics cannot be cyclic and their AllocId // is determined later by interning * entry = State :: InProgressNonAlloc ( TinyList :: new_single ( self . session_id ) ) ; None } } } State :: InProgressNonAlloc ( ref mut sessions ) => { if sessions . contains ( & self . session_id ) { bug ! ( " " ) } else { // Start decoding concurrently sessions . insert ( self . session_id ) ; None } } State :: InProgress ( ref mut sessions , alloc_id ) => { if sessions . contains ( & self . session_id ) { // Don't recurse. return Ok ( alloc_id ) } else { // Start decoding concurrently sessions . insert ( self . session_id ) ; Some ( alloc_id ) } } } } ; // Now decode the actual data let alloc_id = decoder . with_position ( pos , | decoder | { match alloc_kind { AllocDiscriminant :: Alloc => { let allocation = < & ' tcx Allocation as Decodable > :: decode ( decoder ) ? ; // We already have a reserved AllocId. let alloc_id = alloc_id . unwrap ( ) ; trace ! ( " " alloc_id allocation ) ; decoder . tcx ( ) . alloc_map . lock ( ) . set_alloc_id_same_memory ( alloc_id , allocation ) ; Ok ( alloc_id ) } , AllocDiscriminant :: Fn => { assert ! ( alloc_id is_none ( ) ) ; trace ! ( " " ) ; let instance = ty :: Instance :: decode ( decoder ) ? ; trace ! ( " " instance ) ; let alloc_id = decoder . tcx ( ) . alloc_map . lock ( ) . create_fn_alloc ( instance ) ; Ok ( alloc_id ) } , AllocDiscriminant :: Static => { assert ! ( alloc_id is_none ( ) ) ; trace ! ( " " ) ; let did = DefId :: decode ( decoder ) ? ; let alloc_id = decoder . tcx ( ) . alloc_map . lock ( ) . intern_static ( did ) ; Ok ( alloc_id ) } } } ) ? ; self . state . decoding_state [ idx ] . with_lock ( | entry | { * entry = State :: Done ( alloc_id ) ; } ) ; Ok ( alloc_id ) }
Decodes an AllocId in a thread-safe way.
Decodes an AllocId in a thread - safe way .
&self
decoder
&mut D
&self
decoder
&mut D